pygments.rb 1.1.2 → 2.0.0
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 +5 -5
- data/.github/dependabot.yml +13 -0
- data/.github/workflows/ci.yml +28 -0
- data/.github/workflows/release.yml +24 -0
- data/.gitignore +5 -5
- data/CHANGELOG.adoc +128 -0
- data/Gemfile +3 -1
- data/LICENSE +1 -1
- data/README.adoc +160 -0
- data/Rakefile +13 -19
- data/bench.rb +8 -7
- data/cache-lexers.rb +3 -2
- data/lexers +0 -0
- data/lib/pygments.rb +10 -11
- data/lib/pygments/lexer.rb +5 -5
- data/lib/pygments/mentos.py +23 -110
- data/lib/pygments/popen.rb +148 -229
- data/lib/pygments/version.rb +2 -2
- data/pygments.rb.gemspec +12 -11
- data/test/test_pygments.rb +46 -104
- data/vendor/pygments-main/{AUTHORS → Pygments-2.7.3.dist-info/AUTHORS} +23 -3
- data/vendor/pygments-main/Pygments-2.7.3.dist-info/INSTALLER +1 -0
- data/vendor/pygments-main/{LICENSE → Pygments-2.7.3.dist-info/LICENSE} +1 -1
- data/vendor/pygments-main/Pygments-2.7.3.dist-info/METADATA +49 -0
- data/vendor/pygments-main/Pygments-2.7.3.dist-info/RECORD +482 -0
- data/vendor/pygments-main/Pygments-2.7.3.dist-info/REQUESTED +0 -0
- data/vendor/pygments-main/Pygments-2.7.3.dist-info/WHEEL +5 -0
- data/vendor/pygments-main/Pygments-2.7.3.dist-info/entry_points.txt +3 -0
- data/vendor/pygments-main/Pygments-2.7.3.dist-info/top_level.txt +1 -0
- data/vendor/pygments-main/bin/pygmentize +8 -0
- data/vendor/pygments-main/pygments/__init__.py +6 -11
- data/vendor/pygments-main/pygments/__main__.py +18 -0
- data/vendor/pygments-main/pygments/cmdline.py +94 -41
- data/vendor/pygments-main/pygments/console.py +6 -9
- data/vendor/pygments-main/pygments/filter.py +4 -6
- data/vendor/pygments-main/pygments/filters/__init__.py +609 -21
- data/vendor/pygments-main/pygments/formatter.py +4 -4
- data/vendor/pygments-main/pygments/formatters/__init__.py +42 -6
- data/vendor/pygments-main/pygments/formatters/_mapping.py +1 -3
- data/vendor/pygments-main/pygments/formatters/bbcode.py +1 -1
- data/vendor/pygments-main/pygments/formatters/html.py +223 -135
- data/vendor/pygments-main/pygments/formatters/img.py +102 -38
- data/vendor/pygments-main/pygments/formatters/irc.py +39 -39
- data/vendor/pygments-main/pygments/formatters/latex.py +56 -26
- data/vendor/pygments-main/pygments/formatters/other.py +12 -8
- data/vendor/pygments-main/pygments/formatters/rtf.py +29 -29
- data/vendor/pygments-main/pygments/formatters/svg.py +38 -4
- data/vendor/pygments-main/pygments/formatters/terminal.py +25 -31
- data/vendor/pygments-main/pygments/formatters/terminal256.py +22 -12
- data/vendor/pygments-main/pygments/lexer.py +41 -39
- data/vendor/pygments-main/pygments/lexers/__init__.py +62 -15
- data/vendor/pygments-main/pygments/lexers/_asy_builtins.py +5 -5
- data/vendor/pygments-main/pygments/lexers/_cl_builtins.py +15 -15
- data/vendor/pygments-main/pygments/lexers/_cocoa_builtins.py +11 -12
- data/vendor/pygments-main/pygments/lexers/_csound_builtins.py +1717 -1338
- data/vendor/pygments-main/pygments/lexers/_lasso_builtins.py +8 -1
- data/vendor/pygments-main/pygments/lexers/_lua_builtins.py +2 -4
- data/vendor/pygments-main/pygments/lexers/_mapping.py +79 -33
- data/vendor/pygments-main/pygments/lexers/_mql_builtins.py +2 -2
- data/vendor/pygments-main/pygments/lexers/_mysql_builtins.py +1282 -0
- data/vendor/pygments-main/pygments/lexers/_openedge_builtins.py +1 -1
- data/vendor/pygments-main/pygments/lexers/_php_builtins.py +17 -20
- data/vendor/pygments-main/pygments/lexers/_postgres_builtins.py +73 -16
- data/vendor/pygments-main/pygments/lexers/_scilab_builtins.py +2 -2
- data/vendor/pygments-main/pygments/lexers/_sourcemod_builtins.py +1 -3
- data/vendor/pygments-main/pygments/lexers/_stan_builtins.py +151 -125
- data/vendor/pygments-main/pygments/lexers/_stata_builtins.py +6 -4
- data/vendor/pygments-main/pygments/lexers/_tsql_builtins.py +1 -1
- data/vendor/pygments-main/pygments/lexers/_usd_builtins.py +113 -0
- data/vendor/pygments-main/pygments/lexers/_vbscript_builtins.py +280 -0
- data/vendor/pygments-main/pygments/lexers/_vim_builtins.py +1 -1
- data/vendor/pygments-main/pygments/lexers/actionscript.py +8 -3
- data/vendor/pygments-main/pygments/lexers/agile.py +1 -1
- data/vendor/pygments-main/pygments/lexers/algebra.py +20 -1
- data/vendor/pygments-main/pygments/lexers/ambient.py +1 -1
- data/vendor/pygments-main/pygments/lexers/ampl.py +3 -3
- data/vendor/pygments-main/pygments/lexers/apl.py +15 -15
- data/vendor/pygments-main/pygments/lexers/archetype.py +3 -3
- data/vendor/pygments-main/pygments/lexers/arrow.py +117 -0
- data/vendor/pygments-main/pygments/lexers/asm.py +445 -70
- data/vendor/pygments-main/pygments/lexers/automation.py +3 -3
- data/vendor/pygments-main/pygments/lexers/bare.py +104 -0
- data/vendor/pygments-main/pygments/lexers/basic.py +166 -4
- data/vendor/pygments-main/pygments/lexers/bibtex.py +13 -9
- data/vendor/pygments-main/pygments/lexers/boa.py +102 -0
- data/vendor/pygments-main/pygments/lexers/business.py +69 -36
- data/vendor/pygments-main/pygments/lexers/c_cpp.py +137 -45
- data/vendor/pygments-main/pygments/lexers/c_like.py +68 -43
- data/vendor/pygments-main/pygments/lexers/capnproto.py +20 -21
- data/vendor/pygments-main/pygments/lexers/chapel.py +25 -14
- data/vendor/pygments-main/pygments/lexers/clean.py +135 -244
- data/vendor/pygments-main/pygments/lexers/compiled.py +1 -1
- data/vendor/pygments-main/pygments/lexers/configs.py +188 -37
- data/vendor/pygments-main/pygments/lexers/console.py +1 -1
- data/vendor/pygments-main/pygments/lexers/crystal.py +31 -23
- data/vendor/pygments-main/pygments/lexers/csound.py +288 -187
- data/vendor/pygments-main/pygments/lexers/css.py +18 -16
- data/vendor/pygments-main/pygments/lexers/d.py +10 -5
- data/vendor/pygments-main/pygments/lexers/dalvik.py +1 -1
- data/vendor/pygments-main/pygments/lexers/data.py +240 -97
- data/vendor/pygments-main/pygments/lexers/devicetree.py +109 -0
- data/vendor/pygments-main/pygments/lexers/diff.py +4 -4
- data/vendor/pygments-main/pygments/lexers/dotnet.py +40 -24
- data/vendor/pygments-main/pygments/lexers/dsls.py +147 -65
- data/vendor/pygments-main/pygments/lexers/dylan.py +16 -18
- data/vendor/pygments-main/pygments/lexers/ecl.py +16 -2
- data/vendor/pygments-main/pygments/lexers/eiffel.py +1 -1
- data/vendor/pygments-main/pygments/lexers/elm.py +5 -5
- data/vendor/pygments-main/pygments/lexers/email.py +151 -0
- data/vendor/pygments-main/pygments/lexers/erlang.py +29 -32
- data/vendor/pygments-main/pygments/lexers/esoteric.py +54 -25
- data/vendor/pygments-main/pygments/lexers/ezhil.py +24 -15
- data/vendor/pygments-main/pygments/lexers/factor.py +1 -1
- data/vendor/pygments-main/pygments/lexers/fantom.py +1 -1
- data/vendor/pygments-main/pygments/lexers/felix.py +1 -1
- data/vendor/pygments-main/pygments/lexers/floscript.py +83 -0
- data/vendor/pygments-main/pygments/lexers/forth.py +41 -40
- data/vendor/pygments-main/pygments/lexers/fortran.py +5 -4
- data/vendor/pygments-main/pygments/lexers/foxpro.py +2 -2
- data/vendor/pygments-main/pygments/lexers/freefem.py +898 -0
- data/vendor/pygments-main/pygments/lexers/functional.py +1 -1
- data/vendor/pygments-main/pygments/lexers/gdscript.py +346 -0
- data/vendor/pygments-main/pygments/lexers/go.py +1 -1
- data/vendor/pygments-main/pygments/lexers/grammar_notation.py +63 -6
- data/vendor/pygments-main/pygments/lexers/graph.py +14 -9
- data/vendor/pygments-main/pygments/lexers/graphics.py +272 -25
- data/vendor/pygments-main/pygments/lexers/haskell.py +52 -22
- data/vendor/pygments-main/pygments/lexers/haxe.py +6 -6
- data/vendor/pygments-main/pygments/lexers/hdl.py +176 -86
- data/vendor/pygments-main/pygments/lexers/hexdump.py +18 -12
- data/vendor/pygments-main/pygments/lexers/html.py +31 -19
- data/vendor/pygments-main/pygments/lexers/idl.py +20 -9
- data/vendor/pygments-main/pygments/lexers/igor.py +244 -112
- data/vendor/pygments-main/pygments/lexers/inferno.py +2 -2
- data/vendor/pygments-main/pygments/lexers/installers.py +1 -1
- data/vendor/pygments-main/pygments/lexers/int_fiction.py +40 -15
- data/vendor/pygments-main/pygments/lexers/iolang.py +2 -2
- data/vendor/pygments-main/pygments/lexers/j.py +3 -3
- data/vendor/pygments-main/pygments/lexers/javascript.py +100 -66
- data/vendor/pygments-main/pygments/lexers/julia.py +46 -48
- data/vendor/pygments-main/pygments/lexers/jvm.py +265 -165
- data/vendor/pygments-main/pygments/lexers/lisp.py +882 -804
- data/vendor/pygments-main/pygments/lexers/make.py +10 -6
- data/vendor/pygments-main/pygments/lexers/markup.py +213 -43
- data/vendor/pygments-main/pygments/lexers/math.py +1 -1
- data/vendor/pygments-main/pygments/lexers/matlab.py +98 -41
- data/vendor/pygments-main/pygments/lexers/mime.py +226 -0
- data/vendor/pygments-main/pygments/lexers/ml.py +198 -9
- data/vendor/pygments-main/pygments/lexers/modeling.py +26 -18
- data/vendor/pygments-main/pygments/lexers/modula2.py +25 -6
- data/vendor/pygments-main/pygments/lexers/monte.py +4 -3
- data/vendor/pygments-main/pygments/lexers/mosel.py +448 -0
- data/vendor/pygments-main/pygments/lexers/ncl.py +85 -244
- data/vendor/pygments-main/pygments/lexers/nimrod.py +4 -4
- data/vendor/pygments-main/pygments/lexers/nit.py +1 -1
- data/vendor/pygments-main/pygments/lexers/nix.py +1 -1
- data/vendor/pygments-main/pygments/lexers/oberon.py +17 -1
- data/vendor/pygments-main/pygments/lexers/objective.py +16 -16
- data/vendor/pygments-main/pygments/lexers/ooc.py +1 -1
- data/vendor/pygments-main/pygments/lexers/other.py +1 -1
- data/vendor/pygments-main/pygments/lexers/parasail.py +1 -1
- data/vendor/pygments-main/pygments/lexers/parsers.py +23 -58
- data/vendor/pygments-main/pygments/lexers/pascal.py +23 -23
- data/vendor/pygments-main/pygments/lexers/pawn.py +30 -24
- data/vendor/pygments-main/pygments/lexers/perl.py +276 -160
- data/vendor/pygments-main/pygments/lexers/php.py +64 -10
- data/vendor/pygments-main/pygments/lexers/pointless.py +71 -0
- data/vendor/pygments-main/pygments/lexers/pony.py +94 -0
- data/vendor/pygments-main/pygments/lexers/praat.py +38 -30
- data/vendor/pygments-main/pygments/lexers/prolog.py +36 -36
- data/vendor/pygments-main/pygments/lexers/promql.py +183 -0
- data/vendor/pygments-main/pygments/lexers/python.py +439 -226
- data/vendor/pygments-main/pygments/lexers/qvt.py +6 -6
- data/vendor/pygments-main/pygments/lexers/r.py +13 -275
- data/vendor/pygments-main/pygments/lexers/rdf.py +232 -39
- data/vendor/pygments-main/pygments/lexers/rebol.py +8 -8
- data/vendor/pygments-main/pygments/lexers/resource.py +2 -2
- data/vendor/pygments-main/pygments/lexers/ride.py +139 -0
- data/vendor/pygments-main/pygments/lexers/rnc.py +1 -1
- data/vendor/pygments-main/pygments/lexers/roboconf.py +1 -1
- data/vendor/pygments-main/pygments/lexers/robotframework.py +23 -31
- data/vendor/pygments-main/pygments/lexers/ruby.py +22 -24
- data/vendor/pygments-main/pygments/lexers/rust.py +86 -71
- data/vendor/pygments-main/pygments/lexers/sas.py +7 -7
- data/vendor/pygments-main/pygments/lexers/scdoc.py +83 -0
- data/vendor/pygments-main/pygments/lexers/scripting.py +75 -13
- data/vendor/pygments-main/pygments/lexers/sgf.py +61 -0
- data/vendor/pygments-main/pygments/lexers/shell.py +175 -51
- data/vendor/pygments-main/pygments/lexers/sieve.py +69 -0
- data/vendor/pygments-main/pygments/lexers/slash.py +185 -0
- data/vendor/pygments-main/pygments/lexers/smalltalk.py +2 -2
- data/vendor/pygments-main/pygments/lexers/smv.py +30 -26
- data/vendor/pygments-main/pygments/lexers/snobol.py +1 -1
- data/vendor/pygments-main/pygments/lexers/solidity.py +92 -0
- data/vendor/pygments-main/pygments/lexers/special.py +5 -3
- data/vendor/pygments-main/pygments/lexers/sql.py +333 -177
- data/vendor/pygments-main/pygments/lexers/stata.py +107 -42
- data/vendor/pygments-main/pygments/lexers/supercollider.py +6 -1
- data/vendor/pygments-main/pygments/lexers/tcl.py +1 -1
- data/vendor/pygments-main/pygments/lexers/templates.py +144 -132
- data/vendor/pygments-main/pygments/lexers/teraterm.py +335 -0
- data/vendor/pygments-main/pygments/lexers/testing.py +6 -6
- data/vendor/pygments-main/pygments/lexers/text.py +2 -1
- data/vendor/pygments-main/pygments/lexers/textedit.py +4 -4
- data/vendor/pygments-main/pygments/lexers/textfmts.py +146 -13
- data/vendor/pygments-main/pygments/lexers/theorem.py +69 -53
- data/vendor/pygments-main/pygments/lexers/tnt.py +263 -0
- data/vendor/pygments-main/pygments/lexers/trafficscript.py +1 -1
- data/vendor/pygments-main/pygments/lexers/typoscript.py +8 -14
- data/vendor/pygments-main/pygments/lexers/unicon.py +412 -0
- data/vendor/pygments-main/pygments/lexers/urbi.py +14 -1
- data/vendor/pygments-main/pygments/lexers/usd.py +90 -0
- data/vendor/pygments-main/pygments/lexers/varnish.py +5 -5
- data/vendor/pygments-main/pygments/lexers/verification.py +15 -12
- data/vendor/pygments-main/pygments/lexers/web.py +1 -1
- data/vendor/pygments-main/pygments/lexers/webidl.py +299 -0
- data/vendor/pygments-main/pygments/lexers/webmisc.py +50 -38
- data/vendor/pygments-main/pygments/lexers/whiley.py +11 -12
- data/vendor/pygments-main/pygments/lexers/x10.py +1 -1
- data/vendor/pygments-main/pygments/lexers/xorg.py +37 -0
- data/vendor/pygments-main/pygments/lexers/yang.py +104 -0
- data/vendor/pygments-main/pygments/lexers/zig.py +124 -0
- data/vendor/pygments-main/pygments/modeline.py +6 -5
- data/vendor/pygments-main/pygments/plugin.py +14 -18
- data/vendor/pygments-main/pygments/regexopt.py +1 -1
- data/vendor/pygments-main/pygments/scanner.py +2 -2
- data/vendor/pygments-main/pygments/sphinxext.py +2 -4
- data/vendor/pygments-main/pygments/style.py +61 -24
- data/vendor/pygments-main/pygments/styles/__init__.py +13 -5
- data/vendor/pygments-main/pygments/styles/abap.py +29 -0
- data/vendor/pygments-main/pygments/styles/algol.py +1 -1
- data/vendor/pygments-main/pygments/styles/algol_nu.py +1 -1
- data/vendor/pygments-main/pygments/styles/arduino.py +2 -2
- data/vendor/pygments-main/pygments/styles/autumn.py +1 -1
- data/vendor/pygments-main/pygments/styles/borland.py +1 -1
- data/vendor/pygments-main/pygments/styles/bw.py +1 -1
- data/vendor/pygments-main/pygments/styles/colorful.py +1 -1
- data/vendor/pygments-main/pygments/styles/default.py +1 -1
- data/vendor/pygments-main/pygments/styles/emacs.py +1 -1
- data/vendor/pygments-main/pygments/styles/friendly.py +1 -1
- data/vendor/pygments-main/pygments/styles/fruity.py +1 -1
- data/vendor/pygments-main/pygments/styles/igor.py +1 -1
- data/vendor/pygments-main/pygments/styles/inkpot.py +67 -0
- data/vendor/pygments-main/pygments/styles/lovelace.py +1 -1
- data/vendor/pygments-main/pygments/styles/manni.py +1 -1
- data/vendor/pygments-main/pygments/styles/monokai.py +4 -3
- data/vendor/pygments-main/pygments/styles/murphy.py +1 -1
- data/vendor/pygments-main/pygments/styles/native.py +1 -1
- data/vendor/pygments-main/pygments/styles/paraiso_dark.py +1 -1
- data/vendor/pygments-main/pygments/styles/paraiso_light.py +1 -1
- data/vendor/pygments-main/pygments/styles/pastie.py +1 -1
- data/vendor/pygments-main/pygments/styles/perldoc.py +1 -1
- data/vendor/pygments-main/pygments/styles/rainbow_dash.py +89 -0
- data/vendor/pygments-main/pygments/styles/rrt.py +1 -1
- data/vendor/pygments-main/pygments/styles/sas.py +3 -0
- data/vendor/pygments-main/pygments/styles/solarized.py +134 -0
- data/vendor/pygments-main/pygments/styles/stata_dark.py +41 -0
- data/vendor/pygments-main/pygments/styles/stata_light.py +39 -0
- data/vendor/pygments-main/pygments/styles/tango.py +1 -1
- data/vendor/pygments-main/pygments/styles/trac.py +1 -1
- data/vendor/pygments-main/pygments/styles/vim.py +1 -1
- data/vendor/pygments-main/pygments/styles/vs.py +1 -1
- data/vendor/pygments-main/pygments/styles/xcode.py +1 -1
- data/vendor/pygments-main/pygments/token.py +1 -1
- data/vendor/pygments-main/pygments/unistring.py +47 -108
- data/vendor/pygments-main/pygments/util.py +19 -95
- metadata +71 -137
- data/CHANGELOG.md +0 -98
- data/README.md +0 -121
- data/circle.yml +0 -20
- data/test/test_data.c +0 -2581
- data/test/test_data.py +0 -514
- data/test/test_data_generated +0 -2582
- data/vendor/custom_lexers/github.py +0 -565
- data/vendor/pygments-main/CHANGES +0 -1163
- data/vendor/pygments-main/MANIFEST.in +0 -6
- data/vendor/pygments-main/Makefile +0 -65
- data/vendor/pygments-main/README.rst +0 -39
- data/vendor/pygments-main/REVISION +0 -1
- data/vendor/pygments-main/TODO +0 -12
- data/vendor/pygments-main/doc/Makefile +0 -153
- data/vendor/pygments-main/doc/_static/favicon.ico +0 -0
- data/vendor/pygments-main/doc/_static/logo_new.png +0 -0
- data/vendor/pygments-main/doc/_static/logo_only.png +0 -0
- data/vendor/pygments-main/doc/_templates/docssidebar.html +0 -3
- data/vendor/pygments-main/doc/_templates/indexsidebar.html +0 -25
- data/vendor/pygments-main/doc/_themes/pygments14/layout.html +0 -98
- data/vendor/pygments-main/doc/_themes/pygments14/static/bodybg.png +0 -0
- data/vendor/pygments-main/doc/_themes/pygments14/static/docbg.png +0 -0
- data/vendor/pygments-main/doc/_themes/pygments14/static/listitem.png +0 -0
- data/vendor/pygments-main/doc/_themes/pygments14/static/logo.png +0 -0
- data/vendor/pygments-main/doc/_themes/pygments14/static/pocoo.png +0 -0
- data/vendor/pygments-main/doc/_themes/pygments14/static/pygments14.css_t +0 -401
- data/vendor/pygments-main/doc/_themes/pygments14/theme.conf +0 -15
- data/vendor/pygments-main/doc/conf.py +0 -241
- data/vendor/pygments-main/doc/docs/api.rst +0 -331
- data/vendor/pygments-main/doc/docs/authors.rst +0 -4
- data/vendor/pygments-main/doc/docs/changelog.rst +0 -1
- data/vendor/pygments-main/doc/docs/cmdline.rst +0 -149
- data/vendor/pygments-main/doc/docs/filterdevelopment.rst +0 -71
- data/vendor/pygments-main/doc/docs/filters.rst +0 -41
- data/vendor/pygments-main/doc/docs/formatterdevelopment.rst +0 -169
- data/vendor/pygments-main/doc/docs/formatters.rst +0 -48
- data/vendor/pygments-main/doc/docs/index.rst +0 -66
- data/vendor/pygments-main/doc/docs/integrate.rst +0 -40
- data/vendor/pygments-main/doc/docs/java.rst +0 -70
- data/vendor/pygments-main/doc/docs/lexerdevelopment.rst +0 -689
- data/vendor/pygments-main/doc/docs/lexers.rst +0 -69
- data/vendor/pygments-main/doc/docs/moinmoin.rst +0 -39
- data/vendor/pygments-main/doc/docs/plugins.rst +0 -93
- data/vendor/pygments-main/doc/docs/quickstart.rst +0 -205
- data/vendor/pygments-main/doc/docs/rstdirective.rst +0 -22
- data/vendor/pygments-main/doc/docs/styles.rst +0 -201
- data/vendor/pygments-main/doc/docs/tokens.rst +0 -372
- data/vendor/pygments-main/doc/docs/unicode.rst +0 -58
- data/vendor/pygments-main/doc/download.rst +0 -41
- data/vendor/pygments-main/doc/faq.rst +0 -139
- data/vendor/pygments-main/doc/index.rst +0 -54
- data/vendor/pygments-main/doc/languages.rst +0 -154
- data/vendor/pygments-main/doc/make.bat +0 -190
- data/vendor/pygments-main/doc/pygmentize.1 +0 -94
- data/vendor/pygments-main/external/autopygmentize +0 -84
- data/vendor/pygments-main/external/lasso-builtins-generator-9.lasso +0 -162
- data/vendor/pygments-main/external/markdown-processor.py +0 -67
- data/vendor/pygments-main/external/moin-parser.py +0 -112
- data/vendor/pygments-main/external/pygments.bashcomp +0 -38
- data/vendor/pygments-main/external/rst-directive.py +0 -82
- data/vendor/pygments-main/pygmentize +0 -8
- data/vendor/pygments-main/pygments/lexers/github.py +0 -565
- data/vendor/pygments-main/pygments/styles/stata.py +0 -37
- data/vendor/pygments-main/requirements.txt +0 -5
- data/vendor/pygments-main/scripts/check_sources.py +0 -211
- data/vendor/pygments-main/scripts/debug_lexer.py +0 -246
- data/vendor/pygments-main/scripts/detect_missing_analyse_text.py +0 -33
- data/vendor/pygments-main/scripts/epydoc.css +0 -280
- data/vendor/pygments-main/scripts/find_error.py +0 -1
- data/vendor/pygments-main/scripts/get_vimkw.py +0 -74
- data/vendor/pygments-main/scripts/pylintrc +0 -301
- data/vendor/pygments-main/scripts/vim2pygments.py +0 -935
- data/vendor/pygments-main/setup.cfg +0 -10
- data/vendor/pygments-main/setup.py +0 -77
- data/vendor/pygments-main/tox.ini +0 -7
- data/vendor/simplejson/.gitignore +0 -10
- data/vendor/simplejson/.travis.yml +0 -5
- data/vendor/simplejson/CHANGES.txt +0 -291
- data/vendor/simplejson/LICENSE.txt +0 -19
- data/vendor/simplejson/MANIFEST.in +0 -5
- data/vendor/simplejson/README.rst +0 -19
- data/vendor/simplejson/conf.py +0 -179
- data/vendor/simplejson/index.rst +0 -628
- data/vendor/simplejson/scripts/make_docs.py +0 -18
- data/vendor/simplejson/setup.py +0 -104
- data/vendor/simplejson/simplejson/__init__.py +0 -510
- data/vendor/simplejson/simplejson/_speedups.c +0 -2745
- data/vendor/simplejson/simplejson/decoder.py +0 -425
- data/vendor/simplejson/simplejson/encoder.py +0 -567
- data/vendor/simplejson/simplejson/ordered_dict.py +0 -119
- data/vendor/simplejson/simplejson/scanner.py +0 -77
- data/vendor/simplejson/simplejson/tests/__init__.py +0 -67
- data/vendor/simplejson/simplejson/tests/test_bigint_as_string.py +0 -55
- data/vendor/simplejson/simplejson/tests/test_check_circular.py +0 -30
- data/vendor/simplejson/simplejson/tests/test_decimal.py +0 -66
- data/vendor/simplejson/simplejson/tests/test_decode.py +0 -83
- data/vendor/simplejson/simplejson/tests/test_default.py +0 -9
- data/vendor/simplejson/simplejson/tests/test_dump.py +0 -67
- data/vendor/simplejson/simplejson/tests/test_encode_basestring_ascii.py +0 -46
- data/vendor/simplejson/simplejson/tests/test_encode_for_html.py +0 -32
- data/vendor/simplejson/simplejson/tests/test_errors.py +0 -34
- data/vendor/simplejson/simplejson/tests/test_fail.py +0 -91
- data/vendor/simplejson/simplejson/tests/test_float.py +0 -19
- data/vendor/simplejson/simplejson/tests/test_indent.py +0 -86
- data/vendor/simplejson/simplejson/tests/test_item_sort_key.py +0 -20
- data/vendor/simplejson/simplejson/tests/test_namedtuple.py +0 -121
- data/vendor/simplejson/simplejson/tests/test_pass1.py +0 -76
- data/vendor/simplejson/simplejson/tests/test_pass2.py +0 -14
- data/vendor/simplejson/simplejson/tests/test_pass3.py +0 -20
- data/vendor/simplejson/simplejson/tests/test_recursion.py +0 -67
- data/vendor/simplejson/simplejson/tests/test_scanstring.py +0 -117
- data/vendor/simplejson/simplejson/tests/test_separators.py +0 -42
- data/vendor/simplejson/simplejson/tests/test_speedups.py +0 -20
- data/vendor/simplejson/simplejson/tests/test_tuple.py +0 -49
- data/vendor/simplejson/simplejson/tests/test_unicode.py +0 -109
- data/vendor/simplejson/simplejson/tool.py +0 -39
data/bench.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require File.join(File.dirname(__FILE__), '/lib/pygments.rb')
|
|
2
4
|
require 'benchmark'
|
|
3
5
|
|
|
@@ -8,15 +10,14 @@ num = ARGV[0] ? ARGV[0].to_i : 10
|
|
|
8
10
|
# we can also repeat the code itself
|
|
9
11
|
repeats = ARGV[1] ? ARGV[1].to_i : 1
|
|
10
12
|
|
|
11
|
-
code = File.open('test/
|
|
13
|
+
code = File.open('test/test_pygments.rb').read.to_s * repeats
|
|
12
14
|
|
|
13
15
|
puts "Benchmarking....\n"
|
|
14
|
-
puts
|
|
15
|
-
puts
|
|
16
|
+
puts 'Size: ' + code.bytesize.to_s + " bytes\n"
|
|
17
|
+
puts 'Iterations: ' + num.to_s + "\n"
|
|
16
18
|
|
|
17
19
|
Benchmark.bm(40) do |x|
|
|
18
|
-
x.report(
|
|
19
|
-
x.report(
|
|
20
|
-
x.report(
|
|
20
|
+
x.report('pygments popen ') { (1..num).each { |_i|; Pygments.highlight(code, lexer: 'python'); } }
|
|
21
|
+
x.report('pygments popen (process already started) ') { (1..num).each { |_i|; Pygments.highlight(code, lexer: 'python'); } }
|
|
22
|
+
x.report('pygments popen (process already started 2) ') { (1..num).each { |_i|; Pygments.highlight(code, lexer: 'python'); } }
|
|
21
23
|
end
|
|
22
|
-
|
data/cache-lexers.rb
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require File.join(File.dirname(__FILE__), '/lib/pygments.rb')
|
|
2
4
|
|
|
3
5
|
# Simple marshalling
|
|
4
6
|
serialized_lexers = Marshal.dump(Pygments.lexers!)
|
|
5
7
|
|
|
6
8
|
# Write to a file
|
|
7
|
-
File.open(
|
|
8
|
-
|
|
9
|
+
File.open('lexers', 'wb') { |file| file.write(serialized_lexers) }
|
data/lexers
CHANGED
|
Binary file
|
data/lib/pygments.rb
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
# coding: utf-8
|
|
2
1
|
# frozen_string_literal: true
|
|
2
|
+
|
|
3
3
|
require File.join(File.dirname(__FILE__), 'pygments/popen')
|
|
4
4
|
require 'forwardable'
|
|
5
5
|
|
|
6
6
|
module Pygments
|
|
7
|
-
|
|
8
7
|
autoload :Lexer, 'pygments/lexer'
|
|
9
8
|
|
|
10
9
|
class << self
|
|
@@ -16,14 +15,14 @@ module Pygments
|
|
|
16
15
|
end
|
|
17
16
|
|
|
18
17
|
def_delegators :engine,
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
18
|
+
:formatters,
|
|
19
|
+
:lexers,
|
|
20
|
+
:lexers!,
|
|
21
|
+
:filters,
|
|
22
|
+
:styles,
|
|
23
|
+
:css,
|
|
24
|
+
:lexer_name_for,
|
|
25
|
+
:highlight,
|
|
26
|
+
:start
|
|
28
27
|
end
|
|
29
28
|
end
|
data/lib/pygments/lexer.rb
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
# coding: utf-8
|
|
2
1
|
# frozen_string_literal: true
|
|
2
|
+
|
|
3
3
|
module Pygments
|
|
4
4
|
class Lexer < Struct.new(:name, :aliases, :filenames, :mimetypes)
|
|
5
5
|
@lexers = []
|
|
@@ -34,13 +34,13 @@ module Pygments
|
|
|
34
34
|
m[1].scan(/./).each do |s|
|
|
35
35
|
extnames << extname.sub(m[0], s)
|
|
36
36
|
end
|
|
37
|
-
elsif extname !=
|
|
37
|
+
elsif extname != ''
|
|
38
38
|
extnames << extname
|
|
39
39
|
end
|
|
40
40
|
|
|
41
41
|
extnames.each do |the_extname|
|
|
42
42
|
@extname_index[the_extname] = lexer
|
|
43
|
-
@index[the_extname.downcase.sub(/^\./,
|
|
43
|
+
@index[the_extname.downcase.sub(/^\./, '')] ||= lexer
|
|
44
44
|
end
|
|
45
45
|
end
|
|
46
46
|
|
|
@@ -142,8 +142,8 @@ module Pygments
|
|
|
142
142
|
Pygments.highlight(text, options)
|
|
143
143
|
end
|
|
144
144
|
|
|
145
|
-
|
|
146
|
-
|
|
145
|
+
alias == equal?
|
|
146
|
+
alias eql? equal?
|
|
147
147
|
end
|
|
148
148
|
|
|
149
149
|
lexers.values.each { |h| Lexer.create(h) }
|
data/lib/pygments/mentos.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
#!/usr/bin/env
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
3
|
|
|
4
|
+
import struct
|
|
4
5
|
import sys, re, os, signal
|
|
5
6
|
import traceback
|
|
6
7
|
if 'PYGMENTS_PATH' in os.environ:
|
|
@@ -9,15 +10,11 @@ if 'PYGMENTS_PATH' in os.environ:
|
|
|
9
10
|
dirname = os.path.dirname
|
|
10
11
|
|
|
11
12
|
base_dir = dirname(dirname(dirname(os.path.abspath(__file__))))
|
|
12
|
-
sys.path.append(base_dir + "/vendor")
|
|
13
13
|
sys.path.append(base_dir + "/vendor/pygments-main")
|
|
14
|
-
sys.path.append(base_dir + "/vendor/simplejson")
|
|
15
14
|
|
|
16
15
|
import pygments
|
|
17
16
|
from pygments import lexers, formatters, styles, filters
|
|
18
17
|
|
|
19
|
-
from threading import Lock
|
|
20
|
-
|
|
21
18
|
try:
|
|
22
19
|
import json
|
|
23
20
|
except ImportError:
|
|
@@ -27,22 +24,16 @@ def _convert_keys(dictionary):
|
|
|
27
24
|
if not isinstance(dictionary, dict):
|
|
28
25
|
return dictionary
|
|
29
26
|
return dict((str(k), _convert_keys(v))
|
|
30
|
-
for k, v in dictionary.items())
|
|
27
|
+
for k, v in list(dictionary.items()))
|
|
31
28
|
|
|
32
29
|
def _write_error(error):
|
|
33
30
|
res = {"error": error}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
sys.stdout.write(
|
|
37
|
-
sys.stdout.flush()
|
|
38
|
-
sys.stdout.write(out_header + "\n")
|
|
31
|
+
out_header_bytes = json.dumps(res).encode('utf-8')
|
|
32
|
+
sys.stdout.buffer.write(struct.pack('!i', len(out_header_bytes)))
|
|
33
|
+
sys.stdout.buffer.write(out_header_bytes)
|
|
39
34
|
sys.stdout.flush()
|
|
40
35
|
return
|
|
41
36
|
|
|
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
37
|
def _signal_handler(signal, frame):
|
|
47
38
|
"""
|
|
48
39
|
Handle the signal given in the first argument, exiting gracefully
|
|
@@ -163,12 +154,9 @@ class Mentos(object):
|
|
|
163
154
|
res = json.dumps(res)
|
|
164
155
|
|
|
165
156
|
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
157
|
res = self.highlight_text(text, lexer, formatter_name, args, _convert_keys(opts))
|
|
158
|
+
if type(res) is bytes:
|
|
159
|
+
res = res.decode('utf-8')
|
|
172
160
|
|
|
173
161
|
elif method == 'css':
|
|
174
162
|
kwargs = _convert_keys(kwargs)
|
|
@@ -193,52 +181,21 @@ class Mentos(object):
|
|
|
193
181
|
|
|
194
182
|
|
|
195
183
|
def _send_data(self, res, method):
|
|
196
|
-
|
|
197
184
|
# Base header. We'll build on this, adding keys as necessary.
|
|
198
185
|
base_header = {"method": method}
|
|
199
186
|
|
|
200
|
-
res_bytes =
|
|
201
|
-
|
|
187
|
+
res_bytes = res.encode("utf-8")
|
|
188
|
+
bytes = len(res_bytes)
|
|
189
|
+
base_header["bytes"] = bytes
|
|
202
190
|
|
|
203
|
-
|
|
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)
|
|
191
|
+
out_header_bytes = json.dumps(base_header).encode('utf-8')
|
|
208
192
|
|
|
209
193
|
# Send it to Rubyland
|
|
210
|
-
sys.stdout.write(
|
|
211
|
-
sys.stdout.
|
|
212
|
-
|
|
213
|
-
# Send the header.
|
|
214
|
-
sys.stdout.write(out_header + "\n")
|
|
194
|
+
sys.stdout.buffer.write(struct.pack('!i', len(out_header_bytes)))
|
|
195
|
+
sys.stdout.buffer.write(out_header_bytes)
|
|
196
|
+
sys.stdout.buffer.write(res_bytes)
|
|
215
197
|
sys.stdout.flush()
|
|
216
198
|
|
|
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
199
|
def _parse_header(self, header):
|
|
243
200
|
method = header["method"]
|
|
244
201
|
args = header.get("args", [])
|
|
@@ -256,29 +213,18 @@ class Mentos(object):
|
|
|
256
213
|
pygmentized, this header will be followed by the text to be pygmentized.
|
|
257
214
|
|
|
258
215
|
The header is of form:
|
|
259
|
-
{ "method": "highlight", "args": [], "kwargs": {"arg1": "v"}, "bytes": 128
|
|
216
|
+
{ "method": "highlight", "args": [], "kwargs": {"arg1": "v"}, "bytes": 128}
|
|
260
217
|
"""
|
|
261
|
-
lock = Lock()
|
|
262
218
|
|
|
263
219
|
while True:
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
size = sys.stdin.read(32)
|
|
220
|
+
header_size_bytes = sys.stdin.buffer.read(4)
|
|
221
|
+
if not header_size_bytes:
|
|
222
|
+
break
|
|
268
223
|
|
|
269
|
-
|
|
224
|
+
header_size = struct.unpack('!i', header_size_bytes)[0]
|
|
270
225
|
|
|
271
226
|
try:
|
|
272
|
-
|
|
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
|
-
|
|
227
|
+
line = sys.stdin.buffer.read(header_size).decode('utf-8')
|
|
282
228
|
header = json.loads(line)
|
|
283
229
|
|
|
284
230
|
method, args, kwargs, lexer = self._parse_header(header)
|
|
@@ -291,30 +237,18 @@ class Mentos(object):
|
|
|
291
237
|
if kwargs:
|
|
292
238
|
_bytes = kwargs.get("bytes", 0)
|
|
293
239
|
|
|
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)
|
|
240
|
+
# Read up to the given number of *bytes* (not chars) (possibly 0)
|
|
241
|
+
text = sys.stdin.buffer.read(_bytes).decode('utf-8')
|
|
301
242
|
|
|
302
243
|
# Get the actual data from pygments.
|
|
303
244
|
res = self.get_data(method, lexer, args, kwargs, text)
|
|
304
245
|
|
|
305
|
-
# Put back the sanity check values.
|
|
306
|
-
if method == "highlight":
|
|
307
|
-
res = start_id + " " + res + " " + end_id
|
|
308
|
-
|
|
309
246
|
self._send_data(res, method)
|
|
310
247
|
|
|
311
248
|
except:
|
|
312
249
|
tb = traceback.format_exc()
|
|
313
250
|
_write_error(tb)
|
|
314
251
|
|
|
315
|
-
finally:
|
|
316
|
-
lock.release()
|
|
317
|
-
|
|
318
252
|
def main():
|
|
319
253
|
|
|
320
254
|
# Signal handlers to trap signals.
|
|
@@ -324,28 +258,7 @@ def main():
|
|
|
324
258
|
signal.signal(signal.SIGHUP, _signal_handler)
|
|
325
259
|
|
|
326
260
|
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
261
|
mentos.start()
|
|
346
262
|
|
|
347
263
|
if __name__ == "__main__":
|
|
348
264
|
main()
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
data/lib/pygments/popen.rb
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
# coding: utf-8
|
|
2
1
|
# frozen_string_literal: true
|
|
3
2
|
|
|
3
|
+
require 'json'
|
|
4
4
|
require 'open3'
|
|
5
|
-
require 'multi_json'
|
|
6
|
-
require 'timeout'
|
|
7
5
|
require 'logger'
|
|
8
6
|
require 'time'
|
|
9
7
|
|
|
@@ -15,38 +13,36 @@ end
|
|
|
15
13
|
# Python process.
|
|
16
14
|
module Pygments
|
|
17
15
|
class Popen
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
16
|
+
def popen4(argv)
|
|
17
|
+
stdin, stdout, stderr, wait_thr = Open3.popen3(*argv, { close_others: true })
|
|
18
|
+
while (pid = wait_thr.pid).nil? && wait_thr.alive?
|
|
19
|
+
# For unknown reasons, wait_thr.pid is not immediately available on JRuby
|
|
20
|
+
end
|
|
21
|
+
[pid, stdin, stdout, stderr]
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
# Get things started by opening a pipe to mentos (the freshmaker), a
|
|
25
25
|
# Python process that talks to the Pygments library. We'll talk back and
|
|
26
26
|
# forth across this pipe.
|
|
27
|
-
def start(pygments_path = File.expand_path('
|
|
27
|
+
def start(pygments_path = File.expand_path('../../vendor/pygments-main', __dir__))
|
|
28
28
|
begin
|
|
29
|
-
@log = Logger.new(ENV['MENTOS_LOG']
|
|
29
|
+
@log = Logger.new(ENV['MENTOS_LOG'] || File::NULL)
|
|
30
30
|
@log.level = Logger::INFO
|
|
31
|
-
@log.datetime_format =
|
|
32
|
-
rescue
|
|
33
|
-
@log = Logger.new(File::NULL)
|
|
31
|
+
@log.datetime_format = '%Y-%m-%d %H:%M '
|
|
34
32
|
end
|
|
35
33
|
|
|
36
34
|
ENV['PYGMENTS_PATH'] = pygments_path
|
|
37
35
|
|
|
38
36
|
# Make sure we kill off the child when we're done
|
|
39
|
-
at_exit { stop
|
|
37
|
+
at_exit { stop 'Exiting' }
|
|
40
38
|
|
|
41
39
|
# A pipe to the mentos python process. #popen4 gives us
|
|
42
40
|
# the pid and three IO objects to write and read.
|
|
43
|
-
|
|
44
|
-
@pid, @in, @out, @err = popen4(
|
|
45
|
-
@
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
def windows?
|
|
49
|
-
RUBY_PLATFORM =~ /mswin|mingw/
|
|
41
|
+
argv = [*python_binary, File.expand_path('mentos.py', __dir__)]
|
|
42
|
+
@pid, @in, @out, @err = popen4(argv)
|
|
43
|
+
@in.binmode
|
|
44
|
+
@out.binmode
|
|
45
|
+
@log.info "Starting pid #{@pid} with python #{python_binary}."
|
|
50
46
|
end
|
|
51
47
|
|
|
52
48
|
def python_binary
|
|
@@ -58,14 +54,13 @@ module Pygments
|
|
|
58
54
|
end
|
|
59
55
|
|
|
60
56
|
# Detect a suitable Python binary to use.
|
|
61
|
-
# Or return $PYGMENTS_RB_PYTHON if it's exists.
|
|
62
57
|
def find_python_binary
|
|
63
|
-
if
|
|
64
|
-
return which(
|
|
65
|
-
elsif windows? && which('py')
|
|
66
|
-
return 'py -2'
|
|
58
|
+
if Gem.win_platform?
|
|
59
|
+
return %w[py python3 python].first { |py| !which(py).nil? }
|
|
67
60
|
end
|
|
68
|
-
|
|
61
|
+
|
|
62
|
+
# On non-Windows platforms, we simply rely on shebang
|
|
63
|
+
[]
|
|
69
64
|
end
|
|
70
65
|
|
|
71
66
|
# Cross platform which command
|
|
@@ -73,12 +68,12 @@ module Pygments
|
|
|
73
68
|
def which(command)
|
|
74
69
|
exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
|
|
75
70
|
ENV['PATH'].split(File::PATH_SEPARATOR).each do |dir|
|
|
76
|
-
exts.each
|
|
71
|
+
exts.each do |ext|
|
|
77
72
|
path = File.join(dir, "#{command}#{ext}")
|
|
78
73
|
return path if File.executable?(path) && !File.directory?(path)
|
|
79
|
-
|
|
74
|
+
end
|
|
80
75
|
end
|
|
81
|
-
|
|
76
|
+
nil
|
|
82
77
|
end
|
|
83
78
|
|
|
84
79
|
# Stop the child process by issuing a kill -9.
|
|
@@ -94,14 +89,14 @@ module Pygments
|
|
|
94
89
|
# the signal isn't sent); but we have permissions, and
|
|
95
90
|
# we're not doing anything invalid here.
|
|
96
91
|
def stop(reason)
|
|
97
|
-
|
|
92
|
+
unless @pid.nil?
|
|
93
|
+
@log.info "Killing pid: #{@pid}. Reason: #{reason}"
|
|
98
94
|
begin
|
|
99
95
|
Process.kill('KILL', @pid)
|
|
100
96
|
Process.waitpid(@pid)
|
|
101
97
|
rescue Errno::ESRCH, Errno::ECHILD
|
|
102
98
|
end
|
|
103
99
|
end
|
|
104
|
-
@log.info "Killing pid: #{@pid.to_s}. Reason: #{reason}"
|
|
105
100
|
@pid = nil
|
|
106
101
|
end
|
|
107
102
|
|
|
@@ -116,30 +111,29 @@ module Pygments
|
|
|
116
111
|
# Returns true if the child is alive.
|
|
117
112
|
def alive?
|
|
118
113
|
return true if defined?(@pid) && @pid && Process.kill(0, @pid)
|
|
114
|
+
|
|
119
115
|
false
|
|
120
116
|
rescue Errno::ENOENT, Errno::ESRCH
|
|
121
117
|
false
|
|
122
118
|
rescue Errno::EPERM
|
|
123
|
-
raise MentosError,
|
|
119
|
+
raise MentosError, 'EPERM checking if child process is alive.'
|
|
124
120
|
end
|
|
125
121
|
|
|
126
122
|
# Public: Get an array of available Pygments formatters
|
|
127
123
|
#
|
|
128
124
|
# Returns an array of formatters.
|
|
129
125
|
def formatters
|
|
130
|
-
mentos(:get_all_formatters).
|
|
126
|
+
mentos(:get_all_formatters).each_with_object({}) do |(name, desc, aliases), hash|
|
|
131
127
|
# Remove the long-winded and repetitive 'Formatter' suffix
|
|
132
128
|
name.sub!(/Formatter$/, '')
|
|
133
129
|
hash[name] = {
|
|
134
|
-
:
|
|
135
|
-
:
|
|
136
|
-
:
|
|
130
|
+
name: name,
|
|
131
|
+
description: desc,
|
|
132
|
+
aliases: aliases
|
|
137
133
|
}
|
|
138
|
-
hash
|
|
139
134
|
end
|
|
140
135
|
end
|
|
141
136
|
|
|
142
|
-
|
|
143
137
|
# Public: Get all lexers from a serialized array. This avoids needing to spawn
|
|
144
138
|
# mentos when it's not really needed (e.g., one-off jobs, loading the Rails env, etc).
|
|
145
139
|
#
|
|
@@ -147,33 +141,25 @@ module Pygments
|
|
|
147
141
|
#
|
|
148
142
|
# Returns an array of lexers.
|
|
149
143
|
def lexers
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
raise MentosError, "Error loading lexer file. Was it created and vendored?"
|
|
156
|
-
end
|
|
144
|
+
lexer_file = File.expand_path('../../lexers', __dir__)
|
|
145
|
+
raw = File.open(lexer_file, 'rb').read
|
|
146
|
+
Marshal.load(raw)
|
|
147
|
+
rescue Errno::ENOENT
|
|
148
|
+
raise MentosError, 'Error loading lexer file. Was it created and vendored?'
|
|
157
149
|
end
|
|
158
150
|
|
|
159
151
|
# Public: Get back all available lexers from mentos itself
|
|
160
152
|
#
|
|
161
153
|
# Returns an array of lexers.
|
|
162
154
|
def lexers!
|
|
163
|
-
mentos(:get_all_lexers).
|
|
155
|
+
mentos(:get_all_lexers).each_with_object({}) do |lxr, hash|
|
|
164
156
|
name = lxr[0]
|
|
165
157
|
hash[name] = {
|
|
166
|
-
:
|
|
167
|
-
:
|
|
168
|
-
:
|
|
169
|
-
:
|
|
158
|
+
name: name,
|
|
159
|
+
aliases: lxr[1],
|
|
160
|
+
filenames: lxr[2],
|
|
161
|
+
mimetypes: lxr[3]
|
|
170
162
|
}
|
|
171
|
-
hash["dasm16"] = {:name=>"dasm16", :aliases=>["DASM16"], :filenames=>["*.dasm16", "*.dasm"], :mimetypes=>['text/x-dasm16']}
|
|
172
|
-
hash["Puppet"] = {:name=>"Puppet", :aliases=>["puppet"], :filenames=>["*.pp"], :mimetypes=>[]}
|
|
173
|
-
hash["Augeas"] = {:name=>"Augeas", :aliases=>["augeas"], :filenames=>["*.aug"], :mimetypes=>[]}
|
|
174
|
-
hash["TOML"] = {:name=>"TOML", :aliases=>["toml"], :filenames=>["*.toml"], :mimetypes=>[]}
|
|
175
|
-
hash["Slash"] = {:name=>"Slash", :aliases=>["slash"], :filenames=>["*.sl"], :mimetypes=>[]}
|
|
176
|
-
hash
|
|
177
163
|
end
|
|
178
164
|
end
|
|
179
165
|
|
|
@@ -188,7 +174,7 @@ module Pygments
|
|
|
188
174
|
end
|
|
189
175
|
|
|
190
176
|
# Public: Return css for highlighted code
|
|
191
|
-
def css(klass='', opts={})
|
|
177
|
+
def css(klass = '', opts = {})
|
|
192
178
|
if klass.is_a?(Hash)
|
|
193
179
|
opts = klass
|
|
194
180
|
klass = ''
|
|
@@ -199,17 +185,13 @@ module Pygments
|
|
|
199
185
|
# Public: Return the name of a lexer.
|
|
200
186
|
def lexer_name_for(*args)
|
|
201
187
|
# Pop off the last arg if it's a hash, which becomes our opts
|
|
202
|
-
if args.last.is_a?(Hash)
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
188
|
+
opts = if args.last.is_a?(Hash)
|
|
189
|
+
args.pop
|
|
190
|
+
else
|
|
191
|
+
{}
|
|
192
|
+
end
|
|
207
193
|
|
|
208
|
-
if args.last.is_a?(String)
|
|
209
|
-
code = args.pop
|
|
210
|
-
else
|
|
211
|
-
code = nil
|
|
212
|
-
end
|
|
194
|
+
code = (args.pop if args.last.is_a?(String))
|
|
213
195
|
|
|
214
196
|
mentos(:lexer_name_for, args, opts, code)
|
|
215
197
|
end
|
|
@@ -221,7 +203,7 @@ module Pygments
|
|
|
221
203
|
#
|
|
222
204
|
# Returns the highlighted string
|
|
223
205
|
# or nil when the request to the Python process timed out.
|
|
224
|
-
def highlight(code, opts={})
|
|
206
|
+
def highlight(code, opts = {})
|
|
225
207
|
# If the caller didn't give us any code, we have nothing to do,
|
|
226
208
|
# so return right away.
|
|
227
209
|
return code if code.nil? || code.empty?
|
|
@@ -234,191 +216,142 @@ module Pygments
|
|
|
234
216
|
|
|
235
217
|
# Get back the string from mentos and force encoding if we can
|
|
236
218
|
str = mentos(:highlight, nil, opts, code)
|
|
237
|
-
|
|
219
|
+
if str.respond_to?(:force_encoding)
|
|
220
|
+
str.force_encoding(opts[:options][:outencoding])
|
|
221
|
+
end
|
|
238
222
|
str
|
|
239
223
|
end
|
|
240
224
|
|
|
241
225
|
private
|
|
242
226
|
|
|
227
|
+
def with_watchdog(timeout_time, error_message)
|
|
228
|
+
state_mutex = Mutex.new
|
|
229
|
+
state = :alive
|
|
230
|
+
wd_cleanup = ConditionVariable.new
|
|
231
|
+
|
|
232
|
+
watchdog = timeout_time > 0 ? Thread.new do
|
|
233
|
+
state_mutex.synchronize do
|
|
234
|
+
wd_cleanup.wait(state_mutex, timeout_time) if state != :finished
|
|
235
|
+
if state != :finished
|
|
236
|
+
@log.error error_message
|
|
237
|
+
stop error_message
|
|
238
|
+
state = :timeout
|
|
239
|
+
end
|
|
240
|
+
end
|
|
241
|
+
end : nil
|
|
242
|
+
begin
|
|
243
|
+
yield
|
|
244
|
+
ensure
|
|
245
|
+
if watchdog
|
|
246
|
+
state_mutex.synchronize do
|
|
247
|
+
state = :finished if state == :alive
|
|
248
|
+
# wake up watchdog thread
|
|
249
|
+
wd_cleanup.signal
|
|
250
|
+
end
|
|
251
|
+
watchdog.join
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
raise MentosError, error_message if state == :timeout
|
|
255
|
+
end
|
|
256
|
+
end
|
|
257
|
+
|
|
243
258
|
# Our 'rpc'-ish request to mentos. Requires a method name, and then optional
|
|
244
259
|
# args, kwargs, code.
|
|
245
|
-
def mentos(method, args=[], kwargs={},
|
|
260
|
+
def mentos(method, args = [], kwargs = {}, code = nil)
|
|
246
261
|
# Open the pipe if necessary
|
|
247
262
|
start unless alive?
|
|
248
263
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
code = add_ids(original_code, id) if original_code
|
|
260
|
-
|
|
261
|
-
# Add metadata to the header and generate it.
|
|
262
|
-
if code
|
|
263
|
-
bytesize = code.bytesize
|
|
264
|
-
else
|
|
265
|
-
bytesize = 0
|
|
266
|
-
end
|
|
264
|
+
# Timeout requests that take too long.
|
|
265
|
+
# Invalid MENTOS_TIMEOUT results in just using default.
|
|
266
|
+
timeout_time = kwargs.delete(:timeout)
|
|
267
|
+
if timeout_time.nil?
|
|
268
|
+
timeout_time = begin
|
|
269
|
+
Integer(ENV['MENTOS_TIMEOUT'])
|
|
270
|
+
rescue TypeError
|
|
271
|
+
0
|
|
272
|
+
end
|
|
273
|
+
end
|
|
267
274
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
275
|
+
# Add metadata to the header and generate it.
|
|
276
|
+
bytesize = if code
|
|
277
|
+
code.bytesize
|
|
278
|
+
else
|
|
279
|
+
0
|
|
280
|
+
end
|
|
271
281
|
|
|
282
|
+
kwargs.freeze
|
|
283
|
+
kwargs = kwargs.merge('bytes' => bytesize)
|
|
284
|
+
out_header = JSON.generate(method: method, args: args, kwargs: kwargs)
|
|
285
|
+
|
|
286
|
+
begin
|
|
287
|
+
res = with_watchdog(timeout_time, "Timeout on a mentos #{method} call") do
|
|
272
288
|
# Get the size of the header itself and write that.
|
|
273
|
-
|
|
274
|
-
@
|
|
289
|
+
@in.write([out_header.bytesize].pack('N'))
|
|
290
|
+
@log.info "Size out: #{out_header.bytesize}"
|
|
275
291
|
|
|
276
292
|
# mentos is now waiting for the header, and, potentially, code.
|
|
277
|
-
|
|
293
|
+
@in.write(out_header)
|
|
294
|
+
@log.info "Out header: #{out_header}"
|
|
295
|
+
@in.write(code) unless code.nil?
|
|
278
296
|
|
|
279
|
-
|
|
297
|
+
@in.flush
|
|
280
298
|
|
|
281
299
|
# mentos will now return data to us. First it sends the header.
|
|
282
|
-
header = get_header
|
|
283
300
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
return_result(res, method)
|
|
289
|
-
end
|
|
290
|
-
rescue Timeout::Error
|
|
291
|
-
# If we timeout, we need to clear out the pipe and start over.
|
|
292
|
-
@log.error "Timeout on a mentos #{method} call"
|
|
293
|
-
stop "Timeout on mentos #{method} call."
|
|
294
|
-
end
|
|
295
|
-
|
|
296
|
-
rescue Errno::EPIPE, EOFError
|
|
297
|
-
stop "EPIPE"
|
|
298
|
-
raise MentosError, "EPIPE"
|
|
299
|
-
end
|
|
300
|
-
|
|
301
|
-
def check_for_error
|
|
302
|
-
return if @err.closed?
|
|
301
|
+
header_len_bytes = @out.read(4)
|
|
302
|
+
if header_len_bytes.nil?
|
|
303
|
+
raise Errno::EPIPE, %(Failed to read response from Python process on a mentos #{method} call)
|
|
304
|
+
end
|
|
303
305
|
|
|
304
|
-
|
|
306
|
+
header_len = header_len_bytes.unpack('N')[0]
|
|
307
|
+
@log.info "Size in: #{header_len}"
|
|
308
|
+
header = @out.read(header_len)
|
|
305
309
|
|
|
306
|
-
|
|
307
|
-
|
|
310
|
+
# Now handle the header, any read any more data required.
|
|
311
|
+
handle_header_and_return(header)
|
|
312
|
+
end
|
|
308
313
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
314
|
+
# Finally, return what we got.
|
|
315
|
+
return_result(res, method)
|
|
316
|
+
rescue Errno::EPIPE => e
|
|
317
|
+
begin
|
|
318
|
+
error_msg = @err.read
|
|
319
|
+
@log.error "Error running Python script: #{error_msg}"
|
|
320
|
+
stop "Error running Python script: #{error_msg}"
|
|
321
|
+
raise MentosError, %(#{e}: #{error_msg})
|
|
322
|
+
rescue Errno::EPIPE
|
|
323
|
+
@log.error e.to_s
|
|
324
|
+
stop e.to_s
|
|
325
|
+
raise e
|
|
313
326
|
end
|
|
327
|
+
rescue StandardError => e
|
|
328
|
+
@log.error e.to_s
|
|
329
|
+
stop e.to_s
|
|
330
|
+
raise e
|
|
314
331
|
end
|
|
315
|
-
rescue Timeout::Error
|
|
316
|
-
# during the specified time no error were found
|
|
317
|
-
@err.close
|
|
318
332
|
end
|
|
319
333
|
|
|
320
|
-
|
|
321
334
|
# Based on the header we receive, determine if we need
|
|
322
335
|
# to read more bytes, and read those bytes if necessary.
|
|
323
336
|
#
|
|
324
|
-
#
|
|
325
|
-
|
|
326
|
-
# Returns a result — either highlighted text or metadata.
|
|
327
|
-
def handle_header_and_return(header, id)
|
|
337
|
+
# Returns a result - either highlighted text or metadata.
|
|
338
|
+
def handle_header_and_return(header)
|
|
328
339
|
if header
|
|
340
|
+
@log.info "In header: #{header}"
|
|
329
341
|
header = header_to_json(header)
|
|
330
342
|
bytes = header[:bytes]
|
|
331
343
|
|
|
332
344
|
# Read more bytes (the actual response body)
|
|
333
345
|
res = @out.read(bytes.to_i)
|
|
334
346
|
|
|
335
|
-
if header[:method] ==
|
|
347
|
+
if header[:method] == 'highlight'
|
|
336
348
|
# Make sure we have a result back; else consider this an error.
|
|
337
|
-
if res.nil?
|
|
338
|
-
@log.warn "No highlight result back from mentos."
|
|
339
|
-
stop "No highlight result back from mentos."
|
|
340
|
-
raise MentosError, "No highlight result back from mentos."
|
|
341
|
-
end
|
|
342
|
-
|
|
343
|
-
# Remove the newline from Python
|
|
344
|
-
res = res[0..-2]
|
|
345
|
-
@log.info "Highlight in process."
|
|
346
|
-
|
|
347
|
-
# Get the id's
|
|
348
|
-
start_id = res[0..7]
|
|
349
|
-
end_id = res[-8..-1]
|
|
350
|
-
|
|
351
|
-
# Sanity check.
|
|
352
|
-
if not (start_id == id and end_id == id)
|
|
353
|
-
@log.error "ID's did not match. Aborting."
|
|
354
|
-
stop "ID's did not match. Aborting."
|
|
355
|
-
raise MentosError, "ID's did not match. Aborting."
|
|
356
|
-
else
|
|
357
|
-
# We're good. Remove the padding
|
|
358
|
-
res = res[10..-11]
|
|
359
|
-
@log.info "Highlighting complete."
|
|
360
|
-
res
|
|
361
|
-
end
|
|
349
|
+
raise MentosError, 'No highlight result back from mentos.' if res.nil?
|
|
362
350
|
end
|
|
363
|
-
res
|
|
364
|
-
else
|
|
365
|
-
@log.error "No header data back."
|
|
366
|
-
stop "No header data back."
|
|
367
|
-
raise MentosError, "No header received back."
|
|
368
|
-
end
|
|
369
|
-
end
|
|
370
351
|
|
|
371
|
-
|
|
372
|
-
# the following text starts with a slash (like terminal code), and append the
|
|
373
|
-
# id, with two padding also. This means we are sending over the 8 characters +
|
|
374
|
-
# code + 8 characters.
|
|
375
|
-
def add_ids(code, id)
|
|
376
|
-
(id + " #{code} #{id}").freeze
|
|
377
|
-
end
|
|
378
|
-
|
|
379
|
-
# Write data to mentos, the Python process.
|
|
380
|
-
#
|
|
381
|
-
# Returns nothing.
|
|
382
|
-
def write_data(out_header, code=nil)
|
|
383
|
-
@in.write(out_header)
|
|
384
|
-
@log.info "Out header: #{out_header}"
|
|
385
|
-
@in.write(code) if code
|
|
386
|
-
end
|
|
387
|
-
|
|
388
|
-
# Sanity check for size (32-arity of 0's and 1's)
|
|
389
|
-
def size_check(size)
|
|
390
|
-
size_regex = /[0-1]{32}/
|
|
391
|
-
if size_regex.match(size)
|
|
392
|
-
true
|
|
352
|
+
res
|
|
393
353
|
else
|
|
394
|
-
|
|
395
|
-
end
|
|
396
|
-
end
|
|
397
|
-
|
|
398
|
-
# Read the header via the pipe.
|
|
399
|
-
#
|
|
400
|
-
# Returns a header.
|
|
401
|
-
def get_header
|
|
402
|
-
begin
|
|
403
|
-
size = @out.read(33)
|
|
404
|
-
size = size[0..-2]
|
|
405
|
-
|
|
406
|
-
# Sanity check the size
|
|
407
|
-
if not size_check(size)
|
|
408
|
-
@log.error "Size returned from mentos.py invalid."
|
|
409
|
-
stop "Size returned from mentos.py invalid."
|
|
410
|
-
raise MentosError, "Size returned from mentos.py invalid."
|
|
411
|
-
end
|
|
412
|
-
|
|
413
|
-
# Read the amount of bytes we should be expecting. We first
|
|
414
|
-
# convert the string of bits into an integer.
|
|
415
|
-
header_bytes = size.to_s.to_i(2) + 1
|
|
416
|
-
@log.info "Size in: #{size.to_s} (#{header_bytes.to_s})"
|
|
417
|
-
@out.read(header_bytes)
|
|
418
|
-
rescue
|
|
419
|
-
@log.error "Failed to get header."
|
|
420
|
-
stop "Failed to get header."
|
|
421
|
-
raise MentosError, "Failed to get header."
|
|
354
|
+
raise MentosError, 'No header received back.'
|
|
422
355
|
end
|
|
423
356
|
end
|
|
424
357
|
|
|
@@ -426,7 +359,7 @@ module Pygments
|
|
|
426
359
|
# want them, text otherwise.
|
|
427
360
|
def return_result(res, method)
|
|
428
361
|
unless method == :lexer_name_for || method == :highlight || method == :css
|
|
429
|
-
res =
|
|
362
|
+
res = JSON.parse(res, symbolize_names: true)
|
|
430
363
|
end
|
|
431
364
|
res = res.rstrip if res.class == String
|
|
432
365
|
res
|
|
@@ -434,27 +367,13 @@ module Pygments
|
|
|
434
367
|
|
|
435
368
|
# Convert a text header into JSON for easy access.
|
|
436
369
|
def header_to_json(header)
|
|
437
|
-
|
|
438
|
-
header = MultiJson.load(header, :symbolize_keys => true)
|
|
370
|
+
header = JSON.parse(header, symbolize_names: true)
|
|
439
371
|
|
|
440
372
|
if header[:error]
|
|
441
|
-
# Raise this as a Ruby exception of the MentosError class.
|
|
442
|
-
# Stop so we don't leave the pipe in an inconsistent state.
|
|
443
|
-
@log.error "Failed to convert header to JSON."
|
|
444
|
-
stop header[:error]
|
|
445
373
|
raise MentosError, header[:error]
|
|
446
374
|
else
|
|
447
375
|
header
|
|
448
376
|
end
|
|
449
377
|
end
|
|
450
|
-
|
|
451
|
-
def get_fixed_bits_from_header(out_header)
|
|
452
|
-
size = out_header.bytesize
|
|
453
|
-
|
|
454
|
-
# Fixed 32 bits to represent the int. We return a string
|
|
455
|
-
# representation: e.g, "00000000000000000000000000011110"
|
|
456
|
-
Array.new(32) { |i| size[i] }.reverse!.join
|
|
457
|
-
end
|
|
458
378
|
end
|
|
459
379
|
end
|
|
460
|
-
|