Class: Asciidoctor::Cli::Invoker

Inherits:
Object
  • Object
show all
Includes:
Logging
Defined in:
lib/asciidoctor/cli/invoker.rb

Overview

Public Invocation class for starting Asciidoctor via CLI

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Logging

#logger, #message_with_context

Constructor Details

#initialize(*options) ⇒ Invoker

Returns a new instance of Invoker.



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/asciidoctor/cli/invoker.rb', line 12

def initialize *options
  @documents = []
  @out = nil
  @err = nil
  @code = 0
  options = options.flatten
  case (first_option = options[0])
  when Options
    @options = first_option
  when ::Hash
    @options = Options.new options
  else
    if ::Integer === (result = Options.parse! options)
      @code = result
      @options = nil
    else
      @options = result
    end
  end
end

Instance Attribute Details

#codeObject (readonly)



10
11
12
# File 'lib/asciidoctor/cli/invoker.rb', line 10

def code
  @code
end

#documentsObject (readonly)



9
10
11
# File 'lib/asciidoctor/cli/invoker.rb', line 9

def documents
  @documents
end

#optionsObject (readonly)



8
9
10
# File 'lib/asciidoctor/cli/invoker.rb', line 8

def options
  @options
end

Instance Method Details

#documentObject



157
158
159
# File 'lib/asciidoctor/cli/invoker.rb', line 157

def document
  @documents[0]
end

#invoke!Object



33
34
35
36
37
38
39
40
41
42
43
44
45
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
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
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/asciidoctor/cli/invoker.rb', line 33

def invoke!
  return unless @options

  old_logger = old_logger_level = nil
  old_verbose, $VERBOSE = $VERBOSE, @options[:warnings]
  opts = {}
  infiles = []
  outfile = nil
  abs_srcdir_posix = nil
  non_posix_env = ::File::ALT_SEPARATOR == RS
  err = @err || $stderr
  show_timings = false

  @options.map do |key, val|
    case key
    when :input_files
      infiles = val
    when :output_file
      outfile = val
    when :source_dir
      if val
        abs_srcdir_posix = ::File.expand_path val
        abs_srcdir_posix = abs_srcdir_posix.tr RS, FS if non_posix_env && (abs_srcdir_posix.include? RS)
      end
    when :destination_dir
      opts[:to_dir] = val if val
    when :attributes
      # NOTE processor will dup attributes internally
      opts[:attributes] = val
    when :timings
      show_timings = val
    when :trace
      # no assignment
    when :verbose
      case val
      when 0
        $VERBOSE = nil
        old_logger, LoggerManager.logger = logger, NullLogger.new
      when 2
        old_logger_level, logger.level = logger.level, ::Logger::Severity::DEBUG
      end
    else
      opts[key] = val unless val.nil?
    end
  end

  if infiles.size == 1
    if (infile0 = infiles[0]) == '-'
      outfile ||= infile0
      stdin = true
    elsif ::File.pipe? infile0
      outfile ||= '-'
    end
  end

  if outfile == '-'
    # NOTE set_encoding returns nil on JRuby 9.1
    (tofile = @out) || ((tofile = $stdout).set_encoding UTF_8)
  elsif outfile
    opts[:mkdirs] = true
    tofile = outfile
  else
    opts[:mkdirs] = true
    # automatically calculate outfile based on infile
  end

  if stdin
    # allows use of block to supply stdin, particularly useful for tests
    # NOTE set_encoding returns nil on JRuby 9.1
    block_given? ? (input = yield) : ((input = $stdin).set_encoding UTF_8, UTF_8)
    input_opts = opts.merge to_file: tofile
    if show_timings
      @documents << (::Asciidoctor.convert input, (input_opts.merge timings: (timings = Timings.new)))
      timings.print_report err, '-'
    else
      @documents << (::Asciidoctor.convert input, input_opts)
    end
  else
    infiles.each do |infile|
      input_opts = opts.merge to_file: tofile
      if abs_srcdir_posix && (input_opts.key? :to_dir)
        abs_indir = ::File.dirname ::File.expand_path infile
        if non_posix_env
          abs_indir_posix = (abs_indir.include? RS) ? (abs_indir.tr RS, FS) : abs_indir
        else
          abs_indir_posix = abs_indir
        end
        if abs_indir_posix.start_with? %(#{abs_srcdir_posix}/)
          input_opts[:to_dir] += abs_indir.slice abs_srcdir_posix.length, abs_indir.length
        end
      end
      if show_timings
        @documents << (::Asciidoctor.convert_file infile, (input_opts.merge timings: (timings = Timings.new)))
        timings.print_report err, infile
      else
        @documents << (::Asciidoctor.convert_file infile, input_opts)
      end
    end
  end
  @code = 1 if (logger.respond_to? :max_severity) && logger.max_severity && logger.max_severity >= opts[:failure_level]
rescue ::Exception => e
  if ::SignalException === e
    @code = e.signo
    # add extra newline if Ctrl+C is used
    err.puts if ::Interrupt === e
  else
    @code = (e.respond_to? :status) ? e.status : 1
    if @options[:trace]
      raise e
    else
      err.puts ::RuntimeError === e ? %(#{e.message} (#{e.class})) : e.message
      err.puts '  Use --trace for backtrace'
    end
  end
  nil
ensure
  $VERBOSE = old_verbose
  if old_logger
    LoggerManager.logger = old_logger
  elsif old_logger_level
    logger.level = old_logger_level
  end
end

#read_errorObject



170
171
172
# File 'lib/asciidoctor/cli/invoker.rb', line 170

def read_error
  @err ? @err.string : ''
end

#read_outputObject



166
167
168
# File 'lib/asciidoctor/cli/invoker.rb', line 166

def read_output
  @out ? @out.string : ''
end

#redirect_streams(out, err = nil) ⇒ Object



161
162
163
164
# File 'lib/asciidoctor/cli/invoker.rb', line 161

def redirect_streams out, err = nil
  @out = out
  @err = err
end

#reset_streamsObject



174
175
176
177
# File 'lib/asciidoctor/cli/invoker.rb', line 174

def reset_streams
  @out = nil
  @err = nil
end