Class: Metanorma::Document::CLI

Inherits:
Object
  • Object
show all
Defined in:
lib/metanorma/document/cli.rb

Defined Under Namespace

Classes: Error, ToHtmlOptions, ToMirrorOptions

Class Method Summary collapse

Class Method Details

.execute_to_html(options) ⇒ Object



145
146
147
148
149
150
151
152
153
# File 'lib/metanorma/document/cli.rb', line 145

def self.execute_to_html(options)
  # Metanorma::Html is autoloaded from metanorma/document.
  # Reuse the mirror pipeline's flavor inference/model dispatch so
  # to-html and to-mirror parse documents identically.
  step = Mirror::Output::Pipeline::Steps::ParseXml.new
  flavor = options.flavor || step.infer_flavor(options.xml_path)
  doc = step.flavor_class(flavor).from_xml(File.read(options.xml_path))
  write_output(Html::Generator.generate(doc), options.output)
end

.execute_to_mirror(options) ⇒ Object



91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/metanorma/document/cli.rb', line 91

def self.execute_to_mirror(options)
  pipeline = Mirror::Output::Pipeline.new(
    xml_path: options.xml_path,
    flavor: options.flavor,
    title: options.title,
    id_strategy: options.id_strategy,
  )
  guide = pipeline.process

  json = Mirror::Serialization::JsonSerializer.serialize_pretty(guide.content)
  write_output(json, options.output)
end

.parse_to_html_options(argv) ⇒ Object

Raises:



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/metanorma/document/cli.rb', line 118

def self.parse_to_html_options(argv)
  options = ToHtmlOptions.new(output: nil, flavor: nil)

  parser = OptionParser.new do |opts|
    opts.banner = "Usage: metanorma-document to-html <xml_path> [options]"

    opts.on("-o", "--output PATH",
            "Output HTML path (default: stdout)") do |path|
      options.output = path
    end

    opts.on("-f", "--flavor FLAVOR",
            "Document flavor (default: auto-detect)") do |flavor|
      options.flavor = flavor
    end
  end

  parser.parse!(argv)

  xml_path = argv.shift
  raise Error, "XML path required" unless xml_path
  raise Error, "File not found: #{xml_path}" unless File.exist?(xml_path)

  options.xml_path = xml_path
  options
end

.parse_to_mirror_options(argv) ⇒ Object

Raises:



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
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
# File 'lib/metanorma/document/cli.rb', line 46

def self.parse_to_mirror_options(argv)
  options = ToMirrorOptions.new(output: nil, flavor: nil,
                                id_strategy: nil, title: nil)

  parser = OptionParser.new do |opts|
    opts.banner = "Usage: metanorma-document to-mirror <xml_path> [options]"

    opts.on("-o", "--output PATH",
            "Output JSON path (default: stdout)") do |path|
      options.output = path
    end

    opts.on("-f", "--flavor FLAVOR",
            "Document flavor (default: auto-detect)") do |flavor|
      options.flavor = flavor
    end

    opts.on("--id-strategy STRATEGY",
            "ID strategy: preserve (default), positional") do |strategy|
      case strategy
      when "positional"
        options.id_strategy = Mirror::IdStrategy::Positional.new
      when "preserve"
        options.id_strategy = Mirror::IdStrategy::Preserve.new
      else
        raise Error,
              "Unknown ID strategy: #{strategy}. Use 'preserve' or 'positional'."
      end
    end

    opts.on("--title TITLE", "Document title override") do |title|
      options.title = title
    end
  end

  parser.parse!(argv)

  xml_path = argv.shift
  raise Error, "XML path required" unless xml_path
  raise Error, "File not found: #{xml_path}" unless File.exist?(xml_path)

  options.xml_path = xml_path
  options
end

.run(argv) ⇒ Object



27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/metanorma/document/cli.rb', line 27

def self.run(argv)
  command = argv.shift
  case command
  when "to-mirror"
    to_mirror(argv)
  when "to-html"
    to_html(argv)
  when nil, "-h", "--help"
    puts usage
  else
    raise Error, "Unknown command: #{command}"
  end
end

.to_html(argv) ⇒ Object



113
114
115
116
# File 'lib/metanorma/document/cli.rb', line 113

def self.to_html(argv)
  options = parse_to_html_options(argv)
  execute_to_html(options)
end

.to_mirror(argv) ⇒ Object



41
42
43
44
# File 'lib/metanorma/document/cli.rb', line 41

def self.to_mirror(argv)
  options = parse_to_mirror_options(argv)
  execute_to_mirror(options)
end

.usageObject



155
156
157
158
159
160
161
162
163
164
165
# File 'lib/metanorma/document/cli.rb', line 155

def self.usage
  <<~USAGE
    Usage: metanorma-document <command> [options]

    Commands:
      to-mirror    Convert presentation XML to mirror JSON
      to-html      Render presentation XML to standalone HTML

    Run `metanorma-document <command> --help` for command-specific options.
  USAGE
end

.write_output(json, output_path) ⇒ Object



104
105
106
107
108
109
110
111
# File 'lib/metanorma/document/cli.rb', line 104

def self.write_output(json, output_path)
  if output_path
    FileUtils.mkdir_p(File.dirname(output_path))
    File.write(output_path, json)
  else
    $stdout.puts(json)
  end
end