class Rouge::Lexers::ConsoleLexer
The {ConsoleLexer} class is intended to lex content that represents the text that would display in a console/terminal. As distinct from the {Shell} lexer, {ConsoleLexer} will try to parse out the prompt from each line before passing the remainder of the line to the language lexer for the shell (by default, the {Shell} lexer).
The {ConsoleLexer} class accepts five options:
-
lang: the shell language to lex (default: ‘shell`);
-
output: the output language (default: ‘plaintext?token=Generic.Output`);
-
prompt: comma-separated list of strings that indicate the end of a prompt (default: ‘$,#,>,;`);
-
comments: whether to enable comments.
-
error: comma-separated list of strings that indicate the start of an error message
The comments option, if enabled, will lex lines that begin with a ‘#` as a comment. Please note that this option will only work if the prompt is either not manually specified or, if manually specified, does not include the `#` character.
Most Markdown
lexers that recognise GitHub-Flavored Markdown
syntax, will pass the language string to Rouge
as written in the original document. This allows an end user to pass options to {ConsoleLexer} by passing them as CGI-style parameters as in the example below.
@example <pre>Here’s some regular text.
“‘console?comments=true # This is a comment $ cp foo bar “`
Some more regular text.</pre>
Public Class Methods
Rouge::Lexer::new
# File lib/rouge/lexers/console.rb, line 51 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
Public Instance Methods
whether to allow comments. if manually specifying a prompt that isn’t simply “#”, we flag this to on
# File lib/rouge/lexers/console.rb, line 62 def allow_comments? case @comments when :guess @prompt && !@prompt.empty? && !end_chars.include?('#') else @comments end end
# File lib/rouge/lexers/console.rb, line 71 def comment_regex /\A\s*?#/ end
# File lib/rouge/lexers/console.rb, line 75 def end_chars @end_chars ||= if @prompt.any? @prompt.reject { |c| c.empty? } elsif allow_comments? %w($ > ;) else %w($ # > ;) end end
# File lib/rouge/lexers/console.rb, line 85 def error_regex @error_regex ||= if @error.any? /^(?:#{@error.map(&Regexp.method(:escape)).join('|')})/ end end
# File lib/rouge/lexers/console.rb, line 91 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
# File lib/rouge/lexers/console.rb, line 104 def line_regex /(\\.|[^\\])*?(\n|$)/m end
# File lib/rouge/lexers/console.rb, line 108 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
# File lib/rouge/lexers/console.rb, line 121 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
# File lib/rouge/lexers/console.rb, line 166 def prompt_prefix_regex if allow_comments? /[^<#]*?/m else /.*?/m end end
# File lib/rouge/lexers/console.rb, line 174 def prompt_regex @prompt_regex ||= begin /^#{prompt_prefix_regex}(?:#{end_chars.map(&Regexp.method(:escape)).join('|')})/ end end
# File lib/rouge/lexers/console.rb, line 180 def stream_tokens(input, &output) input = StringScanner.new(input) lang_lexer.reset! output_lexer.reset! process_line(input, &output) while !input.eos? end