Class: Metanorma::Compile
- Inherits:
-
Object
- Object
- Metanorma::Compile
- Defined in:
- lib/metanorma/compile.rb
Constant Summary collapse
- REQUIREMENT_XPATH =
"//requirement | //xmlns:requirement | "\ "//recommendation | //xmlns:recommendation | //permission | "\ "//xmlns:permission".freeze
Instance Method Summary collapse
- #clean_sourcecode(xml) ⇒ Object
- #compile(filename, options = {}) ⇒ Object
- #extract(isodoc, dirname, extract_types) ⇒ Object
- #get_extensions(options) ⇒ Object
- #image_export(xml, dirname) ⇒ Object
-
#initialize ⇒ Compile
constructor
A new instance of Compile.
- #options_extract(filename, options) ⇒ Object
- #process_extensions(extensions, file, isodoc, options) ⇒ Object
- #process_input(filename, options) ⇒ Object
- #read_file(filename) ⇒ Object
- #relaton_export(isodoc, options) ⇒ Object
- #require_libraries(options) ⇒ Object
- #requirement_export(xml, dirname) ⇒ Object
- #sourcecode_export(xml, dirname) ⇒ Object
- #validate(options) ⇒ Object
- #validate_format(options) ⇒ Object
- #validate_type(options) ⇒ Object
- #xml_options_extract(file) ⇒ Object
Constructor Details
Instance Method Details
#clean_sourcecode(xml) ⇒ Object
138 139 140 141 142 143 144 |
# File 'lib/metanorma/compile.rb', line 138 def clean_sourcecode(xml) xml.xpath(".//callout | .//annotation | .//xmlns:callout | .//xmlns:annotation").each do |x| x.remove end xml.xpath(".//br | .//xmlns:br").each { |x| x.replace("\n") } HTMLEntities.new.decode(xml.children.to_xml) end |
#compile(filename, options = {}) ⇒ Object
11 12 13 14 15 16 17 18 19 20 21 |
# File 'lib/metanorma/compile.rb', line 11 def compile(filename, = {}) = (filename, ) validate() or return nil require_libraries() @processor = @registry.find_processor([:type].to_sym) extensions = get_extensions() or return nil (file, isodoc = process_input(filename, )) or return nil relaton_export(isodoc, ) extract(isodoc, [:extract], [:extract_type]) process_extensions(extensions, file, isodoc, ) end |
#extract(isodoc, dirname, extract_types) ⇒ Object
146 147 148 149 150 151 152 153 154 155 156 157 |
# File 'lib/metanorma/compile.rb', line 146 def extract(isodoc, dirname, extract_types) return unless dirname if extract_types.nil? || extract_types.empty? extract_types = [:sourcecode, :image, :requirement] end FileUtils.rm_rf dirname FileUtils.mkdir_p dirname xml = Nokogiri::XML(isodoc) sourcecode_export(xml, dirname) if extract_types.include? :sourcecode image_export(xml, dirname) if extract_types.include? :image requirement_export(xml, dirname) if extract_types.include? :requirement end |
#get_extensions(options) ⇒ Object
91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/metanorma/compile.rb', line 91 def get_extensions() [:extension_keys] ||= @processor.output_formats.inject([]) do |memo, (k, _)| memo << k; memo end extensions = [:extension_keys].inject([]) do |memo, e| @processor.output_formats[e] and memo << e or Util.log("[metanorma] Error: #{e} format is not supported for this standard.", :error) memo end extensions end |
#image_export(xml, dirname) ⇒ Object
170 171 172 173 174 175 176 177 178 179 180 181 |
# File 'lib/metanorma/compile.rb', line 170 def image_export(xml, dirname) xml.at("//image | //xmlns:image") or return FileUtils.mkdir_p "#{dirname}/image" xml.xpath("//image | //xmlns:image").each_with_index do |s, i| next unless /^data:image/.match s["src"] %r{^data:image/(?<imgtype>[^;]+);base64,(?<imgdata>.+)$} =~ s["src"] filename = s["filename"] || sprintf("image-%04d.%s", i, imgtype) File.open("#{dirname}/image/#{filename}", "wb") do |f| f.write(Base64.strict_decode64(imgdata)) end end end |
#options_extract(filename, options) ⇒ Object
41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/metanorma/compile.rb', line 41 def (filename, ) content = read_file(filename) o = Metanorma::Input::Asciidoc.new.(content) o = o.merge((content)) [:type] ||= o[:type]&.to_sym dir = filename.sub(%r(/[^/]+$), "/") [:relaton] ||= "#{dir}/#{o[:relaton]}" if o[:relaton] [:sourcecode] ||= "#{dir}/#{o[:sourcecode]}" if o[:sourcecode] [:extension_keys] ||= o[:extensions]&.split(/,[ ]*/)&.map(&:to_sym) [:extension_keys] = nil if [:extension_keys] == [:all] [:format] ||= :asciidoc [:filename] = filename end |
#process_extensions(extensions, file, isodoc, options) ⇒ Object
198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 |
# File 'lib/metanorma/compile.rb', line 198 def process_extensions(extensions, file, isodoc, ) extensions.each do |ext| = @processor.(file) [:datauriimage] = true if [:datauriimage] file_extension = @processor.output_formats[ext] outfilename = [:filename].sub(/\.[^.]+$/, ".#{file_extension}") if ext == :rxl [:relaton] = outfilename relaton_export(isodoc, ) else @processor.output(isodoc, outfilename, ext, ) end if [:wrapper] and /html$/.match file_extension outfilename = outfilename.sub(/\.html$/, "") FileUtils.mkdir_p outfilename FileUtils.mv "#{outfilename}.html", outfilename FileUtils.mv "#{outfilename}_images", outfilename, force: true end end end |
#process_input(filename, options) ⇒ Object
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/metanorma/compile.rb', line 103 def process_input(filename, ) case extname = File.extname(filename) when ".adoc" Util.log("[metanorma] Processing: Asciidoctor input.", :info) file = read_file(filename) [:asciimath] and file.sub!(/^(=[^\n]+\n)/, "\\1:mn-keep-asciimath:\n") dir = File.dirname(filename) dir != '.' and file.gsub!(/^include::/, "include::#{dir}/") [file, @processor.input_to_isodoc(file, filename)] when ".xml" Util.log("[metanorma] Processing: Metanorma XML input.", :info) # TODO NN: this is a hack -- we should provide/bridge the # document attributes in Metanorma XML ["", read_file(filename)] else Util.log("[metanorma] Error: file extension #{extname} is not supported.", :error) nil end end |
#read_file(filename) ⇒ Object
125 126 127 |
# File 'lib/metanorma/compile.rb', line 125 def read_file(filename) File.read(filename, encoding: "utf-8").gsub("\r\n", "\n") end |
#relaton_export(isodoc, options) ⇒ Object
129 130 131 132 133 134 135 136 |
# File 'lib/metanorma/compile.rb', line 129 def relaton_export(isodoc, ) return unless [:relaton] xml = Nokogiri::XML(isodoc) bibdata = xml.at("//bibdata") || xml.at("//xmlns:bibdata") #docid = bibdata&.at("./xmlns:docidentifier")&.text || options[:filename] #outname = docid.sub(/^\s+/, "").sub(/\s+$/, "").gsub(/\s+/, "-") + ".xml" File.open([:relaton], "w:UTF-8") { |f| f.write bibdata.to_xml } end |
#require_libraries(options) ⇒ Object
23 24 25 26 27 28 29 |
# File 'lib/metanorma/compile.rb', line 23 def require_libraries() if [:require] [:require].each do |r| require r end end end |
#requirement_export(xml, dirname) ⇒ Object
187 188 189 190 191 192 193 194 195 196 |
# File 'lib/metanorma/compile.rb', line 187 def requirement_export(xml, dirname) xml.at(REQUIREMENT_XPATH) or return FileUtils.mkdir_p "#{dirname}/requirement" xml.xpath(REQUIREMENT_XPATH).each_with_index do |s, i| filename = s["filename"] || sprintf("%s-%04d.xml", s.name, i) File.open("#{dirname}/requirement/#{filename}", "w:UTF-8") do |f| f.write s end end end |
#sourcecode_export(xml, dirname) ⇒ Object
159 160 161 162 163 164 165 166 167 168 |
# File 'lib/metanorma/compile.rb', line 159 def sourcecode_export(xml, dirname) xml.at("//sourcecode | //xmlns:sourcecode") or return FileUtils.mkdir_p "#{dirname}/sourcecode" xml.xpath("//sourcecode | //xmlns:sourcecode").each_with_index do |s, i| filename = s["filename"] || sprintf("sourcecode-%04d.txt", i) File.open("#{dirname}/sourcecode/#{filename}", "w:UTF-8") do |f| f.write clean_sourcecode(s.dup) end end end |
#validate(options) ⇒ Object
56 57 58 |
# File 'lib/metanorma/compile.rb', line 56 def validate() validate_type() && validate_format() end |
#validate_format(options) ⇒ Object
83 84 85 86 87 88 89 |
# File 'lib/metanorma/compile.rb', line 83 def validate_format() unless [:format] == :asciidoc Util.log("[metanorma] Error: Only source file format currently supported is 'asciidoc'.", :error) return false end true end |
#validate_type(options) ⇒ Object
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/metanorma/compile.rb', line 60 def validate_type() unless [:type] Util.log("[metanorma] Error: Please specify a standard type: #{@registry.supported_backends}.", :error) return nil end stdtype = [:type].to_sym unless @registry.supported_backends.include? stdtype Util.log("[metanorma] Info: Loading `metanorma-#{stdtype}` gem for standard type `#{stdtype}`.", :info) end begin require "metanorma-#{stdtype}" Util.log("[metanorma] Info: gem `metanorma-#{stdtype}` loaded.", :info) rescue LoadError Util.log("[metanorma] Error: loading gem `metanorma-#{stdtype}` failed. Exiting.", :error) return false end unless @registry.supported_backends.include? stdtype Util.log("[metanorma] Error: The `metanorma-#{stdtype}` gem still doesn't support `#{stdtype}`. Exiting.", :error) return false end true end |
#xml_options_extract(file) ⇒ Object
31 32 33 34 35 36 37 38 39 |
# File 'lib/metanorma/compile.rb', line 31 def (file) xml = Nokogiri::XML(file) if xml.root @registry..each do |k, v| return { type: k } if v == xml.root.name end end {} end |