exe/metanorma-manifest
#!/usr/bin/env ruby
require "yaml"
require "optparse"
require "metanorma"
require "uuidtools"
require "uri"
require "metanorma-cli"
registry = Metanorma::Registry.instance
Metanorma::Cli.load_flavors
options = {}
def uuid
UUIDTools::UUID.random_create
end
def extract_documents(m)
return [] unless m && m["sections"]
ret = []
m["sections"].each do |s|
ret << s if s["file"]
ret << extract_documents(s) if s["sections"]
end
ret.flatten
end
def hyperlink(link, suffix)
return unless link
link.sub(/\.adoc(?=$|#)/, ".#{suffix}")
end
def iterate(sections, options)
return "" unless sections
ret = ""
Array(sections).each do |m|
ret += "<clause id='#{uuid}'>\n"
title = m["title"] && m["number"] ? "#{m['number']}. #{m['title']}" : (m["number"] || m["title"] || "—")
ret += "<title>#{title}</title>\n"
ret += "<p>#{m['type']}</p>\n" if m["type"]
if m["file"]
ret += "<p>"
file = hyperlink(m["file"], "html")
ret += "<link target='#{file}'>HTML</link> |" if file
file = hyperlink(m["file"], "pdf")
ret += "<link target='#{file}'>PDF</link> |" if file
file = hyperlink(m["file"], "xml")
ret += "<link target='#{file}'>XML</link> " if file
if options[:relaton]
file = URI.escape("#{options[:relaton]}/id/#{m['number']}.xml")
ret += "| <link target='#{file}'>Relaton XML</link> "
end
ret += "</p>\n"
end
ret += "<p>#{m['description']}</p>\n" if m["description"]
if m["revdate"]
ret += if m["status"]
"<p>STAGE: #{m['status']} (#{m['revdate']})</p>\n"
else
"<p align='right'>#{m['revdate']}</p>\n"
end
elsif m["status"]
ret += "<p>STAGE: #{m['status']}</p>\n"
end
ret += iterate(m["sections"], options)
ret += "</clause>\n"
end
ret
end
opt_parser = OptionParser.new do |opts|
opts.banner += " <file>"
opts.on(
"-t",
"--type TYPE",
"Type of standard to generate",
) { |v| options[:type] = v.to_sym }
opts.on(
"-r",
"--require LIBRARY",
"Require LIBRARY prior to execution",
) do |v|
options[:require] ||= []
options[:require] << v
end
opts.on(
"-R dir",
"--relaton",
"Insert links to relaton XML, generated by relaton-server-csd, with root directory dir (/id/xxxx is supplied)",
) { |v| options[:relaton] = v }
opts.on_tail("-h", "--help", "Show this message") do
puts opts
exit
end
end
opt_parser.parse!(ARGV)
options[:filename] = ARGV.pop
if options[:require]
options[:require].each do |r|
require r
end
end
manifest = YAML.load_file(options[:filename])
documents = extract_documents(manifest)
# TODO real lookup of namespaces and root elements
out = <<~END
<#{options[:type]}-standard xmlns="http://riboseinc.com/isoxml">
<bibdata type="standard">
<title>#{manifest['title']}</title>
END
# TODO leave in anchor references?
#
documents.each do |d|
out += <<~END
<relation type="partOf">
<bibdata type="standard">
<title>#{d['title']}</title>
<docidentifier>#{d['number']}</docidentifier>
<abstract>#{d['description']}</abstract>
</bibdata>
</relation>
END
end
out += <<~END
</bibdata>
<sections>
END
out += iterate(manifest["sections"], options)
out += <<~END
</sections>
<#{options[:type]}-standard>
END
outfilename = options[:filename].sub(/\.[^.]+$/, ".xml")
File.open(outfilename, "w") { |f| f.write out }
processor = registry.find_processor(options[:type].to_sym)
ext = :html
file_extension = "html" || processor.output_formats[ext]
outfilename = options[:filename].sub(/\.[^.]+$/, ".#{file_extension}")
isodoc_options = { suppressheadingnumbers: true }
if manifest["htmlstylesheet"]
isodoc_options[:htmlstylesheet] =
manifest["htmlstylesheet"]
end
processor.output(out, outfilename, ext, isodoc_options)