diff -r 0b5a5b60fd2c pygments/lexers/math.py --- a/pygments/lexers/math.py Wed Sep 16 21:36:37 2009 +0200 +++ b/pygments/lexers/math.py Fri Sep 25 09:51:55 2009 +0100 @@ -22,7 +22,7 @@ from pygments.lexers.agile import PythonLexer __all__ = ['MuPADLexer', 'MatlabLexer', 'MatlabSessionLexer', 'NumPyLexer', - 'SLexer'] + 'RConsoleLexer', 'SLexer'] class MuPADLexer(RegexLexer): @@ -340,6 +340,52 @@ yield index, token, value + +class RConsoleLexer(Lexer): + """ + For R console transcripts or R CMD BATCH output files. + """ + + name = 'RConsole' + aliases = ['rconsole', 'rout'] + filenames = ['*.Rout'] + + def get_tokens_unprocessed(self, text): + slexer = SLexer(**self.options) + + current_code_block = '' + insertions = [] + + for match in line_re.finditer(text): + line = match.group() + if line.startswith('>') or line.startswith('+'): + # Colorize the prompt as such, + # then put rest of line into current_code_block + insertions.append((len(current_code_block), + [(0, Generic.Prompt, line[:2])])) + current_code_block += line[2:] + else: + # We have reached a non-prompt line! + # If we have stored prompt lines, need to process them first. + if current_code_block: + # Weave together the prompts and highlit code. + for item in do_insertions(insertions, + slexer.get_tokens_unprocessed(current_code_block)): + yield item + # Reset vars for next code block. + current_code_block = '' + insertions = [] + # Now process the actual line itself, this is output from R. + yield match.start(), Generic.Output, line + + # If we happen to end on a code block with nothing after it, need to process + # the last code block. This is neither elegant nor DRY so should be changed. + if current_code_block: + for item in do_insertions(insertions, + slexer.get_tokens_unprocessed(current_code_block)): + yield item + + class SLexer(RegexLexer): """ For S, S-plus, and R source code.