pygmentize 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. data/LICENSE +19 -0
  2. data/lib/pygments.rb +23 -0
  3. data/pygmentize.gemspec +11 -0
  4. data/test/pygments.rb +19 -0
  5. data/vendor/pygmentize.py +7 -0
  6. data/vendor/pygments/AUTHORS +73 -0
  7. data/vendor/pygments/LICENSE +25 -0
  8. data/vendor/pygments/__init__.py +91 -0
  9. data/vendor/pygments/__init__.pyc +0 -0
  10. data/vendor/pygments/cmdline.py +430 -0
  11. data/vendor/pygments/cmdline.pyc +0 -0
  12. data/vendor/pygments/console.py +74 -0
  13. data/vendor/pygments/console.pyc +0 -0
  14. data/vendor/pygments/filter.py +74 -0
  15. data/vendor/pygments/filter.pyc +0 -0
  16. data/vendor/pygments/filters/__init__.py +357 -0
  17. data/vendor/pygments/filters/__init__.pyc +0 -0
  18. data/vendor/pygments/formatter.py +92 -0
  19. data/vendor/pygments/formatter.pyc +0 -0
  20. data/vendor/pygments/formatters/__init__.py +68 -0
  21. data/vendor/pygments/formatters/__init__.pyc +0 -0
  22. data/vendor/pygments/formatters/_mapping.py +92 -0
  23. data/vendor/pygments/formatters/_mapping.pyc +0 -0
  24. data/vendor/pygments/formatters/bbcode.py +109 -0
  25. data/vendor/pygments/formatters/bbcode.pyc +0 -0
  26. data/vendor/pygments/formatters/html.py +723 -0
  27. data/vendor/pygments/formatters/html.pyc +0 -0
  28. data/vendor/pygments/formatters/img.py +553 -0
  29. data/vendor/pygments/formatters/img.pyc +0 -0
  30. data/vendor/pygments/formatters/latex.py +354 -0
  31. data/vendor/pygments/formatters/latex.pyc +0 -0
  32. data/vendor/pygments/formatters/other.py +117 -0
  33. data/vendor/pygments/formatters/other.pyc +0 -0
  34. data/vendor/pygments/formatters/rtf.py +136 -0
  35. data/vendor/pygments/formatters/rtf.pyc +0 -0
  36. data/vendor/pygments/formatters/svg.py +154 -0
  37. data/vendor/pygments/formatters/svg.pyc +0 -0
  38. data/vendor/pygments/formatters/terminal.py +109 -0
  39. data/vendor/pygments/formatters/terminal.pyc +0 -0
  40. data/vendor/pygments/formatters/terminal256.py +219 -0
  41. data/vendor/pygments/formatters/terminal256.pyc +0 -0
  42. data/vendor/pygments/lexer.py +660 -0
  43. data/vendor/pygments/lexer.pyc +0 -0
  44. data/vendor/pygments/lexers/__init__.py +226 -0
  45. data/vendor/pygments/lexers/__init__.pyc +0 -0
  46. data/vendor/pygments/lexers/_asybuiltins.py +1645 -0
  47. data/vendor/pygments/lexers/_clbuiltins.py +232 -0
  48. data/vendor/pygments/lexers/_luabuiltins.py +256 -0
  49. data/vendor/pygments/lexers/_mapping.py +234 -0
  50. data/vendor/pygments/lexers/_mapping.pyc +0 -0
  51. data/vendor/pygments/lexers/_phpbuiltins.py +3389 -0
  52. data/vendor/pygments/lexers/_vimbuiltins.py +3 -0
  53. data/vendor/pygments/lexers/agile.py +1485 -0
  54. data/vendor/pygments/lexers/agile.pyc +0 -0
  55. data/vendor/pygments/lexers/asm.py +353 -0
  56. data/vendor/pygments/lexers/compiled.py +2365 -0
  57. data/vendor/pygments/lexers/dotnet.py +355 -0
  58. data/vendor/pygments/lexers/functional.py +756 -0
  59. data/vendor/pygments/lexers/functional.pyc +0 -0
  60. data/vendor/pygments/lexers/math.py +461 -0
  61. data/vendor/pygments/lexers/other.py +2297 -0
  62. data/vendor/pygments/lexers/parsers.py +695 -0
  63. data/vendor/pygments/lexers/special.py +100 -0
  64. data/vendor/pygments/lexers/special.pyc +0 -0
  65. data/vendor/pygments/lexers/templates.py +1387 -0
  66. data/vendor/pygments/lexers/text.py +1586 -0
  67. data/vendor/pygments/lexers/web.py +1619 -0
  68. data/vendor/pygments/lexers/web.pyc +0 -0
  69. data/vendor/pygments/plugin.py +74 -0
  70. data/vendor/pygments/plugin.pyc +0 -0
  71. data/vendor/pygments/scanner.py +104 -0
  72. data/vendor/pygments/style.py +117 -0
  73. data/vendor/pygments/style.pyc +0 -0
  74. data/vendor/pygments/styles/__init__.py +68 -0
  75. data/vendor/pygments/styles/__init__.pyc +0 -0
  76. data/vendor/pygments/styles/autumn.py +65 -0
  77. data/vendor/pygments/styles/borland.py +51 -0
  78. data/vendor/pygments/styles/bw.py +49 -0
  79. data/vendor/pygments/styles/colorful.py +81 -0
  80. data/vendor/pygments/styles/default.py +73 -0
  81. data/vendor/pygments/styles/default.pyc +0 -0
  82. data/vendor/pygments/styles/emacs.py +72 -0
  83. data/vendor/pygments/styles/friendly.py +72 -0
  84. data/vendor/pygments/styles/fruity.py +43 -0
  85. data/vendor/pygments/styles/manni.py +75 -0
  86. data/vendor/pygments/styles/monokai.py +106 -0
  87. data/vendor/pygments/styles/murphy.py +80 -0
  88. data/vendor/pygments/styles/native.py +65 -0
  89. data/vendor/pygments/styles/pastie.py +75 -0
  90. data/vendor/pygments/styles/perldoc.py +69 -0
  91. data/vendor/pygments/styles/tango.py +141 -0
  92. data/vendor/pygments/styles/trac.py +63 -0
  93. data/vendor/pygments/styles/vim.py +63 -0
  94. data/vendor/pygments/styles/vs.py +38 -0
  95. data/vendor/pygments/token.py +198 -0
  96. data/vendor/pygments/token.pyc +0 -0
  97. data/vendor/pygments/unistring.py +130 -0
  98. data/vendor/pygments/unistring.pyc +0 -0
  99. data/vendor/pygments/util.py +226 -0
  100. data/vendor/pygments/util.pyc +0 -0
  101. metadata +166 -0
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2010 Damian Janowski & Michel Martens
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
@@ -0,0 +1,23 @@
1
+ require "shellwords"
2
+
3
+ class Pygments
4
+ VERSION = "0.0.1"
5
+
6
+ def self.bin
7
+ "/usr/bin/env python #{File.expand_path("../vendor/pygmentize.py", File.dirname(__FILE__))}"
8
+ end
9
+
10
+ def self.pygmentize(source, lexer)
11
+ args = [
12
+ "-l", lexer.to_s,
13
+ "-f", "html",
14
+ "-O", "encoding=#{source.encoding}"
15
+ ]
16
+
17
+ IO.popen("#{bin} #{Shellwords.shelljoin args}", "r+") do |io|
18
+ io.write(source)
19
+ io.close_write
20
+ io.read
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,11 @@
1
+
2
+ Gem::Specification.new do |s|
3
+ s.name = "pygmentize"
4
+ s.version = "0.0.1"
5
+ s.summary = "A Ruby gem that vendors Pygments"
6
+ s.description = "A Ruby gem that vendors Pygments"
7
+ s.authors = ["Damian Janowski", "Michel Martens"]
8
+ s.email = ["djanowski@dimaion.com", "michel@soveran.com"]
9
+ s.homepage = "http://github.com/djanowski/pygments"
10
+ s.files = ["pygmentize.gemspec", "LICENSE", "lib/pygments.rb", "test/pygments.rb", "vendor/pygmentize.py", "vendor/pygments", "vendor/pygments/__init__.py", "vendor/pygments/__init__.pyc", "vendor/pygments/AUTHORS", "vendor/pygments/cmdline.py", "vendor/pygments/cmdline.pyc", "vendor/pygments/console.py", "vendor/pygments/console.pyc", "vendor/pygments/filter.py", "vendor/pygments/filter.pyc", "vendor/pygments/filters", "vendor/pygments/filters/__init__.py", "vendor/pygments/filters/__init__.pyc", "vendor/pygments/formatter.py", "vendor/pygments/formatter.pyc", "vendor/pygments/formatters", "vendor/pygments/formatters/__init__.py", "vendor/pygments/formatters/__init__.pyc", "vendor/pygments/formatters/_mapping.py", "vendor/pygments/formatters/_mapping.pyc", "vendor/pygments/formatters/bbcode.py", "vendor/pygments/formatters/bbcode.pyc", "vendor/pygments/formatters/html.py", "vendor/pygments/formatters/html.pyc", "vendor/pygments/formatters/img.py", "vendor/pygments/formatters/img.pyc", "vendor/pygments/formatters/latex.py", "vendor/pygments/formatters/latex.pyc", "vendor/pygments/formatters/other.py", "vendor/pygments/formatters/other.pyc", "vendor/pygments/formatters/rtf.py", "vendor/pygments/formatters/rtf.pyc", "vendor/pygments/formatters/svg.py", "vendor/pygments/formatters/svg.pyc", "vendor/pygments/formatters/terminal.py", "vendor/pygments/formatters/terminal.pyc", "vendor/pygments/formatters/terminal256.py", "vendor/pygments/formatters/terminal256.pyc", "vendor/pygments/lexer.py", "vendor/pygments/lexer.pyc", "vendor/pygments/lexers", "vendor/pygments/lexers/__init__.py", "vendor/pygments/lexers/__init__.pyc", "vendor/pygments/lexers/_asybuiltins.py", "vendor/pygments/lexers/_clbuiltins.py", "vendor/pygments/lexers/_luabuiltins.py", "vendor/pygments/lexers/_mapping.py", "vendor/pygments/lexers/_mapping.pyc", "vendor/pygments/lexers/_phpbuiltins.py", "vendor/pygments/lexers/_vimbuiltins.py", "vendor/pygments/lexers/agile.py", "vendor/pygments/lexers/agile.pyc", "vendor/pygments/lexers/asm.py", "vendor/pygments/lexers/compiled.py", "vendor/pygments/lexers/dotnet.py", "vendor/pygments/lexers/functional.py", "vendor/pygments/lexers/functional.pyc", "vendor/pygments/lexers/math.py", "vendor/pygments/lexers/other.py", "vendor/pygments/lexers/parsers.py", "vendor/pygments/lexers/special.py", "vendor/pygments/lexers/special.pyc", "vendor/pygments/lexers/templates.py", "vendor/pygments/lexers/text.py", "vendor/pygments/lexers/web.py", "vendor/pygments/lexers/web.pyc", "vendor/pygments/LICENSE", "vendor/pygments/plugin.py", "vendor/pygments/plugin.pyc", "vendor/pygments/scanner.py", "vendor/pygments/style.py", "vendor/pygments/style.pyc", "vendor/pygments/styles", "vendor/pygments/styles/__init__.py", "vendor/pygments/styles/__init__.pyc", "vendor/pygments/styles/autumn.py", "vendor/pygments/styles/borland.py", "vendor/pygments/styles/bw.py", "vendor/pygments/styles/colorful.py", "vendor/pygments/styles/default.py", "vendor/pygments/styles/default.pyc", "vendor/pygments/styles/emacs.py", "vendor/pygments/styles/friendly.py", "vendor/pygments/styles/fruity.py", "vendor/pygments/styles/manni.py", "vendor/pygments/styles/monokai.py", "vendor/pygments/styles/murphy.py", "vendor/pygments/styles/native.py", "vendor/pygments/styles/pastie.py", "vendor/pygments/styles/perldoc.py", "vendor/pygments/styles/tango.py", "vendor/pygments/styles/trac.py", "vendor/pygments/styles/vim.py", "vendor/pygments/styles/vs.py", "vendor/pygments/token.py", "vendor/pygments/token.pyc", "vendor/pygments/unistring.py", "vendor/pygments/unistring.pyc", "vendor/pygments/util.py", "vendor/pygments/util.pyc"]
11
+ end
@@ -0,0 +1,19 @@
1
+ # encoding: UTF-8
2
+
3
+ require File.expand_path("../lib/pygments", File.dirname(__FILE__))
4
+ require "nokogiri"
5
+
6
+ test "colorizes output" do
7
+ output = Pygments.pygmentize(%Q[{foo: "bar"}], :javascript)
8
+
9
+ doc = Nokogiri::HTML(output)
10
+
11
+ assert doc.at_xpath(".//div[@class='highlight']")
12
+ assert doc.at_xpath(".//div[@class='highlight']/pre/span[@class='nx' and text()='foo']")
13
+ end
14
+
15
+ test "handles encodings" do
16
+ output = Pygments.pygmentize(%Q[{foo: "bar", baz: "qüx"}], :javascript)
17
+
18
+ assert output.encoding == Encoding::UTF_8
19
+ end
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env python
2
+
3
+ import sys, pygments.cmdline
4
+ try:
5
+ sys.exit(pygments.cmdline.main(sys.argv))
6
+ except KeyboardInterrupt:
7
+ sys.exit(1)
@@ -0,0 +1,73 @@
1
+ Pygments is written and maintained by Georg Brandl <georg@python.org>.
2
+
3
+ Major developers are Tim Hatch <tim@timhatch.com> and Armin Ronacher
4
+ <armin.ronacher@active-4.com>.
5
+
6
+ Other contributors, listed alphabetically, are:
7
+
8
+ * Kumar Appaiah -- Debian control lexer
9
+ * Ali Afshar -- image formatter
10
+ * Andreas Amann -- AppleScript lexer
11
+ * Jeremy Ashkenas -- CoffeeScript lexer
12
+ * Stefan Matthias Aust -- Smalltalk lexer
13
+ * Ben Bangert -- Mako lexers
14
+ * Max Battcher -- Darcs patch lexer
15
+ * Paul Baumgart, 280 North, Inc. -- Objective-J lexer
16
+ * Michael Bayer -- Myghty lexers
17
+ * Jarrett Billingsley -- MiniD lexer
18
+ * Adam Blinkinsop -- Haskell, Redcode lexers
19
+ * Frits van Bommel -- assembler lexers
20
+ * Pierre Bourdon -- bugfixes
21
+ * Christopher Creutzig -- MuPAD lexer
22
+ * Pete Curry -- bugfixes
23
+ * Owen Durni -- haXe lexer
24
+ * Nick Efford -- Python 3 lexer
25
+ * Artem Egorkine -- terminal256 formatter
26
+ * Laurent Gautier -- R/S lexer
27
+ * Krzysiek Goj -- Scala lexer
28
+ * Matt Good -- Genshi, Cheetah lexers
29
+ * Patrick Gotthardt -- PHP namespaces support
30
+ * Olivier Guibe -- Asymptote lexer
31
+ * Matthew Harrison -- SVG formatter
32
+ * Steven Hazel -- Tcl lexer
33
+ * Aslak Hellesøy -- Gherkin lexer
34
+ * David Hess, Fish Software, Inc. -- Objective-J lexer
35
+ * Varun Hiremath -- Debian control lexer
36
+ * Dennis Kaarsemaker -- sources.list lexer
37
+ * Benjamin Kowarsch -- Modula-2 lexer
38
+ * Marek Kubica -- Scheme lexer
39
+ * Jochen Kupperschmidt -- Markdown processor
40
+ * Gerd Kurzbach -- Modelica lexer
41
+ * Mark Lee -- Vala lexer
42
+ * Ben Mabey -- Gherkin lexer
43
+ * Kirk McDonald -- D lexer
44
+ * Lukas Meuser -- BBCode formatter, Lua lexer
45
+ * Paulo Moura -- Logtalk lexer
46
+ * Ana Nelson -- Ragel, ANTLR, R console lexers
47
+ * Nam T. Nguyen -- Monokai style
48
+ * Jesper Noehr -- HTML formatter "anchorlinenos"
49
+ * Jonas Obrist -- BBCode lexer
50
+ * David Oliva -- Rebol lexer
51
+ * Ronny Pfannschmidt -- BBCode lexer
52
+ * Benjamin Peterson -- Test suite refactoring
53
+ * Justin Reidy -- MXML lexer
54
+ * Andre Roberge -- Tango style
55
+ * Konrad Rudolph -- LaTeX formatter enhancements
56
+ * Mario Ruggier -- Evoque lexers
57
+ * Stou Sandalski -- NumPy, FORTRAN, tcsh and XSLT lexers
58
+ * Matteo Sasso -- Common Lisp lexer
59
+ * Joe Schafer -- Ada lexer
60
+ * Ken Schutte -- Matlab lexers
61
+ * Tassilo Schweyer -- Io, MOOCode lexers
62
+ * Joerg Sieker -- ABAP lexer
63
+ * Kirill Simonov -- YAML lexer
64
+ * Tiberius Teng -- default style overhaul
65
+ * Jeremy Thurgood -- Erlang, Squid config lexers
66
+ * Erick Tryzelaar -- Felix lexer
67
+ * Whitney Young -- ObjectiveC lexer
68
+ * Nathan Weizenbaum -- Haml and Sass lexers
69
+ * Dietmar Winkler -- Modelica lexer
70
+ * Nils Winter -- Smalltalk lexer
71
+ * Davy Wybiral -- Clojure lexer
72
+
73
+ Many thanks for all contributions!
@@ -0,0 +1,25 @@
1
+ Copyright (c) 2006-2010 by the respective authors (see AUTHORS file).
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are
6
+ met:
7
+
8
+ * Redistributions of source code must retain the above copyright
9
+ notice, this list of conditions and the following disclaimer.
10
+
11
+ * Redistributions in binary form must reproduce the above copyright
12
+ notice, this list of conditions and the following disclaimer in the
13
+ documentation and/or other materials provided with the distribution.
14
+
15
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,91 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ Pygments
4
+ ~~~~~~~~
5
+
6
+ Pygments is a syntax highlighting package written in Python.
7
+
8
+ It is a generic syntax highlighter for general use in all kinds of software
9
+ such as forum systems, wikis or other applications that need to prettify
10
+ source code. Highlights are:
11
+
12
+ * a wide range of common languages and markup formats is supported
13
+ * special attention is paid to details, increasing quality by a fair amount
14
+ * support for new languages and formats are added easily
15
+ * a number of output formats, presently HTML, LaTeX, RTF, SVG, all image
16
+ formats that PIL supports, and ANSI sequences
17
+ * it is usable as a command-line tool and as a library
18
+ * ... and it highlights even Brainfuck!
19
+
20
+ The `Pygments tip`_ is installable with ``easy_install Pygments==dev``.
21
+
22
+ .. _Pygments tip:
23
+ http://dev.pocoo.org/hg/pygments-main/archive/tip.tar.gz#egg=Pygments-dev
24
+
25
+ :copyright: Copyright 2006-2010 by the Pygments team, see AUTHORS.
26
+ :license: BSD, see LICENSE for details.
27
+ """
28
+
29
+ __version__ = '1.3.1'
30
+ __docformat__ = 'restructuredtext'
31
+
32
+ __all__ = ['lex', 'format', 'highlight']
33
+
34
+
35
+ import sys
36
+
37
+ from pygments.util import StringIO, BytesIO
38
+
39
+
40
+ def lex(code, lexer):
41
+ """
42
+ Lex ``code`` with ``lexer`` and return an iterable of tokens.
43
+ """
44
+ try:
45
+ return lexer.get_tokens(code)
46
+ except TypeError, err:
47
+ if isinstance(err.args[0], str) and \
48
+ 'unbound method get_tokens' in err.args[0]:
49
+ raise TypeError('lex() argument must be a lexer instance, '
50
+ 'not a class')
51
+ raise
52
+
53
+
54
+ def format(tokens, formatter, outfile=None):
55
+ """
56
+ Format a tokenlist ``tokens`` with the formatter ``formatter``.
57
+
58
+ If ``outfile`` is given and a valid file object (an object
59
+ with a ``write`` method), the result will be written to it, otherwise
60
+ it is returned as a string.
61
+ """
62
+ try:
63
+ if not outfile:
64
+ #print formatter, 'using', formatter.encoding
65
+ realoutfile = formatter.encoding and BytesIO() or StringIO()
66
+ formatter.format(tokens, realoutfile)
67
+ return realoutfile.getvalue()
68
+ else:
69
+ formatter.format(tokens, outfile)
70
+ except TypeError, err:
71
+ if isinstance(err.args[0], str) and \
72
+ 'unbound method format' in err.args[0]:
73
+ raise TypeError('format() argument must be a formatter instance, '
74
+ 'not a class')
75
+ raise
76
+
77
+
78
+ def highlight(code, lexer, formatter, outfile=None):
79
+ """
80
+ Lex ``code`` with ``lexer`` and format it with the formatter ``formatter``.
81
+
82
+ If ``outfile`` is given and a valid file object (an object
83
+ with a ``write`` method), the result will be written to it, otherwise
84
+ it is returned as a string.
85
+ """
86
+ return format(lex(code, lexer), formatter, outfile)
87
+
88
+
89
+ if __name__ == '__main__':
90
+ from pygments.cmdline import main
91
+ sys.exit(main(sys.argv))
@@ -0,0 +1,430 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ pygments.cmdline
4
+ ~~~~~~~~~~~~~~~~
5
+
6
+ Command line interface.
7
+
8
+ :copyright: Copyright 2006-2010 by the Pygments team, see AUTHORS.
9
+ :license: BSD, see LICENSE for details.
10
+ """
11
+ import sys
12
+ import getopt
13
+ from textwrap import dedent
14
+
15
+ from pygments import __version__, highlight
16
+ from pygments.util import ClassNotFound, OptionError, docstring_headline
17
+ from pygments.lexers import get_all_lexers, get_lexer_by_name, get_lexer_for_filename, \
18
+ find_lexer_class, guess_lexer, TextLexer
19
+ from pygments.formatters import get_all_formatters, get_formatter_by_name, \
20
+ get_formatter_for_filename, find_formatter_class, \
21
+ TerminalFormatter # pylint:disable-msg=E0611
22
+ from pygments.filters import get_all_filters, find_filter_class
23
+ from pygments.styles import get_all_styles, get_style_by_name
24
+
25
+
26
+ USAGE = """\
27
+ Usage: %s [-l <lexer> | -g] [-F <filter>[:<options>]] [-f <formatter>]
28
+ [-O <options>] [-P <option=value>] [-o <outfile>] [<infile>]
29
+
30
+ %s -S <style> -f <formatter> [-a <arg>] [-O <options>] [-P <option=value>]
31
+ %s -L [<which> ...]
32
+ %s -N <filename>
33
+ %s -H <type> <name>
34
+ %s -h | -V
35
+
36
+ Highlight the input file and write the result to <outfile>.
37
+
38
+ If no input file is given, use stdin, if -o is not given, use stdout.
39
+
40
+ <lexer> is a lexer name (query all lexer names with -L). If -l is not
41
+ given, the lexer is guessed from the extension of the input file name
42
+ (this obviously doesn't work if the input is stdin). If -g is passed,
43
+ attempt to guess the lexer from the file contents, or pass through as
44
+ plain text if this fails (this can work for stdin).
45
+
46
+ Likewise, <formatter> is a formatter name, and will be guessed from
47
+ the extension of the output file name. If no output file is given,
48
+ the terminal formatter will be used by default.
49
+
50
+ With the -O option, you can give the lexer and formatter a comma-
51
+ separated list of options, e.g. ``-O bg=light,python=cool``.
52
+
53
+ The -P option adds lexer and formatter options like the -O option, but
54
+ you can only give one option per -P. That way, the option value may
55
+ contain commas and equals signs, which it can't with -O, e.g.
56
+ ``-P "heading=Pygments, the Python highlighter".
57
+
58
+ With the -F option, you can add filters to the token stream, you can
59
+ give options in the same way as for -O after a colon (note: there must
60
+ not be spaces around the colon).
61
+
62
+ The -O, -P and -F options can be given multiple times.
63
+
64
+ With the -S option, print out style definitions for style <style>
65
+ for formatter <formatter>. The argument given by -a is formatter
66
+ dependent.
67
+
68
+ The -L option lists lexers, formatters, styles or filters -- set
69
+ `which` to the thing you want to list (e.g. "styles"), or omit it to
70
+ list everything.
71
+
72
+ The -N option guesses and prints out a lexer name based solely on
73
+ the given filename. It does not take input or highlight anything.
74
+ If no specific lexer can be determined "text" is returned.
75
+
76
+ The -H option prints detailed help for the object <name> of type <type>,
77
+ where <type> is one of "lexer", "formatter" or "filter".
78
+
79
+ The -h option prints this help.
80
+ The -V option prints the package version.
81
+ """
82
+
83
+
84
+ def _parse_options(o_strs):
85
+ opts = {}
86
+ if not o_strs:
87
+ return opts
88
+ for o_str in o_strs:
89
+ if not o_str:
90
+ continue
91
+ o_args = o_str.split(',')
92
+ for o_arg in o_args:
93
+ o_arg = o_arg.strip()
94
+ try:
95
+ o_key, o_val = o_arg.split('=')
96
+ o_key = o_key.strip()
97
+ o_val = o_val.strip()
98
+ except ValueError:
99
+ opts[o_arg] = True
100
+ else:
101
+ opts[o_key] = o_val
102
+ return opts
103
+
104
+
105
+ def _parse_filters(f_strs):
106
+ filters = []
107
+ if not f_strs:
108
+ return filters
109
+ for f_str in f_strs:
110
+ if ':' in f_str:
111
+ fname, fopts = f_str.split(':', 1)
112
+ filters.append((fname, _parse_options([fopts])))
113
+ else:
114
+ filters.append((f_str, {}))
115
+ return filters
116
+
117
+
118
+ def _print_help(what, name):
119
+ try:
120
+ if what == 'lexer':
121
+ cls = find_lexer_class(name)
122
+ print "Help on the %s lexer:" % cls.name
123
+ print dedent(cls.__doc__)
124
+ elif what == 'formatter':
125
+ cls = find_formatter_class(name)
126
+ print "Help on the %s formatter:" % cls.name
127
+ print dedent(cls.__doc__)
128
+ elif what == 'filter':
129
+ cls = find_filter_class(name)
130
+ print "Help on the %s filter:" % name
131
+ print dedent(cls.__doc__)
132
+ except AttributeError:
133
+ print >>sys.stderr, "%s not found!" % what
134
+
135
+
136
+ def _print_list(what):
137
+ if what == 'lexer':
138
+ print
139
+ print "Lexers:"
140
+ print "~~~~~~~"
141
+
142
+ info = []
143
+ for fullname, names, exts, _ in get_all_lexers():
144
+ tup = (', '.join(names)+':', fullname,
145
+ exts and '(filenames ' + ', '.join(exts) + ')' or '')
146
+ info.append(tup)
147
+ info.sort()
148
+ for i in info:
149
+ print ('* %s\n %s %s') % i
150
+
151
+ elif what == 'formatter':
152
+ print
153
+ print "Formatters:"
154
+ print "~~~~~~~~~~~"
155
+
156
+ info = []
157
+ for cls in get_all_formatters():
158
+ doc = docstring_headline(cls)
159
+ tup = (', '.join(cls.aliases) + ':', doc, cls.filenames and
160
+ '(filenames ' + ', '.join(cls.filenames) + ')' or '')
161
+ info.append(tup)
162
+ info.sort()
163
+ for i in info:
164
+ print ('* %s\n %s %s') % i
165
+
166
+ elif what == 'filter':
167
+ print
168
+ print "Filters:"
169
+ print "~~~~~~~~"
170
+
171
+ for name in get_all_filters():
172
+ cls = find_filter_class(name)
173
+ print "* " + name + ':'
174
+ print " %s" % docstring_headline(cls)
175
+
176
+ elif what == 'style':
177
+ print
178
+ print "Styles:"
179
+ print "~~~~~~~"
180
+
181
+ for name in get_all_styles():
182
+ cls = get_style_by_name(name)
183
+ print "* " + name + ':'
184
+ print " %s" % docstring_headline(cls)
185
+
186
+
187
+ def main(args=sys.argv):
188
+ """
189
+ Main command line entry point.
190
+ """
191
+ # pylint: disable-msg=R0911,R0912,R0915
192
+
193
+ usage = USAGE % ((args[0],) * 6)
194
+
195
+ try:
196
+ popts, args = getopt.getopt(args[1:], "l:f:F:o:O:P:LS:a:N:hVHg")
197
+ except getopt.GetoptError, err:
198
+ print >>sys.stderr, usage
199
+ return 2
200
+ opts = {}
201
+ O_opts = []
202
+ P_opts = []
203
+ F_opts = []
204
+ for opt, arg in popts:
205
+ if opt == '-O':
206
+ O_opts.append(arg)
207
+ elif opt == '-P':
208
+ P_opts.append(arg)
209
+ elif opt == '-F':
210
+ F_opts.append(arg)
211
+ opts[opt] = arg
212
+
213
+ if not opts and not args:
214
+ print usage
215
+ return 0
216
+
217
+ if opts.pop('-h', None) is not None:
218
+ print usage
219
+ return 0
220
+
221
+ if opts.pop('-V', None) is not None:
222
+ print 'Pygments version %s, (c) 2006-2008 by Georg Brandl.' % __version__
223
+ return 0
224
+
225
+ # handle ``pygmentize -L``
226
+ L_opt = opts.pop('-L', None)
227
+ if L_opt is not None:
228
+ if opts:
229
+ print >>sys.stderr, usage
230
+ return 2
231
+
232
+ # print version
233
+ main(['', '-V'])
234
+ if not args:
235
+ args = ['lexer', 'formatter', 'filter', 'style']
236
+ for arg in args:
237
+ _print_list(arg.rstrip('s'))
238
+ return 0
239
+
240
+ # handle ``pygmentize -H``
241
+ H_opt = opts.pop('-H', None)
242
+ if H_opt is not None:
243
+ if opts or len(args) != 2:
244
+ print >>sys.stderr, usage
245
+ return 2
246
+
247
+ what, name = args
248
+ if what not in ('lexer', 'formatter', 'filter'):
249
+ print >>sys.stderr, usage
250
+ return 2
251
+
252
+ _print_help(what, name)
253
+ return 0
254
+
255
+ # parse -O options
256
+ parsed_opts = _parse_options(O_opts)
257
+ opts.pop('-O', None)
258
+
259
+ # parse -P options
260
+ for p_opt in P_opts:
261
+ try:
262
+ name, value = p_opt.split('=', 1)
263
+ except ValueError:
264
+ parsed_opts[p_opt] = True
265
+ else:
266
+ parsed_opts[name] = value
267
+ opts.pop('-P', None)
268
+
269
+ # handle ``pygmentize -N``
270
+ infn = opts.pop('-N', None)
271
+ if infn is not None:
272
+ try:
273
+ lexer = get_lexer_for_filename(infn, **parsed_opts)
274
+ except ClassNotFound, err:
275
+ lexer = TextLexer()
276
+ except OptionError, err:
277
+ print >>sys.stderr, 'Error:', err
278
+ return 1
279
+
280
+ print lexer.aliases[0]
281
+ return 0
282
+
283
+ # handle ``pygmentize -S``
284
+ S_opt = opts.pop('-S', None)
285
+ a_opt = opts.pop('-a', None)
286
+ if S_opt is not None:
287
+ f_opt = opts.pop('-f', None)
288
+ if not f_opt:
289
+ print >>sys.stderr, usage
290
+ return 2
291
+ if opts or args:
292
+ print >>sys.stderr, usage
293
+ return 2
294
+
295
+ try:
296
+ parsed_opts['style'] = S_opt
297
+ fmter = get_formatter_by_name(f_opt, **parsed_opts)
298
+ except ClassNotFound, err:
299
+ print >>sys.stderr, err
300
+ return 1
301
+
302
+ arg = a_opt or ''
303
+ try:
304
+ print fmter.get_style_defs(arg)
305
+ except Exception, err:
306
+ print >>sys.stderr, 'Error:', err
307
+ return 1
308
+ return 0
309
+
310
+ # if no -S is given, -a is not allowed
311
+ if a_opt is not None:
312
+ print >>sys.stderr, usage
313
+ return 2
314
+
315
+ # parse -F options
316
+ F_opts = _parse_filters(F_opts)
317
+ opts.pop('-F', None)
318
+
319
+ # select formatter
320
+ outfn = opts.pop('-o', None)
321
+ fmter = opts.pop('-f', None)
322
+ if fmter:
323
+ try:
324
+ fmter = get_formatter_by_name(fmter, **parsed_opts)
325
+ except (OptionError, ClassNotFound), err:
326
+ print >>sys.stderr, 'Error:', err
327
+ return 1
328
+
329
+ if outfn:
330
+ if not fmter:
331
+ try:
332
+ fmter = get_formatter_for_filename(outfn, **parsed_opts)
333
+ except (OptionError, ClassNotFound), err:
334
+ print >>sys.stderr, 'Error:', err
335
+ return 1
336
+ try:
337
+ outfile = open(outfn, 'wb')
338
+ except Exception, err:
339
+ print >>sys.stderr, 'Error: cannot open outfile:', err
340
+ return 1
341
+ else:
342
+ if not fmter:
343
+ fmter = TerminalFormatter(**parsed_opts)
344
+ outfile = sys.stdout
345
+
346
+ # select lexer
347
+ lexer = opts.pop('-l', None)
348
+ if lexer:
349
+ try:
350
+ lexer = get_lexer_by_name(lexer, **parsed_opts)
351
+ except (OptionError, ClassNotFound), err:
352
+ print >>sys.stderr, 'Error:', err
353
+ return 1
354
+
355
+ if args:
356
+ if len(args) > 1:
357
+ print >>sys.stderr, usage
358
+ return 2
359
+
360
+ infn = args[0]
361
+ try:
362
+ code = open(infn, 'rb').read()
363
+ except Exception, err:
364
+ print >>sys.stderr, 'Error: cannot read infile:', err
365
+ return 1
366
+
367
+ if not lexer:
368
+ try:
369
+ lexer = get_lexer_for_filename(infn, code, **parsed_opts)
370
+ except ClassNotFound, err:
371
+ if '-g' in opts:
372
+ try:
373
+ lexer = guess_lexer(code)
374
+ except ClassNotFound:
375
+ lexer = TextLexer()
376
+ else:
377
+ print >>sys.stderr, 'Error:', err
378
+ return 1
379
+ except OptionError, err:
380
+ print >>sys.stderr, 'Error:', err
381
+ return 1
382
+
383
+ else:
384
+ if '-g' in opts:
385
+ code = sys.stdin.read()
386
+ try:
387
+ lexer = guess_lexer(code)
388
+ except ClassNotFound:
389
+ lexer = TextLexer()
390
+ elif not lexer:
391
+ print >>sys.stderr, 'Error: no lexer name given and reading ' + \
392
+ 'from stdin (try using -g or -l <lexer>)'
393
+ return 2
394
+ else:
395
+ code = sys.stdin.read()
396
+
397
+ # No encoding given? Use latin1 if output file given,
398
+ # stdin/stdout encoding otherwise.
399
+ # (This is a compromise, I'm not too happy with it...)
400
+ if 'encoding' not in parsed_opts and 'outencoding' not in parsed_opts:
401
+ if outfn:
402
+ # encoding pass-through
403
+ fmter.encoding = 'latin1'
404
+ else:
405
+ if sys.version_info < (3,):
406
+ # use terminal encoding; Python 3's terminals already do that
407
+ lexer.encoding = getattr(sys.stdin, 'encoding',
408
+ None) or 'ascii'
409
+ fmter.encoding = getattr(sys.stdout, 'encoding',
410
+ None) or 'ascii'
411
+
412
+ # ... and do it!
413
+ try:
414
+ # process filters
415
+ for fname, fopts in F_opts:
416
+ lexer.add_filter(fname, **fopts)
417
+ highlight(code, lexer, fmter, outfile)
418
+ except Exception, err:
419
+ import traceback
420
+ info = traceback.format_exception(*sys.exc_info())
421
+ msg = info[-1].strip()
422
+ if len(info) >= 3:
423
+ # extract relevant file and position info
424
+ msg += '\n (f%s)' % info[-2].split('\n')[0].strip()[1:]
425
+ print >>sys.stderr
426
+ print >>sys.stderr, '*** Error while highlighting:'
427
+ print >>sys.stderr, msg
428
+ return 1
429
+
430
+ return 0