Class: KramdownRFC::KDRFC

Inherits:
Object show all
Defined in:
lib/kramdown-rfc/kdrfc-processor.rb

Constant Summary collapse

KDRFC_PREPEND =

)))

[ENV["KDRFC_PREPEND"]].compact
IDNITS_WEBSERVICE =

curl -s author-tools.ietf.org/api/idnits -X POST -F [email protected] -F hidetext=true

ENV["KRAMDOWN_IDNITS_WEBSERVICE"] ||
'https://author-tools.ietf.org/api/idnits'
XML2RFC_WEBSERVICE =

curl author-tools.ietf.org/api/render/text -X POST -F “file=@…”

ENV["KRAMDOWN_XML2RFC_WEBSERVICE"] ||
'https://author-tools.ietf.org/api/render/'
MODE_AS_FORMAT =
{
    "--text" => "text",
    "--html" => "html",
    "--v2v3" => "xml",
    "--pdf" => "pdf",
}

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeKDRFC

Returns a new instance of KDRFC.



14
15
16
# File 'lib/kramdown-rfc/kdrfc-processor.rb', line 14

def initialize
  @options = OpenStruct.new
end

Instance Attribute Details

#optionsObject (readonly)

Returns the value of attribute options.



12
13
14
# File 'lib/kramdown-rfc/kdrfc-processor.rb', line 12

def options
  @options
end

Instance Method Details

#checked_json(t) ⇒ Object



132
133
134
135
136
137
138
# File 'lib/kramdown-rfc/kdrfc-processor.rb', line 132

def checked_json(t)
  begin
    JSON.load(t)
  rescue => e
    raise IOError.new("*** JSON result: #{e.detailed_message}, #{diag}")
  end
end

#persistent_httpObject



140
141
142
# File 'lib/kramdown-rfc/kdrfc-processor.rb', line 140

def persistent_http
  $http ||= Net::HTTP::Persistent.new name: 'kramdown-rfc'
end

#process(fn) ⇒ Object



217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
# File 'lib/kramdown-rfc/kdrfc-processor.rb', line 217

def process(fn)
  case fn
  when /(.*)\.xml\z/
    if @options.xml_only
      warn "*** You already have XML"
    else                        # FIXME: copy/paste
      process_the_xml(fn, $1)
    end
  when /(.*)\.mk?d\z/
    xml = "#$1.xml"
    process_mkd(fn, xml)
    process_the_xml(xml, $1) unless @options.xml_only
  when /(.*)\.txt\z/
    run_idnits(fn) if @options.idnits
  else
    raise ArgumentError.new("Unknown file type: #{fn}")
  end
end

#process_mkd(input, output) ⇒ Object



27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/kramdown-rfc/kdrfc-processor.rb', line 27

def process_mkd(input, output)
  warn "* converting locally from markdown #{input} to xml #{output}" if @options.verbose
  o, s = Open3.capture2(*KDRFC_PREPEND, "kramdown-rfc2629", *v3_flag?, input)
  if s.success?
    File.open(output, "w") do |fo|
      fo.print(o)
    end
    warn "* #{output} written" if @options.verbose
  else
    raise IOError.new("*** kramdown-rfc failed, status #{s.exitstatus}")
  end
end

#process_the_xml(fn, base) ⇒ Object



208
209
210
211
212
213
214
215
# File 'lib/kramdown-rfc/kdrfc-processor.rb', line 208

def process_the_xml(fn, base)
  process_xml(fn, "#{base}.prepped.xml", "--preptool") if @options.prep
  process_xml(fn, "#{base}.v2v3.xml", "--v2v3") if @options.v2v3
  process_xml(fn, "#{base}.txt") if @options.txt || @options.idnits
  process_xml(fn, "#{base}.html", "--html") if @options.html
  process_xml(fn, "#{base}.pdf", "--pdf") if @options.pdf
  run_idnits("#{base}.txt") if @options.idnits
end

#process_xml(*args) ⇒ Object



97
98
99
100
101
102
103
# File 'lib/kramdown-rfc/kdrfc-processor.rb', line 97

def process_xml(*args)
  if @options.remote
    process_xml_remotely(*args)
  else
    process_xml_locally(*args)
  end
end

#process_xml_locally(input, output, *flags) ⇒ Object



105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/kramdown-rfc/kdrfc-processor.rb', line 105

def process_xml_locally(input, output, *flags)
  warn "* converting locally from xml #{input} to txt #{output}" if @options.verbose
  begin
    o, s = Open3.capture2(*KDRFC_PREPEND, "xml2rfc", *v3_flag?, *flags, input)
    puts o
    if s.success?
      warn "* #{output} written" if @options.verbose
    else
      raise IOError.new("*** xml2rfc failed, status #{s.exitstatus} (possibly try with -r)")
    end
  rescue Errno::ENOENT
    warn "*** falling back to remote xml2rfc processing (web service)" # if @options.verbose
    process_xml_remotely(input, output, *flags)
  end
end

#process_xml_remotely(input, output, *flags) ⇒ Object



144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
# File 'lib/kramdown-rfc/kdrfc-processor.rb', line 144

def process_xml_remotely(input, output, *flags)

  format = flags[0] || "--text"
  warn "* converting remotely from xml #{input} to #{format} #{output}" if @options.verbose
  maf = MODE_AS_FORMAT[format]
  unless maf
    raise ArgumentError.new("*** don't know how to convert remotely from xml #{input} to #{format} #{output}")
  end
  url = URI(XML2RFC_WEBSERVICE + maf)
  req = Net::HTTP::Post.new(url)
  form = [["file", File.open(input),
           {filename: "input.xml",
            content_type: "text/plain"}]]
  diag = ["url/form: ", url, form].inspect
  req.set_form(form, 'multipart/form-data')
  warn "* requesting at #{url}" if @options.verbose
  t0 = Time.now
  res = persistent_http.request(url, req)
  warn "* elapsed time: #{Time.now - t0}" if @options.verbose
  case res
  when Net::HTTPBadRequest
    result = checked_json(res.body)
    raise IOError.new("*** Remote Error: #{result["error"]}")
  when Net::HTTPOK
    case res.content_type
    when 'application/json'
      if res.body == ''
        raise IOError.new("*** HTTP response is empty with status #{res.code}, not written")
      end
      # warn "* res.body #{res.body}" if @options.verbose
      result = checked_json(res.body)
      if logs = result["logs"]
        if errors = logs["errors"]
          errors.each do |err|
            warn("*** Error: #{err}")
          end
        end
        if warnings = logs["warnings"]
          warnings.each do |w|
            warn("** Warning: #{w}")
          end
        end
      end
      raise IOError.new("*** No useful result from remote") unless result["url"]
      res = persistent_http.request(URI(result["url"]))
      warn "* result content type #{res.content_type}" if @options.verbose
      if res.body == ''
        raise IOError.new("*** Second HTTP response is empty with status #{res.code}, not written")
      end
      File.open(output, "w") do |fo|
        fo.print(res.body)
      end
      warn "* #{output} written" if @options.verbose
    else
      warning = "*** HTTP response has unexpected content_type #{res.content_type} with status #{res.code}, #{diag}"
      warning << "\n"
      warning << res.body
      raise IOError.new(warning)
    end
  else
    raise IOError.new("*** HTTP response: #{res.code}, #{diag}")
  end
end

#run_idnits(*args) ⇒ Object



40
41
42
43
44
45
46
# File 'lib/kramdown-rfc/kdrfc-processor.rb', line 40

def run_idnits(*args)
  if @options.remote
    run_idnits_remotely(*args)
  else
    run_idnits_locally(*args)
  end
end

#run_idnits_locally(txt_fn) ⇒ Object



48
49
50
51
52
53
54
55
# File 'lib/kramdown-rfc/kdrfc-processor.rb', line 48

def run_idnits_locally(txt_fn)
  warn "* running idnits locally in txt #{txt_fn}" if @options.verbose
  unless system("idnits", txt_fn)
    warn "*** problem #$? running idnits" if @options.verbose
    warn "*** problem running idnits -- falling back to remote idnits processing"
    run_idnits_remotely(txt_fn)
  end
end

#run_idnits_remotely(txt_fn) ⇒ Object



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/kramdown-rfc/kdrfc-processor.rb', line 61

def run_idnits_remotely(txt_fn)
  url = URI(IDNITS_WEBSERVICE)
  req = Net::HTTP::Post.new(url)
  form = [["file", File.open(txt_fn),
           {filename: "input.txt",
            content_type: "text/plain"}],
          ["hidetext", "true"]]
  diag = ["url/form: ", url, form].inspect
  req.set_form(form, 'multipart/form-data')
  warn "* requesting idnits at #{url}" if @options.verbose
  t0 = Time.now
  res = persistent_http.request(url, req)
  warn "* elapsed time: #{Time.now - t0}" if @options.verbose
  case res
  when Net::HTTPBadRequest
    result = checked_json(res.body)
    raise IOError.new("*** Remote Error: #{result["error"]}")
  when Net::HTTPOK
    case res.content_type
    when 'text/plain'
      if res.body == ''
        raise IOError.new("*** HTTP response is empty with status #{res.code}, not written")
      end
      puts res.body
    else
      warning = "*** HTTP response has unexpected content_type #{res.content_type} with status #{res.code}, #{diag}"
      warning << "\n"
      warning << res.body
      raise IOError.new(warning)
    end
  else
    raise IOError.new("*** HTTP response: #{res.code}, #{diag}")
  end
end

#v3_flag?Boolean

Returns:

  • (Boolean)


22
23
24
25
# File 'lib/kramdown-rfc/kdrfc-processor.rb', line 22

def v3_flag?
  [*(@options.v3 ? ["--v3"] : []),
   *(@options.v2 ? ["--v2"] : [])]
end