pygments.rb-jruby 0.5.4
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.
- checksums.yaml +7 -0
- data/.gitignore +6 -0
- data/CHANGELOG.md +71 -0
- data/Gemfile +2 -0
- data/LICENSE +17 -0
- data/README.md +118 -0
- data/Rakefile +66 -0
- data/bench.rb +22 -0
- data/cache-lexers.rb +8 -0
- data/lexers +0 -0
- data/lib/pygments.rb +8 -0
- data/lib/pygments/lexer.rb +148 -0
- data/lib/pygments/mentos.py +351 -0
- data/lib/pygments/popen.rb +404 -0
- data/lib/pygments/version.rb +3 -0
- data/pygments.rb.gemspec +24 -0
- data/test/test_data.c +2581 -0
- data/test/test_data.py +514 -0
- data/test/test_data_generated +2582 -0
- data/test/test_pygments.rb +287 -0
- data/vendor/custom_lexers/github.py +565 -0
- data/vendor/pygments-main/AUTHORS +153 -0
- data/vendor/pygments-main/CHANGES +889 -0
- data/vendor/pygments-main/LICENSE +25 -0
- data/vendor/pygments-main/MANIFEST.in +6 -0
- data/vendor/pygments-main/Makefile +59 -0
- data/vendor/pygments-main/REVISION +1 -0
- data/vendor/pygments-main/TODO +15 -0
- data/vendor/pygments-main/docs/generate.py +472 -0
- data/vendor/pygments-main/docs/pygmentize.1 +94 -0
- data/vendor/pygments-main/docs/src/api.txt +270 -0
- data/vendor/pygments-main/docs/src/authors.txt +5 -0
- data/vendor/pygments-main/docs/src/changelog.txt +5 -0
- data/vendor/pygments-main/docs/src/cmdline.txt +147 -0
- data/vendor/pygments-main/docs/src/filterdevelopment.txt +70 -0
- data/vendor/pygments-main/docs/src/filters.txt +42 -0
- data/vendor/pygments-main/docs/src/formatterdevelopment.txt +169 -0
- data/vendor/pygments-main/docs/src/formatters.txt +48 -0
- data/vendor/pygments-main/docs/src/index.txt +69 -0
- data/vendor/pygments-main/docs/src/installation.txt +71 -0
- data/vendor/pygments-main/docs/src/integrate.txt +48 -0
- data/vendor/pygments-main/docs/src/java.txt +70 -0
- data/vendor/pygments-main/docs/src/lexerdevelopment.txt +603 -0
- data/vendor/pygments-main/docs/src/lexers.txt +67 -0
- data/vendor/pygments-main/docs/src/moinmoin.txt +39 -0
- data/vendor/pygments-main/docs/src/plugins.txt +93 -0
- data/vendor/pygments-main/docs/src/quickstart.txt +202 -0
- data/vendor/pygments-main/docs/src/rstdirective.txt +22 -0
- data/vendor/pygments-main/docs/src/styles.txt +143 -0
- data/vendor/pygments-main/docs/src/tokens.txt +349 -0
- data/vendor/pygments-main/docs/src/unicode.txt +49 -0
- data/vendor/pygments-main/external/autopygmentize +64 -0
- data/vendor/pygments-main/external/lasso-builtins-generator-9.lasso +144 -0
- data/vendor/pygments-main/external/markdown-processor.py +67 -0
- data/vendor/pygments-main/external/moin-parser.py +112 -0
- data/vendor/pygments-main/external/pygments.bashcomp +38 -0
- data/vendor/pygments-main/external/rst-directive-old.py +77 -0
- data/vendor/pygments-main/external/rst-directive.py +83 -0
- data/vendor/pygments-main/ez_setup.py +276 -0
- data/vendor/pygments-main/pygmentize +7 -0
- data/vendor/pygments-main/pygments/__init__.py +91 -0
- data/vendor/pygments-main/pygments/cmdline.py +441 -0
- data/vendor/pygments-main/pygments/console.py +74 -0
- data/vendor/pygments-main/pygments/filter.py +74 -0
- data/vendor/pygments-main/pygments/filters/__init__.py +356 -0
- data/vendor/pygments-main/pygments/formatter.py +95 -0
- data/vendor/pygments-main/pygments/formatters/__init__.py +68 -0
- data/vendor/pygments-main/pygments/formatters/_mapping.py +92 -0
- data/vendor/pygments-main/pygments/formatters/bbcode.py +109 -0
- data/vendor/pygments-main/pygments/formatters/html.py +821 -0
- data/vendor/pygments-main/pygments/formatters/img.py +553 -0
- data/vendor/pygments-main/pygments/formatters/latex.py +378 -0
- data/vendor/pygments-main/pygments/formatters/other.py +115 -0
- data/vendor/pygments-main/pygments/formatters/rtf.py +136 -0
- data/vendor/pygments-main/pygments/formatters/svg.py +154 -0
- data/vendor/pygments-main/pygments/formatters/terminal.py +112 -0
- data/vendor/pygments-main/pygments/formatters/terminal256.py +222 -0
- data/vendor/pygments-main/pygments/lexer.py +765 -0
- data/vendor/pygments-main/pygments/lexers/__init__.py +240 -0
- data/vendor/pygments-main/pygments/lexers/_asybuiltins.py +1645 -0
- data/vendor/pygments-main/pygments/lexers/_clbuiltins.py +232 -0
- data/vendor/pygments-main/pygments/lexers/_lassobuiltins.py +5172 -0
- data/vendor/pygments-main/pygments/lexers/_luabuiltins.py +249 -0
- data/vendor/pygments-main/pygments/lexers/_mapping.py +354 -0
- data/vendor/pygments-main/pygments/lexers/_openedgebuiltins.py +562 -0
- data/vendor/pygments-main/pygments/lexers/_phpbuiltins.py +3787 -0
- data/vendor/pygments-main/pygments/lexers/_postgres_builtins.py +233 -0
- data/vendor/pygments-main/pygments/lexers/_robotframeworklexer.py +557 -0
- data/vendor/pygments-main/pygments/lexers/_scilab_builtins.py +40 -0
- data/vendor/pygments-main/pygments/lexers/_sourcemodbuiltins.py +1072 -0
- data/vendor/pygments-main/pygments/lexers/_stan_builtins.py +360 -0
- data/vendor/pygments-main/pygments/lexers/_vimbuiltins.py +13 -0
- data/vendor/pygments-main/pygments/lexers/agile.py +2290 -0
- data/vendor/pygments-main/pygments/lexers/asm.py +398 -0
- data/vendor/pygments-main/pygments/lexers/compiled.py +3723 -0
- data/vendor/pygments-main/pygments/lexers/dalvik.py +104 -0
- data/vendor/pygments-main/pygments/lexers/dotnet.py +671 -0
- data/vendor/pygments-main/pygments/lexers/foxpro.py +428 -0
- data/vendor/pygments-main/pygments/lexers/functional.py +2731 -0
- data/vendor/pygments-main/pygments/lexers/github.py +565 -0
- data/vendor/pygments-main/pygments/lexers/hdl.py +356 -0
- data/vendor/pygments-main/pygments/lexers/jvm.py +1112 -0
- data/vendor/pygments-main/pygments/lexers/math.py +1918 -0
- data/vendor/pygments-main/pygments/lexers/other.py +3778 -0
- data/vendor/pygments-main/pygments/lexers/parsers.py +778 -0
- data/vendor/pygments-main/pygments/lexers/shell.py +424 -0
- data/vendor/pygments-main/pygments/lexers/special.py +100 -0
- data/vendor/pygments-main/pygments/lexers/sql.py +559 -0
- data/vendor/pygments-main/pygments/lexers/templates.py +1742 -0
- data/vendor/pygments-main/pygments/lexers/text.py +1893 -0
- data/vendor/pygments-main/pygments/lexers/web.py +4045 -0
- data/vendor/pygments-main/pygments/modeline.py +40 -0
- data/vendor/pygments-main/pygments/plugin.py +74 -0
- data/vendor/pygments-main/pygments/scanner.py +104 -0
- data/vendor/pygments-main/pygments/style.py +117 -0
- data/vendor/pygments-main/pygments/styles/__init__.py +70 -0
- data/vendor/pygments-main/pygments/styles/autumn.py +65 -0
- data/vendor/pygments-main/pygments/styles/borland.py +51 -0
- data/vendor/pygments-main/pygments/styles/bw.py +49 -0
- data/vendor/pygments-main/pygments/styles/colorful.py +81 -0
- data/vendor/pygments-main/pygments/styles/default.py +73 -0
- data/vendor/pygments-main/pygments/styles/emacs.py +72 -0
- data/vendor/pygments-main/pygments/styles/friendly.py +72 -0
- data/vendor/pygments-main/pygments/styles/fruity.py +42 -0
- data/vendor/pygments-main/pygments/styles/manni.py +75 -0
- data/vendor/pygments-main/pygments/styles/monokai.py +106 -0
- data/vendor/pygments-main/pygments/styles/murphy.py +80 -0
- data/vendor/pygments-main/pygments/styles/native.py +65 -0
- data/vendor/pygments-main/pygments/styles/pastie.py +75 -0
- data/vendor/pygments-main/pygments/styles/perldoc.py +69 -0
- data/vendor/pygments-main/pygments/styles/rrt.py +33 -0
- data/vendor/pygments-main/pygments/styles/tango.py +141 -0
- data/vendor/pygments-main/pygments/styles/trac.py +63 -0
- data/vendor/pygments-main/pygments/styles/vim.py +63 -0
- data/vendor/pygments-main/pygments/styles/vs.py +38 -0
- data/vendor/pygments-main/pygments/token.py +195 -0
- data/vendor/pygments-main/pygments/unistring.py +140 -0
- data/vendor/pygments-main/pygments/util.py +277 -0
- data/vendor/pygments-main/scripts/check_sources.py +242 -0
- data/vendor/pygments-main/scripts/detect_missing_analyse_text.py +32 -0
- data/vendor/pygments-main/scripts/epydoc.css +280 -0
- data/vendor/pygments-main/scripts/find_codetags.py +205 -0
- data/vendor/pygments-main/scripts/find_error.py +170 -0
- data/vendor/pygments-main/scripts/get_vimkw.py +43 -0
- data/vendor/pygments-main/scripts/pylintrc +301 -0
- data/vendor/pygments-main/scripts/reindent.py +291 -0
- data/vendor/pygments-main/scripts/vim2pygments.py +933 -0
- data/vendor/pygments-main/setup.cfg +7 -0
- data/vendor/pygments-main/setup.py +90 -0
- data/vendor/pygments-main/tests/dtds/HTML4-f.dtd +37 -0
- data/vendor/pygments-main/tests/dtds/HTML4-s.dtd +869 -0
- data/vendor/pygments-main/tests/dtds/HTML4.dcl +88 -0
- data/vendor/pygments-main/tests/dtds/HTML4.dtd +1092 -0
- data/vendor/pygments-main/tests/dtds/HTML4.soc +9 -0
- data/vendor/pygments-main/tests/dtds/HTMLlat1.ent +195 -0
- data/vendor/pygments-main/tests/dtds/HTMLspec.ent +77 -0
- data/vendor/pygments-main/tests/dtds/HTMLsym.ent +241 -0
- data/vendor/pygments-main/tests/examplefiles/ANTLRv3.g +608 -0
- data/vendor/pygments-main/tests/examplefiles/AcidStateAdvanced.hs +209 -0
- data/vendor/pygments-main/tests/examplefiles/AlternatingGroup.mu +102 -0
- data/vendor/pygments-main/tests/examplefiles/BOM.js +1 -0
- data/vendor/pygments-main/tests/examplefiles/CPDictionary.j +611 -0
- data/vendor/pygments-main/tests/examplefiles/Config.in.cache +1973 -0
- data/vendor/pygments-main/tests/examplefiles/Constants.mo +158 -0
- data/vendor/pygments-main/tests/examplefiles/DancingSudoku.lhs +411 -0
- data/vendor/pygments-main/tests/examplefiles/Deflate.fs +578 -0
- data/vendor/pygments-main/tests/examplefiles/Errors.scala +18 -0
- data/vendor/pygments-main/tests/examplefiles/File.hy +174 -0
- data/vendor/pygments-main/tests/examplefiles/Get-CommandDefinitionHtml.ps1 +66 -0
- data/vendor/pygments-main/tests/examplefiles/IPDispatchC.nc +104 -0
- data/vendor/pygments-main/tests/examplefiles/IPDispatchP.nc +671 -0
- data/vendor/pygments-main/tests/examplefiles/Intro.java +1660 -0
- data/vendor/pygments-main/tests/examplefiles/Makefile +1131 -0
- data/vendor/pygments-main/tests/examplefiles/Object.st +4394 -0
- data/vendor/pygments-main/tests/examplefiles/OrderedMap.hx +584 -0
- data/vendor/pygments-main/tests/examplefiles/RoleQ.pm6 +23 -0
- data/vendor/pygments-main/tests/examplefiles/SmallCheck.hs +378 -0
- data/vendor/pygments-main/tests/examplefiles/Sorting.mod +470 -0
- data/vendor/pygments-main/tests/examplefiles/Sudoku.lhs +382 -0
- data/vendor/pygments-main/tests/examplefiles/addressbook.proto +30 -0
- data/vendor/pygments-main/tests/examplefiles/antlr_throws +1 -0
- data/vendor/pygments-main/tests/examplefiles/apache2.conf +393 -0
- data/vendor/pygments-main/tests/examplefiles/as3_test.as +143 -0
- data/vendor/pygments-main/tests/examplefiles/as3_test2.as +46 -0
- data/vendor/pygments-main/tests/examplefiles/as3_test3.as +3 -0
- data/vendor/pygments-main/tests/examplefiles/aspx-cs_example +27 -0
- data/vendor/pygments-main/tests/examplefiles/autoit_submit.au3 +25 -0
- data/vendor/pygments-main/tests/examplefiles/badcase.java +2 -0
- data/vendor/pygments-main/tests/examplefiles/batchfile.bat +49 -0
- data/vendor/pygments-main/tests/examplefiles/bigtest.nsi +308 -0
- data/vendor/pygments-main/tests/examplefiles/boot-9.scm +1557 -0
- data/vendor/pygments-main/tests/examplefiles/ca65_example +284 -0
- data/vendor/pygments-main/tests/examplefiles/cbmbas_example +9 -0
- data/vendor/pygments-main/tests/examplefiles/cells.ps +515 -0
- data/vendor/pygments-main/tests/examplefiles/ceval.c +2604 -0
- data/vendor/pygments-main/tests/examplefiles/cheetah_example.html +13 -0
- data/vendor/pygments-main/tests/examplefiles/classes.dylan +125 -0
- data/vendor/pygments-main/tests/examplefiles/condensed_ruby.rb +10 -0
- data/vendor/pygments-main/tests/examplefiles/coq_RelationClasses +447 -0
- data/vendor/pygments-main/tests/examplefiles/database.pytb +20 -0
- data/vendor/pygments-main/tests/examplefiles/de.MoinMoin.po +2461 -0
- data/vendor/pygments-main/tests/examplefiles/demo.ahk +181 -0
- data/vendor/pygments-main/tests/examplefiles/demo.cfm +38 -0
- data/vendor/pygments-main/tests/examplefiles/django_sample.html+django +68 -0
- data/vendor/pygments-main/tests/examplefiles/dwarf.cw +17 -0
- data/vendor/pygments-main/tests/examplefiles/erl_session +10 -0
- data/vendor/pygments-main/tests/examplefiles/escape_semicolon.clj +1 -0
- data/vendor/pygments-main/tests/examplefiles/evil_regex.js +48 -0
- data/vendor/pygments-main/tests/examplefiles/example.Rd +78 -0
- data/vendor/pygments-main/tests/examplefiles/example.bug +54 -0
- data/vendor/pygments-main/tests/examplefiles/example.c +2080 -0
- data/vendor/pygments-main/tests/examplefiles/example.ceylon +52 -0
- data/vendor/pygments-main/tests/examplefiles/example.clay +33 -0
- data/vendor/pygments-main/tests/examplefiles/example.cls +15 -0
- data/vendor/pygments-main/tests/examplefiles/example.cob +3556 -0
- data/vendor/pygments-main/tests/examplefiles/example.cpp +2363 -0
- data/vendor/pygments-main/tests/examplefiles/example.gs +106 -0
- data/vendor/pygments-main/tests/examplefiles/example.gst +7 -0
- data/vendor/pygments-main/tests/examplefiles/example.hx +142 -0
- data/vendor/pygments-main/tests/examplefiles/example.jag +48 -0
- data/vendor/pygments-main/tests/examplefiles/example.kt +47 -0
- data/vendor/pygments-main/tests/examplefiles/example.lagda +19 -0
- data/vendor/pygments-main/tests/examplefiles/example.lua +250 -0
- data/vendor/pygments-main/tests/examplefiles/example.monkey +152 -0
- data/vendor/pygments-main/tests/examplefiles/example.moo +26 -0
- data/vendor/pygments-main/tests/examplefiles/example.moon +629 -0
- data/vendor/pygments-main/tests/examplefiles/example.msc +43 -0
- data/vendor/pygments-main/tests/examplefiles/example.nim +1010 -0
- data/vendor/pygments-main/tests/examplefiles/example.ns2 +69 -0
- data/vendor/pygments-main/tests/examplefiles/example.p +34 -0
- data/vendor/pygments-main/tests/examplefiles/example.pas +2708 -0
- data/vendor/pygments-main/tests/examplefiles/example.prg +161 -0
- data/vendor/pygments-main/tests/examplefiles/example.rb +1852 -0
- data/vendor/pygments-main/tests/examplefiles/example.reg +19 -0
- data/vendor/pygments-main/tests/examplefiles/example.rexx +50 -0
- data/vendor/pygments-main/tests/examplefiles/example.rhtml +561 -0
- data/vendor/pygments-main/tests/examplefiles/example.rkt +95 -0
- data/vendor/pygments-main/tests/examplefiles/example.rpf +4 -0
- data/vendor/pygments-main/tests/examplefiles/example.sh-session +19 -0
- data/vendor/pygments-main/tests/examplefiles/example.shell-session +45 -0
- data/vendor/pygments-main/tests/examplefiles/example.sml +156 -0
- data/vendor/pygments-main/tests/examplefiles/example.snobol +15 -0
- data/vendor/pygments-main/tests/examplefiles/example.stan +108 -0
- data/vendor/pygments-main/tests/examplefiles/example.tea +34 -0
- data/vendor/pygments-main/tests/examplefiles/example.ts +28 -0
- data/vendor/pygments-main/tests/examplefiles/example.u +548 -0
- data/vendor/pygments-main/tests/examplefiles/example.weechatlog +9 -0
- data/vendor/pygments-main/tests/examplefiles/example.xhtml +376 -0
- data/vendor/pygments-main/tests/examplefiles/example.xtend +34 -0
- data/vendor/pygments-main/tests/examplefiles/example.yaml +302 -0
- data/vendor/pygments-main/tests/examplefiles/example2.aspx +29 -0
- data/vendor/pygments-main/tests/examplefiles/example2.msc +79 -0
- data/vendor/pygments-main/tests/examplefiles/example_elixir.ex +363 -0
- data/vendor/pygments-main/tests/examplefiles/example_file.fy +128 -0
- data/vendor/pygments-main/tests/examplefiles/firefox.mak +586 -0
- data/vendor/pygments-main/tests/examplefiles/flipflop.sv +19 -0
- data/vendor/pygments-main/tests/examplefiles/foo.sce +6 -0
- data/vendor/pygments-main/tests/examplefiles/format.ml +1213 -0
- data/vendor/pygments-main/tests/examplefiles/fucked_up.rb +77 -0
- data/vendor/pygments-main/tests/examplefiles/function.mu +1 -0
- data/vendor/pygments-main/tests/examplefiles/functional.rst +1472 -0
- data/vendor/pygments-main/tests/examplefiles/garcia-wachs.kk +133 -0
- data/vendor/pygments-main/tests/examplefiles/genclass.clj +510 -0
- data/vendor/pygments-main/tests/examplefiles/genshi_example.xml+genshi +193 -0
- data/vendor/pygments-main/tests/examplefiles/genshitext_example.genshitext +33 -0
- data/vendor/pygments-main/tests/examplefiles/glsl.frag +7 -0
- data/vendor/pygments-main/tests/examplefiles/glsl.vert +13 -0
- data/vendor/pygments-main/tests/examplefiles/grammar-test.p6 +22 -0
- data/vendor/pygments-main/tests/examplefiles/hello.smali +40 -0
- data/vendor/pygments-main/tests/examplefiles/hello.sp +9 -0
- data/vendor/pygments-main/tests/examplefiles/html+php_faulty.php +1 -0
- data/vendor/pygments-main/tests/examplefiles/http_request_example +15 -0
- data/vendor/pygments-main/tests/examplefiles/http_response_example +29 -0
- data/vendor/pygments-main/tests/examplefiles/import.hs +4 -0
- data/vendor/pygments-main/tests/examplefiles/inet_pton6.dg +71 -0
- data/vendor/pygments-main/tests/examplefiles/intro.ik +24 -0
- data/vendor/pygments-main/tests/examplefiles/ints.php +10 -0
- data/vendor/pygments-main/tests/examplefiles/intsyn.fun +675 -0
- data/vendor/pygments-main/tests/examplefiles/intsyn.sig +286 -0
- data/vendor/pygments-main/tests/examplefiles/irb_heredoc +8 -0
- data/vendor/pygments-main/tests/examplefiles/irc.lsp +214 -0
- data/vendor/pygments-main/tests/examplefiles/java.properties +16 -0
- data/vendor/pygments-main/tests/examplefiles/jbst_example1.jbst +28 -0
- data/vendor/pygments-main/tests/examplefiles/jbst_example2.jbst +45 -0
- data/vendor/pygments-main/tests/examplefiles/jinjadesignerdoc.rst +713 -0
- data/vendor/pygments-main/tests/examplefiles/json.lasso +301 -0
- data/vendor/pygments-main/tests/examplefiles/json.lasso9 +213 -0
- data/vendor/pygments-main/tests/examplefiles/lighttpd_config.conf +13 -0
- data/vendor/pygments-main/tests/examplefiles/linecontinuation.py +47 -0
- data/vendor/pygments-main/tests/examplefiles/livescript-demo.ls +41 -0
- data/vendor/pygments-main/tests/examplefiles/logos_example.xm +28 -0
- data/vendor/pygments-main/tests/examplefiles/ltmain.sh +2849 -0
- data/vendor/pygments-main/tests/examplefiles/main.cmake +42 -0
- data/vendor/pygments-main/tests/examplefiles/markdown.lsp +679 -0
- data/vendor/pygments-main/tests/examplefiles/matlab_noreturn +3 -0
- data/vendor/pygments-main/tests/examplefiles/matlab_sample +30 -0
- data/vendor/pygments-main/tests/examplefiles/matlabsession_sample.txt +37 -0
- data/vendor/pygments-main/tests/examplefiles/metagrammar.treetop +455 -0
- data/vendor/pygments-main/tests/examplefiles/mg_sample.pro +73 -0
- data/vendor/pygments-main/tests/examplefiles/minehunt.qml +112 -0
- data/vendor/pygments-main/tests/examplefiles/minimal.ns2 +4 -0
- data/vendor/pygments-main/tests/examplefiles/moin_SyntaxReference.txt +340 -0
- data/vendor/pygments-main/tests/examplefiles/multiline_regexes.rb +38 -0
- data/vendor/pygments-main/tests/examplefiles/nanomsg.intr +95 -0
- data/vendor/pygments-main/tests/examplefiles/nasm_aoutso.asm +96 -0
- data/vendor/pygments-main/tests/examplefiles/nasm_objexe.asm +30 -0
- data/vendor/pygments-main/tests/examplefiles/nemerle_sample.n +87 -0
- data/vendor/pygments-main/tests/examplefiles/nginx_nginx.conf +118 -0
- data/vendor/pygments-main/tests/examplefiles/numbers.c +12 -0
- data/vendor/pygments-main/tests/examplefiles/objc_example.m +32 -0
- data/vendor/pygments-main/tests/examplefiles/objc_example2.m +24 -0
- data/vendor/pygments-main/tests/examplefiles/perl_misc +62 -0
- data/vendor/pygments-main/tests/examplefiles/perl_perl5db +998 -0
- data/vendor/pygments-main/tests/examplefiles/perl_regex-delims +120 -0
- data/vendor/pygments-main/tests/examplefiles/perlfunc.1 +856 -0
- data/vendor/pygments-main/tests/examplefiles/phpMyAdmin.spec +163 -0
- data/vendor/pygments-main/tests/examplefiles/phpcomplete.vim +567 -0
- data/vendor/pygments-main/tests/examplefiles/pleac.in.rb +1223 -0
- data/vendor/pygments-main/tests/examplefiles/postgresql_test.txt +47 -0
- data/vendor/pygments-main/tests/examplefiles/pppoe.applescript +10 -0
- data/vendor/pygments-main/tests/examplefiles/psql_session.txt +122 -0
- data/vendor/pygments-main/tests/examplefiles/py3_test.txt +2 -0
- data/vendor/pygments-main/tests/examplefiles/py3tb_test.py3tb +4 -0
- data/vendor/pygments-main/tests/examplefiles/pycon_test.pycon +14 -0
- data/vendor/pygments-main/tests/examplefiles/pytb_test2.pytb +2 -0
- data/vendor/pygments-main/tests/examplefiles/pytb_test3.pytb +4 -0
- data/vendor/pygments-main/tests/examplefiles/python25-bsd.mak +234 -0
- data/vendor/pygments-main/tests/examplefiles/qsort.prolog +13 -0
- data/vendor/pygments-main/tests/examplefiles/r-console-transcript.Rout +38 -0
- data/vendor/pygments-main/tests/examplefiles/ragel-cpp_rlscan +280 -0
- data/vendor/pygments-main/tests/examplefiles/ragel-cpp_snippet +2 -0
- data/vendor/pygments-main/tests/examplefiles/regex.js +22 -0
- data/vendor/pygments-main/tests/examplefiles/reversi.lsp +427 -0
- data/vendor/pygments-main/tests/examplefiles/robotframework.txt +39 -0
- data/vendor/pygments-main/tests/examplefiles/ruby_func_def.rb +11 -0
- data/vendor/pygments-main/tests/examplefiles/rust_example.rs +233 -0
- data/vendor/pygments-main/tests/examplefiles/scilab.sci +30 -0
- data/vendor/pygments-main/tests/examplefiles/session.dylan-console +9 -0
- data/vendor/pygments-main/tests/examplefiles/sibling.prolog +19 -0
- data/vendor/pygments-main/tests/examplefiles/simple.md +747 -0
- data/vendor/pygments-main/tests/examplefiles/smarty_example.html +209 -0
- data/vendor/pygments-main/tests/examplefiles/source.lgt +343 -0
- data/vendor/pygments-main/tests/examplefiles/sources.list +62 -0
- data/vendor/pygments-main/tests/examplefiles/sphere.pov +18 -0
- data/vendor/pygments-main/tests/examplefiles/sqlite3.sqlite3-console +27 -0
- data/vendor/pygments-main/tests/examplefiles/squid.conf +30 -0
- data/vendor/pygments-main/tests/examplefiles/string.jl +1031 -0
- data/vendor/pygments-main/tests/examplefiles/string_delimiters.d +21 -0
- data/vendor/pygments-main/tests/examplefiles/stripheredoc.sh +3 -0
- data/vendor/pygments-main/tests/examplefiles/swig_java.swg +1329 -0
- data/vendor/pygments-main/tests/examplefiles/swig_std_vector.i +225 -0
- data/vendor/pygments-main/tests/examplefiles/test.R +153 -0
- data/vendor/pygments-main/tests/examplefiles/test.adb +211 -0
- data/vendor/pygments-main/tests/examplefiles/test.agda +102 -0
- data/vendor/pygments-main/tests/examplefiles/test.asy +131 -0
- data/vendor/pygments-main/tests/examplefiles/test.awk +121 -0
- data/vendor/pygments-main/tests/examplefiles/test.bas +29 -0
- data/vendor/pygments-main/tests/examplefiles/test.bb +95 -0
- data/vendor/pygments-main/tests/examplefiles/test.bmx +145 -0
- data/vendor/pygments-main/tests/examplefiles/test.boo +39 -0
- data/vendor/pygments-main/tests/examplefiles/test.bro +250 -0
- data/vendor/pygments-main/tests/examplefiles/test.cs +374 -0
- data/vendor/pygments-main/tests/examplefiles/test.css +54 -0
- data/vendor/pygments-main/tests/examplefiles/test.cu +36 -0
- data/vendor/pygments-main/tests/examplefiles/test.d +135 -0
- data/vendor/pygments-main/tests/examplefiles/test.dart +23 -0
- data/vendor/pygments-main/tests/examplefiles/test.dtd +89 -0
- data/vendor/pygments-main/tests/examplefiles/test.ebnf +31 -0
- data/vendor/pygments-main/tests/examplefiles/test.ec +605 -0
- data/vendor/pygments-main/tests/examplefiles/test.ecl +58 -0
- data/vendor/pygments-main/tests/examplefiles/test.eh +315 -0
- data/vendor/pygments-main/tests/examplefiles/test.erl +169 -0
- data/vendor/pygments-main/tests/examplefiles/test.evoque +33 -0
- data/vendor/pygments-main/tests/examplefiles/test.fan +818 -0
- data/vendor/pygments-main/tests/examplefiles/test.flx +57 -0
- data/vendor/pygments-main/tests/examplefiles/test.gdc +13 -0
- data/vendor/pygments-main/tests/examplefiles/test.groovy +97 -0
- data/vendor/pygments-main/tests/examplefiles/test.html +339 -0
- data/vendor/pygments-main/tests/examplefiles/test.ini +10 -0
- data/vendor/pygments-main/tests/examplefiles/test.java +653 -0
- data/vendor/pygments-main/tests/examplefiles/test.jsp +24 -0
- data/vendor/pygments-main/tests/examplefiles/test.maql +45 -0
- data/vendor/pygments-main/tests/examplefiles/test.mod +374 -0
- data/vendor/pygments-main/tests/examplefiles/test.moo +51 -0
- data/vendor/pygments-main/tests/examplefiles/test.myt +166 -0
- data/vendor/pygments-main/tests/examplefiles/test.nim +93 -0
- data/vendor/pygments-main/tests/examplefiles/test.opa +10 -0
- data/vendor/pygments-main/tests/examplefiles/test.p6 +252 -0
- data/vendor/pygments-main/tests/examplefiles/test.pas +743 -0
- data/vendor/pygments-main/tests/examplefiles/test.php +505 -0
- data/vendor/pygments-main/tests/examplefiles/test.plot +333 -0
- data/vendor/pygments-main/tests/examplefiles/test.ps1 +108 -0
- data/vendor/pygments-main/tests/examplefiles/test.pypylog +1839 -0
- data/vendor/pygments-main/tests/examplefiles/test.r3 +94 -0
- data/vendor/pygments-main/tests/examplefiles/test.rb +177 -0
- data/vendor/pygments-main/tests/examplefiles/test.rhtml +43 -0
- data/vendor/pygments-main/tests/examplefiles/test.scaml +8 -0
- data/vendor/pygments-main/tests/examplefiles/test.ssp +12 -0
- data/vendor/pygments-main/tests/examplefiles/test.tcsh +830 -0
- data/vendor/pygments-main/tests/examplefiles/test.vb +407 -0
- data/vendor/pygments-main/tests/examplefiles/test.vhdl +161 -0
- data/vendor/pygments-main/tests/examplefiles/test.xqy +138 -0
- data/vendor/pygments-main/tests/examplefiles/test.xsl +23 -0
- data/vendor/pygments-main/tests/examplefiles/test2.pypylog +120 -0
- data/vendor/pygments-main/tests/examplefiles/truncated.pytb +15 -0
- data/vendor/pygments-main/tests/examplefiles/type.lisp +1218 -0
- data/vendor/pygments-main/tests/examplefiles/underscore.coffee +603 -0
- data/vendor/pygments-main/tests/examplefiles/unicode.applescript +5 -0
- data/vendor/pygments-main/tests/examplefiles/unicodedoc.py +11 -0
- data/vendor/pygments-main/tests/examplefiles/unix-io.lid +37 -0
- data/vendor/pygments-main/tests/examplefiles/webkit-transition.css +3 -0
- data/vendor/pygments-main/tests/examplefiles/while.pov +13 -0
- data/vendor/pygments-main/tests/examplefiles/wiki.factor +384 -0
- data/vendor/pygments-main/tests/examplefiles/xml_example +1897 -0
- data/vendor/pygments-main/tests/examplefiles/zmlrpc.f90 +798 -0
- data/vendor/pygments-main/tests/old_run.py +138 -0
- data/vendor/pygments-main/tests/run.py +49 -0
- data/vendor/pygments-main/tests/support.py +15 -0
- data/vendor/pygments-main/tests/support/tags +36 -0
- data/vendor/pygments-main/tests/test_basic_api.py +295 -0
- data/vendor/pygments-main/tests/test_clexer.py +31 -0
- data/vendor/pygments-main/tests/test_cmdline.py +105 -0
- data/vendor/pygments-main/tests/test_examplefiles.py +99 -0
- data/vendor/pygments-main/tests/test_html_formatter.py +178 -0
- data/vendor/pygments-main/tests/test_latex_formatter.py +55 -0
- data/vendor/pygments-main/tests/test_lexers_other.py +68 -0
- data/vendor/pygments-main/tests/test_perllexer.py +137 -0
- data/vendor/pygments-main/tests/test_regexlexer.py +47 -0
- data/vendor/pygments-main/tests/test_token.py +46 -0
- data/vendor/pygments-main/tests/test_using_api.py +40 -0
- data/vendor/pygments-main/tests/test_util.py +135 -0
- data/vendor/simplejson/.gitignore +10 -0
- data/vendor/simplejson/.travis.yml +5 -0
- data/vendor/simplejson/CHANGES.txt +291 -0
- data/vendor/simplejson/LICENSE.txt +19 -0
- data/vendor/simplejson/MANIFEST.in +5 -0
- data/vendor/simplejson/README.rst +19 -0
- data/vendor/simplejson/conf.py +179 -0
- data/vendor/simplejson/index.rst +628 -0
- data/vendor/simplejson/scripts/make_docs.py +18 -0
- data/vendor/simplejson/setup.py +104 -0
- data/vendor/simplejson/simplejson/__init__.py +510 -0
- data/vendor/simplejson/simplejson/_speedups.c +2745 -0
- data/vendor/simplejson/simplejson/decoder.py +425 -0
- data/vendor/simplejson/simplejson/encoder.py +567 -0
- data/vendor/simplejson/simplejson/ordered_dict.py +119 -0
- data/vendor/simplejson/simplejson/scanner.py +77 -0
- data/vendor/simplejson/simplejson/tests/__init__.py +67 -0
- data/vendor/simplejson/simplejson/tests/test_bigint_as_string.py +55 -0
- data/vendor/simplejson/simplejson/tests/test_check_circular.py +30 -0
- data/vendor/simplejson/simplejson/tests/test_decimal.py +66 -0
- data/vendor/simplejson/simplejson/tests/test_decode.py +83 -0
- data/vendor/simplejson/simplejson/tests/test_default.py +9 -0
- data/vendor/simplejson/simplejson/tests/test_dump.py +67 -0
- data/vendor/simplejson/simplejson/tests/test_encode_basestring_ascii.py +46 -0
- data/vendor/simplejson/simplejson/tests/test_encode_for_html.py +32 -0
- data/vendor/simplejson/simplejson/tests/test_errors.py +34 -0
- data/vendor/simplejson/simplejson/tests/test_fail.py +91 -0
- data/vendor/simplejson/simplejson/tests/test_float.py +19 -0
- data/vendor/simplejson/simplejson/tests/test_indent.py +86 -0
- data/vendor/simplejson/simplejson/tests/test_item_sort_key.py +20 -0
- data/vendor/simplejson/simplejson/tests/test_namedtuple.py +121 -0
- data/vendor/simplejson/simplejson/tests/test_pass1.py +76 -0
- data/vendor/simplejson/simplejson/tests/test_pass2.py +14 -0
- data/vendor/simplejson/simplejson/tests/test_pass3.py +20 -0
- data/vendor/simplejson/simplejson/tests/test_recursion.py +67 -0
- data/vendor/simplejson/simplejson/tests/test_scanstring.py +117 -0
- data/vendor/simplejson/simplejson/tests/test_separators.py +42 -0
- data/vendor/simplejson/simplejson/tests/test_speedups.py +20 -0
- data/vendor/simplejson/simplejson/tests/test_tuple.py +49 -0
- data/vendor/simplejson/simplejson/tests/test_unicode.py +109 -0
- data/vendor/simplejson/simplejson/tool.py +39 -0
- metadata +557 -0
@@ -0,0 +1,351 @@
|
|
1
|
+
#!/usr/bin/env python
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
|
4
|
+
import sys, re, os, signal
|
5
|
+
import traceback
|
6
|
+
if 'PYGMENTS_PATH' in os.environ:
|
7
|
+
sys.path.insert(0, os.environ['PYGMENTS_PATH'])
|
8
|
+
|
9
|
+
dirname = os.path.dirname
|
10
|
+
|
11
|
+
base_dir = dirname(dirname(dirname(os.path.abspath(__file__))))
|
12
|
+
sys.path.append(base_dir + "/vendor")
|
13
|
+
sys.path.append(base_dir + "/vendor/pygments-main")
|
14
|
+
sys.path.append(base_dir + "/vendor/simplejson")
|
15
|
+
|
16
|
+
import pygments
|
17
|
+
from pygments import lexers, formatters, styles, filters
|
18
|
+
|
19
|
+
from threading import Lock
|
20
|
+
|
21
|
+
try:
|
22
|
+
import json
|
23
|
+
except ImportError:
|
24
|
+
import simplejson as json
|
25
|
+
|
26
|
+
def _convert_keys(dictionary):
|
27
|
+
if not isinstance(dictionary, dict):
|
28
|
+
return dictionary
|
29
|
+
return dict((str(k), _convert_keys(v))
|
30
|
+
for k, v in dictionary.items())
|
31
|
+
|
32
|
+
def _write_error(error):
|
33
|
+
res = {"error": error}
|
34
|
+
out_header = json.dumps(res).encode('utf-8')
|
35
|
+
bits = _get_fixed_bits_from_header(out_header)
|
36
|
+
sys.stdout.write(bits + "\n")
|
37
|
+
sys.stdout.flush()
|
38
|
+
sys.stdout.write(out_header + "\n")
|
39
|
+
sys.stdout.flush()
|
40
|
+
return
|
41
|
+
|
42
|
+
def _get_fixed_bits_from_header(out_header):
|
43
|
+
size = len(out_header)
|
44
|
+
return "".join(map(lambda y:str((size>>y)&1), range(32-1, -1, -1)))
|
45
|
+
|
46
|
+
def _signal_handler(signal, frame):
|
47
|
+
"""
|
48
|
+
Handle the signal given in the first argument, exiting gracefully
|
49
|
+
"""
|
50
|
+
sys.exit(0)
|
51
|
+
|
52
|
+
class Mentos(object):
|
53
|
+
"""
|
54
|
+
Interacts with pygments.rb to provide access to pygments functionality
|
55
|
+
"""
|
56
|
+
def __init__(self):
|
57
|
+
pass
|
58
|
+
|
59
|
+
def return_lexer(self, lexer, args, inputs, code=None):
|
60
|
+
"""
|
61
|
+
Accepting a variety of possible inputs, return a Lexer object.
|
62
|
+
|
63
|
+
The inputs argument should be a hash with at least one of the following
|
64
|
+
keys:
|
65
|
+
|
66
|
+
- 'lexer' ("python")
|
67
|
+
- 'mimetype' ("text/x-ruby")
|
68
|
+
- 'filename' ("yeaaah.py")
|
69
|
+
|
70
|
+
The code argument should be a string, such as "import derp".
|
71
|
+
|
72
|
+
The code guessing method is not especially great. It is advised that
|
73
|
+
clients pass in a literal lexer name whenever possible, which provides
|
74
|
+
the best probability of match (100 percent).
|
75
|
+
"""
|
76
|
+
|
77
|
+
if lexer:
|
78
|
+
if inputs:
|
79
|
+
return lexers.get_lexer_by_name(lexer, **inputs)
|
80
|
+
else:
|
81
|
+
return lexers.get_lexer_by_name(lexer)
|
82
|
+
|
83
|
+
if inputs:
|
84
|
+
if 'lexer' in inputs:
|
85
|
+
return lexers.get_lexer_by_name(inputs['lexer'], **inputs)
|
86
|
+
|
87
|
+
elif 'mimetype' in inputs:
|
88
|
+
return lexers.get_lexer_for_mimetype(inputs['mimetype'], **inputs)
|
89
|
+
|
90
|
+
elif 'filename' in inputs:
|
91
|
+
name = inputs['filename']
|
92
|
+
|
93
|
+
# If we have code and a filename, pygments allows us to guess
|
94
|
+
# with both. This is better than just guessing with code.
|
95
|
+
if code:
|
96
|
+
return lexers.guess_lexer_for_filename(name, code, **inputs)
|
97
|
+
else:
|
98
|
+
return lexers.get_lexer_for_filename(name, **inputs)
|
99
|
+
|
100
|
+
# If all we got is code, try anyway.
|
101
|
+
if code:
|
102
|
+
return lexers.guess_lexer(code, **inputs)
|
103
|
+
|
104
|
+
else:
|
105
|
+
return None
|
106
|
+
|
107
|
+
|
108
|
+
def highlight_text(self, code, lexer, formatter_name, args, kwargs):
|
109
|
+
"""
|
110
|
+
Highlight the relevant code, and return a result string.
|
111
|
+
The default formatter is html, but alternate formatters can be passed in via
|
112
|
+
the formatter_name argument. Additional paramters can be passed as args
|
113
|
+
or kwargs.
|
114
|
+
"""
|
115
|
+
# Default to html if we don't have the formatter name.
|
116
|
+
if formatter_name:
|
117
|
+
_format_name = str(formatter_name)
|
118
|
+
else:
|
119
|
+
_format_name = "html"
|
120
|
+
|
121
|
+
# Return a lexer object
|
122
|
+
lexer = self.return_lexer(lexer, args, kwargs, code)
|
123
|
+
|
124
|
+
# Make sure we sucessfuly got a lexer
|
125
|
+
if lexer:
|
126
|
+
formatter = pygments.formatters.get_formatter_by_name(str.lower(_format_name), **kwargs)
|
127
|
+
|
128
|
+
# Do the damn thing.
|
129
|
+
res = pygments.highlight(code, lexer, formatter)
|
130
|
+
|
131
|
+
return res
|
132
|
+
|
133
|
+
else:
|
134
|
+
_write_error("No lexer")
|
135
|
+
|
136
|
+
def get_data(self, method, lexer, args, kwargs, text=None):
|
137
|
+
"""
|
138
|
+
Based on the method argument, determine the action we'd like pygments
|
139
|
+
to do. Then return the data generated from pygments.
|
140
|
+
"""
|
141
|
+
if kwargs:
|
142
|
+
formatter_name = kwargs.get("formatter", None)
|
143
|
+
opts = kwargs.get("options", {})
|
144
|
+
|
145
|
+
# Ensure there's a 'method' key before proceeeding
|
146
|
+
if method:
|
147
|
+
res = None
|
148
|
+
|
149
|
+
# Now check what that method is. For the get methods, pygments
|
150
|
+
# itself returns generators, so we make them lists so we can serialize
|
151
|
+
# easier.
|
152
|
+
if method == 'get_all_styles':
|
153
|
+
res = json.dumps(list(pygments.styles.get_all_styles()))
|
154
|
+
|
155
|
+
elif method == 'get_all_filters':
|
156
|
+
res = json.dumps(list(pygments.filters.get_all_filters()))
|
157
|
+
|
158
|
+
elif method == 'get_all_lexers':
|
159
|
+
res = json.dumps(list(pygments.lexers.get_all_lexers()))
|
160
|
+
|
161
|
+
elif method == 'get_all_formatters':
|
162
|
+
res = [ [ft.__name__, ft.name, ft.aliases] for ft in pygments.formatters.get_all_formatters() ]
|
163
|
+
res = json.dumps(res)
|
164
|
+
|
165
|
+
elif method == 'highlight':
|
166
|
+
try:
|
167
|
+
text = text.decode('utf-8')
|
168
|
+
except UnicodeDecodeError:
|
169
|
+
# The text may already be encoded
|
170
|
+
text = text
|
171
|
+
res = self.highlight_text(text, lexer, formatter_name, args, _convert_keys(opts))
|
172
|
+
|
173
|
+
elif method == 'css':
|
174
|
+
kwargs = _convert_keys(kwargs)
|
175
|
+
fmt = pygments.formatters.get_formatter_by_name(args[0], **kwargs)
|
176
|
+
res = fmt.get_style_defs(args[1])
|
177
|
+
|
178
|
+
elif method == 'lexer_name_for':
|
179
|
+
lexer = self.return_lexer(None, args, kwargs, text)
|
180
|
+
|
181
|
+
if lexer:
|
182
|
+
# We don't want the Lexer itself, just the name.
|
183
|
+
# Take the first alias.
|
184
|
+
res = lexer.aliases[0]
|
185
|
+
|
186
|
+
else:
|
187
|
+
_write_error("No lexer")
|
188
|
+
|
189
|
+
else:
|
190
|
+
_write_error("Invalid method " + method)
|
191
|
+
|
192
|
+
return res
|
193
|
+
|
194
|
+
|
195
|
+
def _send_data(self, res, method):
|
196
|
+
|
197
|
+
# Base header. We'll build on this, adding keys as necessary.
|
198
|
+
base_header = {"method": method}
|
199
|
+
|
200
|
+
res_bytes = len(res) + 1
|
201
|
+
base_header["bytes"] = res_bytes
|
202
|
+
|
203
|
+
out_header = json.dumps(base_header).encode('utf-8')
|
204
|
+
|
205
|
+
# Following the protocol, send over a fixed size represenation of the
|
206
|
+
# size of the JSON header
|
207
|
+
bits = _get_fixed_bits_from_header(out_header)
|
208
|
+
|
209
|
+
# Send it to Rubyland
|
210
|
+
sys.stdout.write(bits + "\n")
|
211
|
+
sys.stdout.flush()
|
212
|
+
|
213
|
+
# Send the header.
|
214
|
+
sys.stdout.write(out_header + "\n")
|
215
|
+
sys.stdout.flush()
|
216
|
+
|
217
|
+
# Finally, send the result
|
218
|
+
sys.stdout.write(res + "\n")
|
219
|
+
sys.stdout.flush()
|
220
|
+
|
221
|
+
|
222
|
+
def _get_ids(self, text):
|
223
|
+
start_id = text[:8]
|
224
|
+
end_id = text[-8:]
|
225
|
+
return start_id, end_id
|
226
|
+
|
227
|
+
def _check_and_return_text(self, text, start_id, end_id):
|
228
|
+
|
229
|
+
# Sanity check.
|
230
|
+
id_regex = re.compile('[A-Z]{8}')
|
231
|
+
|
232
|
+
if not id_regex.match(start_id) and not id_regex.match(end_id):
|
233
|
+
_write_error("ID check failed. Not an ID.")
|
234
|
+
|
235
|
+
if not start_id == end_id:
|
236
|
+
_write_error("ID check failed. ID's did not match.")
|
237
|
+
|
238
|
+
# Passed the sanity check. Remove the id's and return
|
239
|
+
text = text[10:-10]
|
240
|
+
return text
|
241
|
+
|
242
|
+
def _parse_header(self, header):
|
243
|
+
method = header["method"]
|
244
|
+
args = header.get("args", [])
|
245
|
+
kwargs = header.get("kwargs", {})
|
246
|
+
lexer = kwargs.get("lexer", None)
|
247
|
+
return (method, args, kwargs, lexer)
|
248
|
+
|
249
|
+
def start(self):
|
250
|
+
"""
|
251
|
+
Main loop, waiting for inputs on stdin. When it gets some data,
|
252
|
+
it goes to work.
|
253
|
+
|
254
|
+
mentos exposes most of the "High-level API" of pygments. It always
|
255
|
+
expects and requires a JSON header of metadata. If there is data to be
|
256
|
+
pygmentized, this header will be followed by the text to be pygmentized.
|
257
|
+
|
258
|
+
The header is of form:
|
259
|
+
{ "method": "highlight", "args": [], "kwargs": {"arg1": "v"}, "bytes": 128, "fd": "8"}
|
260
|
+
"""
|
261
|
+
lock = Lock()
|
262
|
+
|
263
|
+
while True:
|
264
|
+
# The loop begins by reading off a simple 32-arity string
|
265
|
+
# representing an integer of 32 bits. This is the length of
|
266
|
+
# our JSON header.
|
267
|
+
size = sys.stdin.read(32)
|
268
|
+
|
269
|
+
lock.acquire()
|
270
|
+
|
271
|
+
try:
|
272
|
+
# Read from stdin the amount of bytes we were told to expect.
|
273
|
+
header_bytes = int(size, 2)
|
274
|
+
|
275
|
+
# Sanity check the size
|
276
|
+
size_regex = re.compile('[0-1]{32}')
|
277
|
+
if not size_regex.match(size):
|
278
|
+
_write_error("Size received is not valid.")
|
279
|
+
|
280
|
+
line = sys.stdin.read(header_bytes)
|
281
|
+
|
282
|
+
header = json.loads(line)
|
283
|
+
|
284
|
+
method, args, kwargs, lexer = self._parse_header(header)
|
285
|
+
_bytes = 0
|
286
|
+
|
287
|
+
if lexer:
|
288
|
+
lexer = str(lexer)
|
289
|
+
|
290
|
+
# Read more bytes if necessary
|
291
|
+
if kwargs:
|
292
|
+
_bytes = kwargs.get("bytes", 0)
|
293
|
+
|
294
|
+
# Read up to the given number bytes (possibly 0)
|
295
|
+
text = sys.stdin.read(_bytes)
|
296
|
+
|
297
|
+
# Sanity check the return.
|
298
|
+
if _bytes:
|
299
|
+
start_id, end_id = self._get_ids(text)
|
300
|
+
text = self._check_and_return_text(text, start_id, end_id)
|
301
|
+
|
302
|
+
# Get the actual data from pygments.
|
303
|
+
res = self.get_data(method, lexer, args, kwargs, text)
|
304
|
+
|
305
|
+
# Put back the sanity check values.
|
306
|
+
if method == "highlight":
|
307
|
+
res = start_id + " " + res + " " + end_id
|
308
|
+
|
309
|
+
self._send_data(res, method)
|
310
|
+
|
311
|
+
except:
|
312
|
+
tb = traceback.format_exc()
|
313
|
+
_write_error(tb)
|
314
|
+
|
315
|
+
finally:
|
316
|
+
lock.release()
|
317
|
+
|
318
|
+
def main():
|
319
|
+
|
320
|
+
# Signal handlers to trap signals.
|
321
|
+
signal.signal(signal.SIGINT, _signal_handler)
|
322
|
+
signal.signal(signal.SIGTERM, _signal_handler)
|
323
|
+
if sys.platform != "win32":
|
324
|
+
signal.signal(signal.SIGHUP, _signal_handler)
|
325
|
+
|
326
|
+
mentos = Mentos()
|
327
|
+
|
328
|
+
if sys.platform == "win32":
|
329
|
+
# disable CRLF
|
330
|
+
import msvcrt
|
331
|
+
msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
|
332
|
+
else:
|
333
|
+
# close fd's inherited from the ruby parent
|
334
|
+
import resource
|
335
|
+
maxfd = resource.getrlimit(resource.RLIMIT_NOFILE)[1]
|
336
|
+
if maxfd == resource.RLIM_INFINITY:
|
337
|
+
maxfd = 65536
|
338
|
+
|
339
|
+
for fd in range(3, maxfd):
|
340
|
+
try:
|
341
|
+
os.close(fd)
|
342
|
+
except:
|
343
|
+
pass
|
344
|
+
|
345
|
+
mentos.start()
|
346
|
+
|
347
|
+
if __name__ == "__main__":
|
348
|
+
main()
|
349
|
+
|
350
|
+
|
351
|
+
|
@@ -0,0 +1,404 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require 'yajl'
|
3
|
+
require 'timeout'
|
4
|
+
require 'logger'
|
5
|
+
require 'time'
|
6
|
+
|
7
|
+
# Error class
|
8
|
+
class MentosError < IOError
|
9
|
+
end
|
10
|
+
|
11
|
+
# Pygments provides access to the Pygments library via a pipe and a long-running
|
12
|
+
# Python process.
|
13
|
+
module Pygments
|
14
|
+
module Popen
|
15
|
+
extend self
|
16
|
+
|
17
|
+
# Get things started by opening a pipe to mentos (the freshmaker), a
|
18
|
+
# Python process that talks to the Pygments library. We'll talk back and
|
19
|
+
# forth across this pipe.
|
20
|
+
def start(pygments_path = File.expand_path('../../../vendor/pygments-main/', __FILE__))
|
21
|
+
is_windows = RUBY_PLATFORM =~ /mswin|mingw/
|
22
|
+
begin
|
23
|
+
@log = Logger.new(ENV['MENTOS_LOG'] ||= is_windows ? 'NUL:' : '/dev/null')
|
24
|
+
@log.level = Logger::INFO
|
25
|
+
@log.datetime_format = "%Y-%m-%d %H:%M "
|
26
|
+
rescue
|
27
|
+
@log = Logger.new(is_windows ? 'NUL:' : '/dev/null')
|
28
|
+
end
|
29
|
+
|
30
|
+
ENV['PYGMENTS_PATH'] = pygments_path
|
31
|
+
|
32
|
+
# Make sure we kill off the child when we're done
|
33
|
+
at_exit { stop "Exiting" }
|
34
|
+
|
35
|
+
# A pipe to the mentos python process. #popen4 gives us
|
36
|
+
# the pid and three IO objects to write and read.
|
37
|
+
script = "#{python_binary} #{File.expand_path('../mentos.py', __FILE__)}"
|
38
|
+
@pid, @in, @out, @err = popen4(script)
|
39
|
+
@log.info "[#{Time.now.iso8601}] Starting pid #{@pid.to_s} with fd #{@out.to_i.to_s}."
|
40
|
+
end
|
41
|
+
|
42
|
+
# Detect a suitable Python binary to use. We can't just use `python2`
|
43
|
+
# because apparently some old versions of Debian only have `python` or
|
44
|
+
# something like that.
|
45
|
+
def python_binary
|
46
|
+
@python_binary ||= begin
|
47
|
+
`which python2`
|
48
|
+
$?.success? ? "python2" : "python"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# Stop the child process by issuing a kill -9.
|
53
|
+
#
|
54
|
+
# We then call waitpid() with the pid, which waits for that particular
|
55
|
+
# child and reaps it.
|
56
|
+
#
|
57
|
+
# kill() can set errno to ESRCH if, for some reason, the file
|
58
|
+
# is gone; regardless the final outcome of this method
|
59
|
+
# will be to set our @pid variable to nil.
|
60
|
+
#
|
61
|
+
# Technically, kill() can also fail with EPERM or EINVAL (wherein
|
62
|
+
# the signal isn't sent); but we have permissions, and
|
63
|
+
# we're not doing anything invalid here.
|
64
|
+
def stop(reason)
|
65
|
+
if @pid
|
66
|
+
begin
|
67
|
+
Process.kill('KILL', @pid)
|
68
|
+
Process.waitpid(@pid)
|
69
|
+
rescue Errno::ESRCH, Errno::ECHILD
|
70
|
+
end
|
71
|
+
end
|
72
|
+
@log.info "[#{Time.now.iso8601}] Killing pid: #{@pid.to_s}. Reason: #{reason}"
|
73
|
+
@pid = nil
|
74
|
+
end
|
75
|
+
|
76
|
+
# Check for a @pid variable, and then hit `kill -0` with the pid to
|
77
|
+
# check if the pid is still in the process table. If this function
|
78
|
+
# gives us an ENOENT or ESRCH, we can also safely return false (no process
|
79
|
+
# to worry about). Defensively, if EPERM is raised, in a odd/rare
|
80
|
+
# dying process situation (e.g., mentos is checking on the pid of a dead
|
81
|
+
# process and the pid has already been re-used) we'll want to raise
|
82
|
+
# that as a more informative Mentos exception.
|
83
|
+
#
|
84
|
+
# Returns true if the child is alive.
|
85
|
+
def alive?
|
86
|
+
return true if @pid && Process.kill(0, @pid)
|
87
|
+
false
|
88
|
+
rescue Errno::ENOENT, Errno::ESRCH
|
89
|
+
false
|
90
|
+
rescue Errno::EPERM
|
91
|
+
raise MentosError, "EPERM checking if child process is alive."
|
92
|
+
end
|
93
|
+
|
94
|
+
# Public: Get an array of available Pygments formatters
|
95
|
+
#
|
96
|
+
# Returns an array of formatters.
|
97
|
+
def formatters
|
98
|
+
mentos(:get_all_formatters).inject(Hash.new) do | hash, (name, desc, aliases) |
|
99
|
+
# Remove the long-winded and repetitive 'Formatter' suffix
|
100
|
+
name.sub!(/Formatter$/, '')
|
101
|
+
hash[name] = {
|
102
|
+
:name => name,
|
103
|
+
:description => desc,
|
104
|
+
:aliases => aliases
|
105
|
+
}
|
106
|
+
hash
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
|
111
|
+
# Public: Get all lexers from a serialized array. This avoids needing to spawn
|
112
|
+
# mentos when it's not really needed (e.g,. one-off jobs, loading the Rails env, etc).
|
113
|
+
#
|
114
|
+
# Should be preferred to #lexers!
|
115
|
+
#
|
116
|
+
# Returns an array of lexers
|
117
|
+
def lexers
|
118
|
+
begin
|
119
|
+
lexer_file = File.expand_path('../../../lexers', __FILE__)
|
120
|
+
raw = File.open(lexer_file, "r").read
|
121
|
+
Marshal.load(raw)
|
122
|
+
rescue Errno::ENOENT
|
123
|
+
raise MentosError, "Error loading lexer file. Was it created and vendored?"
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
# Public: Get back all available lexers from mentos itself
|
128
|
+
#
|
129
|
+
# Returns an array of lexers
|
130
|
+
def lexers!
|
131
|
+
mentos(:get_all_lexers).inject(Hash.new) do |hash, lxr|
|
132
|
+
name = lxr[0]
|
133
|
+
hash[name] = {
|
134
|
+
:name => name,
|
135
|
+
:aliases => lxr[1],
|
136
|
+
:filenames => lxr[2],
|
137
|
+
:mimetypes => lxr[3]
|
138
|
+
}
|
139
|
+
hash["Augeas"] = {:name=>"Augeas", :aliases=>["augeas"], :filenames=>["*.aug"], :mimetypes=>[]}
|
140
|
+
hash["dasm16"] = {:name=>"dasm16", :aliases=>["DASM16"], :filenames=>["*.dasm16", "*.dasm"], :mimetypes=>['text/x-dasm16']}
|
141
|
+
hash["Puppet"] = {:name=>"Puppet", :aliases=>["puppet"], :filenames=>["*.pp"], :mimetypes=>[]}
|
142
|
+
hash["Slash"] = {:name=>"Slash", :aliases=>["slash"], :filenames=>["*.sl"], :mimetypes=>[]}
|
143
|
+
hash
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
# Public: Return an array of all available filters
|
148
|
+
def filters
|
149
|
+
mentos(:get_all_filters)
|
150
|
+
end
|
151
|
+
|
152
|
+
# Public: Return an array of all available styles
|
153
|
+
def styles
|
154
|
+
mentos(:get_all_styles)
|
155
|
+
end
|
156
|
+
|
157
|
+
# Public: Return css for highlighted code
|
158
|
+
def css(klass='', opts={})
|
159
|
+
if klass.is_a?(Hash)
|
160
|
+
opts = klass
|
161
|
+
klass = ''
|
162
|
+
end
|
163
|
+
mentos(:css, ['html', klass], opts)
|
164
|
+
end
|
165
|
+
|
166
|
+
# Public: Return the name of a lexer.
|
167
|
+
def lexer_name_for(*args)
|
168
|
+
# Pop off the last arg if it's a hash, which becomes our opts
|
169
|
+
if args.last.is_a?(Hash)
|
170
|
+
opts = args.pop
|
171
|
+
else
|
172
|
+
opts = {}
|
173
|
+
end
|
174
|
+
|
175
|
+
if args.last.is_a?(String)
|
176
|
+
code = args.pop
|
177
|
+
else
|
178
|
+
code = nil
|
179
|
+
end
|
180
|
+
|
181
|
+
mentos(:lexer_name_for, args, opts, code)
|
182
|
+
end
|
183
|
+
|
184
|
+
# Public: Highlight code.
|
185
|
+
#
|
186
|
+
# Takes a first-position argument of the code to be highlighted, and a
|
187
|
+
# second-position hash of various arguments specifiying highlighting properties.
|
188
|
+
def highlight(code, opts={})
|
189
|
+
# If the caller didn't give us any code, we have nothing to do,
|
190
|
+
# so return right away.
|
191
|
+
return code if code.nil? || code.empty?
|
192
|
+
|
193
|
+
# Callers pass along options in the hash
|
194
|
+
opts[:options] ||= {}
|
195
|
+
|
196
|
+
# Default to utf-8 for the output encoding, if not given.
|
197
|
+
opts[:options][:outencoding] ||= 'utf-8'
|
198
|
+
|
199
|
+
# Get back the string from mentos and force encoding if we can
|
200
|
+
str = mentos(:highlight, nil, opts, code)
|
201
|
+
str.force_encoding(opts[:options][:outencoding]) if str.respond_to?(:force_encoding)
|
202
|
+
str
|
203
|
+
end
|
204
|
+
|
205
|
+
private
|
206
|
+
|
207
|
+
# Our 'rpc'-ish request to mentos. Requires a method name, and then optional
|
208
|
+
# args, kwargs, code.
|
209
|
+
def mentos(method, args=[], kwargs={}, original_code=nil)
|
210
|
+
# Open the pipe if necessary
|
211
|
+
start unless alive?
|
212
|
+
|
213
|
+
begin
|
214
|
+
# Timeout requests that take too long.
|
215
|
+
timeout_time = 8
|
216
|
+
|
217
|
+
Timeout::timeout(timeout_time) do
|
218
|
+
# For sanity checking on both sides of the pipe when highlighting, we prepend and
|
219
|
+
# append an id. mentos checks that these are 8 character ids and that they match.
|
220
|
+
# It then returns the id's back to Rubyland.
|
221
|
+
id = (0...8).map{65.+(rand(25)).chr}.join
|
222
|
+
code = add_ids(original_code, id) if original_code
|
223
|
+
|
224
|
+
# Add metadata to the header and generate it.
|
225
|
+
if code
|
226
|
+
bytesize = code.bytesize
|
227
|
+
else
|
228
|
+
bytesize = 0
|
229
|
+
end
|
230
|
+
|
231
|
+
kwargs.freeze
|
232
|
+
kwargs = kwargs.merge("fd" => @out.to_i, "id" => id, "bytes" => bytesize)
|
233
|
+
out_header = Yajl.dump(:method => method, :args => args, :kwargs => kwargs)
|
234
|
+
|
235
|
+
# Get the size of the header itself and write that.
|
236
|
+
bits = get_fixed_bits_from_header(out_header)
|
237
|
+
@in.write(bits)
|
238
|
+
|
239
|
+
# mentos is now waiting for the header, and, potentially, code.
|
240
|
+
write_data(out_header, code)
|
241
|
+
|
242
|
+
# mentos will now return data to us. First it sends the header.
|
243
|
+
header = get_header
|
244
|
+
|
245
|
+
# Now handle the header, any read any more data required.
|
246
|
+
res = handle_header_and_return(header, id)
|
247
|
+
|
248
|
+
# Finally, return what we got.
|
249
|
+
return_result(res, method)
|
250
|
+
end
|
251
|
+
rescue Timeout::Error
|
252
|
+
# If we timeout, we need to clear out the pipe and start over.
|
253
|
+
@log.error "[#{Time.now.iso8601}] Timeout on a mentos #{method} call"
|
254
|
+
stop "Timeout on mentos #{method} call."
|
255
|
+
end
|
256
|
+
|
257
|
+
rescue Errno::EPIPE, EOFError
|
258
|
+
stop "EPIPE"
|
259
|
+
raise MentosError, "EPIPE"
|
260
|
+
end
|
261
|
+
|
262
|
+
|
263
|
+
# Based on the header we receive, determine if we need
|
264
|
+
# to read more bytes, and read those bytes if necessary.
|
265
|
+
#
|
266
|
+
# Then, do a sanity check wih the ids.
|
267
|
+
#
|
268
|
+
# Returns a result — either highlighted text or metadata.
|
269
|
+
def handle_header_and_return(header, id)
|
270
|
+
if header
|
271
|
+
header = header_to_json(header)
|
272
|
+
bytes = header["bytes"]
|
273
|
+
|
274
|
+
# Read more bytes (the actual response body)
|
275
|
+
res = @out.read(bytes.to_i)
|
276
|
+
|
277
|
+
if header["method"] == "highlight"
|
278
|
+
# Make sure we have a result back; else consider this an error.
|
279
|
+
if res.nil?
|
280
|
+
@log.warn "[#{Time.now.iso8601}] No highlight result back from mentos."
|
281
|
+
stop "No highlight result back from mentos."
|
282
|
+
raise MentosError, "No highlight result back from mentos."
|
283
|
+
end
|
284
|
+
|
285
|
+
# Remove the newline from Python
|
286
|
+
res = res[0..-2]
|
287
|
+
@log.info "[#{Time.now.iso8601}] Highlight in process."
|
288
|
+
|
289
|
+
# Get the id's
|
290
|
+
start_id = res[0..7]
|
291
|
+
end_id = res[-8..-1]
|
292
|
+
|
293
|
+
# Sanity check.
|
294
|
+
if not (start_id == id and end_id == id)
|
295
|
+
@log.error "[#{Time.now.iso8601}] ID's did not match. Aborting."
|
296
|
+
stop "ID's did not match. Aborting."
|
297
|
+
raise MentosError, "ID's did not match. Aborting."
|
298
|
+
else
|
299
|
+
# We're good. Remove the padding
|
300
|
+
res = res[10..-11]
|
301
|
+
@log.info "[#{Time.now.iso8601}] Highlighting complete."
|
302
|
+
res
|
303
|
+
end
|
304
|
+
end
|
305
|
+
res
|
306
|
+
else
|
307
|
+
@log.error "[#{Time.now.iso8601}] No header data back."
|
308
|
+
stop "No header data back."
|
309
|
+
raise MentosError, "No header received back."
|
310
|
+
end
|
311
|
+
end
|
312
|
+
|
313
|
+
# With the code, prepend the id (with two spaces to avoid escaping weirdness if
|
314
|
+
# the following text starts with a slash (like terminal code), and append the
|
315
|
+
# id, with two padding also. This means we are sending over the 8 characters +
|
316
|
+
# code + 8 characters.
|
317
|
+
def add_ids(code, id)
|
318
|
+
code.freeze
|
319
|
+
code = id + " #{code} #{id}"
|
320
|
+
code
|
321
|
+
end
|
322
|
+
|
323
|
+
# Write data to mentos, the Python Process.
|
324
|
+
#
|
325
|
+
# Returns nothing.
|
326
|
+
def write_data(out_header, code=nil)
|
327
|
+
@in.write(out_header)
|
328
|
+
@log.info "[#{Time.now.iso8601}] Out header: #{out_header.to_s}"
|
329
|
+
@in.write(code) if code
|
330
|
+
end
|
331
|
+
|
332
|
+
# Sanity check for size (32-arity of 0's and 1's)
|
333
|
+
def size_check(size)
|
334
|
+
size_regex = /[0-1]{32}/
|
335
|
+
if size_regex.match(size)
|
336
|
+
true
|
337
|
+
else
|
338
|
+
false
|
339
|
+
end
|
340
|
+
end
|
341
|
+
|
342
|
+
# Read the header via the pipe.
|
343
|
+
#
|
344
|
+
# Returns a header.
|
345
|
+
def get_header
|
346
|
+
begin
|
347
|
+
size = @out.read(33)
|
348
|
+
size = size[0..-2]
|
349
|
+
|
350
|
+
# Sanity check the size
|
351
|
+
if not size_check(size)
|
352
|
+
@log.error "[#{Time.now.iso8601}] Size returned from mentos.py invalid."
|
353
|
+
stop "Size returned from mentos.py invalid."
|
354
|
+
raise MentosError, "Size returned from mentos.py invalid."
|
355
|
+
end
|
356
|
+
|
357
|
+
# Read the amount of bytes we should be expecting. We first
|
358
|
+
# convert the string of bits into an integer.
|
359
|
+
header_bytes = size.to_s.to_i(2) + 1
|
360
|
+
@log.info "[#{Time.now.iso8601}] Size in: #{size.to_s} (#{header_bytes.to_s})"
|
361
|
+
@out.read(header_bytes)
|
362
|
+
rescue
|
363
|
+
@log.error "[#{Time.now.iso8601}] Failed to get header."
|
364
|
+
stop "Failed to get header."
|
365
|
+
raise MentosError, "Failed to get header."
|
366
|
+
end
|
367
|
+
end
|
368
|
+
|
369
|
+
# Return the final result for the API. Return Ruby objects for the methods that
|
370
|
+
# want them, text otherwise.
|
371
|
+
def return_result(res, method)
|
372
|
+
unless method == :lexer_name_for || method == :highlight || method == :css
|
373
|
+
res = Yajl.load(res, :symbolize_keys => true)
|
374
|
+
end
|
375
|
+
res = res.rstrip if res.class == String
|
376
|
+
res
|
377
|
+
end
|
378
|
+
|
379
|
+
# Convert a text header into JSON for easy access.
|
380
|
+
def header_to_json(header)
|
381
|
+
@log.info "[#{Time.now.iso8601}] In header: #{header.to_s} "
|
382
|
+
header = Yajl.load(header)
|
383
|
+
|
384
|
+
if header["error"]
|
385
|
+
# Raise this as a Ruby exception of the MentosError class.
|
386
|
+
# Stop so we don't leave the pipe in an inconsistent state.
|
387
|
+
@log.error "[#{Time.now.iso8601}] Failed to convert header to JSON."
|
388
|
+
stop header["error"]
|
389
|
+
raise MentosError, header["error"]
|
390
|
+
else
|
391
|
+
header
|
392
|
+
end
|
393
|
+
end
|
394
|
+
|
395
|
+
def get_fixed_bits_from_header(out_header)
|
396
|
+
size = out_header.bytesize
|
397
|
+
|
398
|
+
# Fixed 32 bits to represent the int. We return a string
|
399
|
+
# represenation: e.g, "00000000000000000000000000011110"
|
400
|
+
Array.new(32) { |i| size[i] }.reverse!.join
|
401
|
+
end
|
402
|
+
end
|
403
|
+
end
|
404
|
+
|