class Rouge::Lexers::ConsoleLexer

Some more regular text.</pre>
“‘
$ cp foo bar
# This is a comment
“`console?comments=true
<pre>Here’s some regular text.
@example
as CGI-style parameters as in the example below.
This allows an end user to pass options to {ConsoleLexer} by passing them
pass the language string to Rouge as written in the original document.
Most Markdown lexers that recognise GitHub-Flavored Markdown syntax, will
the ‘#` character.
either not manually specified or, if manually specified, does not include
comment. Please note that this option will only work if the prompt is
The comments option, if enabled, will lex lines that begin with a `#` as a
error message
5. error: comma-separated list of strings that indicate the start of an
4. comments: whether to enable comments.
prompt (default: `$,#,>,;`);
3. prompt: comma-separated list of strings that indicate the end of a
2. output: the output language (default: `plaintext?token=Generic.Output`);
1. lang: the shell language to lex (default: `shell`);
The {ConsoleLexer} class accepts five options:
the shell (by default, the {Shell} lexer).
line before passing the remainder of the line to the language lexer for
{Shell} lexer, {ConsoleLexer} will try to parse out the prompt from each
text that would display in a console/terminal. As distinct from the
The {ConsoleLexer} class is intended to lex content that represents the

def allow_comments?

simply "#", we flag this to on
whether to allow comments. if manually specifying a prompt that isn't
def allow_comments?
  case @comments
  when :guess
    @prompt && !@prompt.empty? && !end_chars.include?('#')
  else
    @comments
  end
end

def comment_regex

def comment_regex
  /\A\s*?#/
end

def end_chars

def end_chars
  @end_chars ||= if @prompt.any?
    @prompt.reject { |c| c.empty? }
  elsif allow_comments?
    %w($ > ;)
  else
    %w($ # > ;)
  end
end

def error_regex

def error_regex
  @error_regex ||= if @error.any?
    /^(?:#{@error.map(&Regexp.method(:escape)).join('|')})/
  end
end

def initialize(*)

def initialize(*)
  super
  @prompt = list_option(:prompt) { nil }
  @lang = lexer_option(:lang) { 'shell' }
  @output = lexer_option(:output) { PlainText.new(token: Generic::Output) }
  @comments = bool_option(:comments) { :guess }
  @error = list_option(:error) { nil }
end

def lang_lexer

def lang_lexer
  @lang_lexer ||= case @lang
  when Lexer
    @lang
  when nil
    Shell.new(options)
  when Class
    @lang.new(options)
  when String
    Lexer.find(@lang).new(options)
  end
end

def line_regex

def line_regex
  /(.*?)(\n|$)/
end

def output_lexer

def output_lexer
  @output_lexer ||= case @output
  when nil
    PlainText.new(token: Generic::Output)
  when Lexer
    @output
  when Class
    @output.new(options)
  when String
    Lexer.find(@output).new(options)
  end
end

def process_line(input, &output)

def process_line(input, &output)
  input.scan(line_regex)
  # As a nicety, support the use of elisions in input text. A user can
  # write a line with only `<...>` or one or more `.` characters and
  # Rouge will treat it as a comment.
  if input[0] =~ /\A\s*(?:<[.]+>|[.]+)\s*\z/
    puts "console: matched snip #{input[0].inspect}" if @debug
    output_lexer.reset!
    lang_lexer.reset!
    yield Comment, input[0]
  elsif prompt_regex =~ input[0]
    puts "console: matched prompt #{input[0].inspect}" if @debug
    output_lexer.reset!
    yield Generic::Prompt, $&
    # make sure to take care of initial whitespace
    # before we pass to the lang lexer so it can determine where
    # the "real" beginning of the line is
    $' =~ /\A\s*/
    yield Text::Whitespace, $& unless $&.empty?
    lang_lexer.continue_lex($', &output)
  elsif comment_regex =~ input[0].strip
    puts "console: matched comment #{input[0].inspect}" if @debug
    output_lexer.reset!
    lang_lexer.reset!
    yield Comment, input[0]
  elsif error_regex =~ input[0]
    puts "console: matched error #{input[0].inspect}" if @debug
    output_lexer.reset!
    lang_lexer.reset!
    yield Generic::Error, input[0]
  else
    puts "console: matched output #{input[0].inspect}" if @debug
    lang_lexer.reset!
    output_lexer.continue_lex(input[0], &output)
  end
end

def prompt_prefix_regex

def prompt_prefix_regex
  if allow_comments?
    /[^<#]*?/m
  else
    /.*?/m
  end
end

def prompt_regex

def prompt_regex
  @prompt_regex ||= begin
    /^#{prompt_prefix_regex}(?:#{end_chars.map(&Regexp.method(:escape)).join('|')})/
  end
end

def stream_tokens(input, &output)

def stream_tokens(input, &output)
  input = StringScanner.new(input)
  lang_lexer.reset!
  output_lexer.reset!
  process_line(input, &output) while !input.eos?
end