pygments.rb 2.0.0.rc3 → 2.3.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 +4 -4
- data/.github/workflows/ci.yml +13 -1
- data/.gitignore +0 -1
- data/.rubocop.yml +16 -0
- data/CHANGELOG.adoc +19 -0
- data/README.adoc +1 -3
- data/Rakefile +0 -14
- data/bench.rb +11 -6
- data/lib/pygments/lexer.rb +84 -62
- data/lib/pygments/mentos.py +7 -49
- data/lib/pygments/popen.rb +133 -173
- data/lib/pygments/version.rb +1 -1
- data/lib/pygments.rb +15 -6
- data/pygments.rb.gemspec +16 -11
- data/test/test_pygments.rb +19 -40
- data/vendor/pygments-main/{Pygments-2.7.3.dist-info → Pygments-2.10.0.dist-info}/AUTHORS +13 -1
- data/vendor/pygments-main/{Pygments-2.7.3.dist-info → Pygments-2.10.0.dist-info}/INSTALLER +0 -0
- data/vendor/pygments-main/{Pygments-2.7.3.dist-info → Pygments-2.10.0.dist-info}/LICENSE +1 -1
- data/vendor/pygments-main/{Pygments-2.7.3.dist-info → Pygments-2.10.0.dist-info}/METADATA +8 -9
- data/vendor/pygments-main/Pygments-2.10.0.dist-info/RECORD +524 -0
- data/vendor/pygments-main/{Pygments-2.7.3.dist-info → Pygments-2.10.0.dist-info}/REQUESTED +0 -0
- data/vendor/pygments-main/{Pygments-2.7.3.dist-info → Pygments-2.10.0.dist-info}/WHEEL +0 -0
- data/vendor/pygments-main/{Pygments-2.7.3.dist-info → Pygments-2.10.0.dist-info}/entry_points.txt +0 -0
- data/vendor/pygments-main/{Pygments-2.7.3.dist-info → Pygments-2.10.0.dist-info}/top_level.txt +0 -0
- data/vendor/pygments-main/bin/pygmentize +1 -1
- data/vendor/pygments-main/pygments/__init__.py +2 -3
- data/vendor/pygments-main/pygments/__main__.py +1 -2
- data/vendor/pygments-main/pygments/cmdline.py +179 -159
- data/vendor/pygments-main/pygments/console.py +1 -2
- data/vendor/pygments-main/pygments/filter.py +1 -2
- data/vendor/pygments-main/pygments/filters/__init__.py +1 -2
- data/vendor/pygments-main/pygments/formatter.py +1 -2
- data/vendor/pygments-main/pygments/formatters/__init__.py +2 -3
- data/vendor/pygments-main/pygments/formatters/_mapping.py +2 -2
- data/vendor/pygments-main/pygments/formatters/bbcode.py +1 -2
- data/vendor/pygments-main/pygments/formatters/html.py +53 -25
- data/vendor/pygments-main/pygments/formatters/img.py +24 -10
- data/vendor/pygments-main/pygments/formatters/irc.py +1 -2
- data/vendor/pygments-main/pygments/formatters/latex.py +8 -9
- data/vendor/pygments-main/pygments/formatters/other.py +7 -10
- data/vendor/pygments-main/pygments/formatters/pangomarkup.py +83 -0
- data/vendor/pygments-main/pygments/formatters/rtf.py +1 -2
- data/vendor/pygments-main/pygments/formatters/svg.py +5 -4
- data/vendor/pygments-main/pygments/formatters/terminal.py +1 -2
- data/vendor/pygments-main/pygments/formatters/terminal256.py +24 -3
- data/vendor/pygments-main/pygments/lexer.py +7 -6
- data/vendor/pygments-main/pygments/lexers/__init__.py +2 -3
- data/vendor/pygments-main/pygments/lexers/_asy_builtins.py +1 -2
- data/vendor/pygments-main/pygments/lexers/_cl_builtins.py +1 -2
- data/vendor/pygments-main/pygments/lexers/_cocoa_builtins.py +16 -12
- data/vendor/pygments-main/pygments/lexers/_csound_builtins.py +56 -16
- data/vendor/pygments-main/pygments/lexers/_julia_builtins.py +401 -0
- data/vendor/pygments-main/pygments/lexers/_lasso_builtins.py +1 -2
- data/vendor/pygments-main/pygments/lexers/_lua_builtins.py +1 -2
- data/vendor/pygments-main/pygments/lexers/_mapping.py +73 -54
- data/vendor/pygments-main/pygments/lexers/_mql_builtins.py +1 -2
- data/vendor/pygments-main/pygments/lexers/_mysql_builtins.py +2 -3
- data/vendor/pygments-main/pygments/lexers/_openedge_builtins.py +439 -386
- data/vendor/pygments-main/pygments/lexers/_php_builtins.py +1 -2
- data/vendor/pygments-main/pygments/lexers/_postgres_builtins.py +1 -2
- data/vendor/pygments-main/pygments/lexers/_scilab_builtins.py +1 -2
- data/vendor/pygments-main/pygments/lexers/_sourcemod_builtins.py +1 -2
- data/vendor/pygments-main/pygments/lexers/_stan_builtins.py +1 -2
- data/vendor/pygments-main/pygments/lexers/_stata_builtins.py +91 -55
- data/vendor/pygments-main/pygments/lexers/_tsql_builtins.py +1 -2
- data/vendor/pygments-main/pygments/lexers/_usd_builtins.py +1 -2
- data/vendor/pygments-main/pygments/lexers/_vbscript_builtins.py +1 -2
- data/vendor/pygments-main/pygments/lexers/_vim_builtins.py +1 -2
- data/vendor/pygments-main/pygments/lexers/actionscript.py +9 -10
- data/vendor/pygments-main/pygments/lexers/agile.py +1 -2
- data/vendor/pygments-main/pygments/lexers/algebra.py +1 -2
- data/vendor/pygments-main/pygments/lexers/ambient.py +3 -4
- data/vendor/pygments-main/pygments/lexers/amdgpu.py +53 -0
- data/vendor/pygments-main/pygments/lexers/ampl.py +1 -2
- data/vendor/pygments-main/pygments/lexers/apdlexer.py +448 -0
- data/vendor/pygments-main/pygments/lexers/apl.py +7 -5
- data/vendor/pygments-main/pygments/lexers/archetype.py +2 -3
- data/vendor/pygments-main/pygments/lexers/arrow.py +1 -2
- data/vendor/pygments-main/pygments/lexers/asc.py +51 -0
- data/vendor/pygments-main/pygments/lexers/asm.py +87 -60
- data/vendor/pygments-main/pygments/lexers/automation.py +8 -3
- data/vendor/pygments-main/pygments/lexers/bare.py +1 -2
- data/vendor/pygments-main/pygments/lexers/basic.py +3 -4
- data/vendor/pygments-main/pygments/lexers/bibtex.py +3 -4
- data/vendor/pygments-main/pygments/lexers/boa.py +4 -5
- data/vendor/pygments-main/pygments/lexers/business.py +3 -4
- data/vendor/pygments-main/pygments/lexers/c_cpp.py +61 -36
- data/vendor/pygments-main/pygments/lexers/c_like.py +103 -5
- data/vendor/pygments-main/pygments/lexers/capnproto.py +1 -2
- data/vendor/pygments-main/pygments/lexers/cddl.py +190 -0
- data/vendor/pygments-main/pygments/lexers/chapel.py +52 -29
- data/vendor/pygments-main/pygments/lexers/clean.py +7 -8
- data/vendor/pygments-main/pygments/lexers/compiled.py +1 -2
- data/vendor/pygments-main/pygments/lexers/configs.py +139 -48
- data/vendor/pygments-main/pygments/lexers/console.py +1 -2
- data/vendor/pygments-main/pygments/lexers/crystal.py +53 -79
- data/vendor/pygments-main/pygments/lexers/csound.py +3 -4
- data/vendor/pygments-main/pygments/lexers/css.py +11 -8
- data/vendor/pygments-main/pygments/lexers/d.py +3 -4
- data/vendor/pygments-main/pygments/lexers/dalvik.py +1 -2
- data/vendor/pygments-main/pygments/lexers/data.py +2 -3
- data/vendor/pygments-main/pygments/lexers/devicetree.py +2 -3
- data/vendor/pygments-main/pygments/lexers/diff.py +1 -2
- data/vendor/pygments-main/pygments/lexers/dotnet.py +7 -8
- data/vendor/pygments-main/pygments/lexers/dsls.py +3 -4
- data/vendor/pygments-main/pygments/lexers/dylan.py +1 -2
- data/vendor/pygments-main/pygments/lexers/ecl.py +4 -6
- data/vendor/pygments-main/pygments/lexers/eiffel.py +2 -3
- data/vendor/pygments-main/pygments/lexers/elm.py +1 -2
- data/vendor/pygments-main/pygments/lexers/email.py +1 -2
- data/vendor/pygments-main/pygments/lexers/erlang.py +2 -3
- data/vendor/pygments-main/pygments/lexers/esoteric.py +1 -2
- data/vendor/pygments-main/pygments/lexers/ezhil.py +1 -2
- data/vendor/pygments-main/pygments/lexers/factor.py +3 -4
- data/vendor/pygments-main/pygments/lexers/fantom.py +1 -2
- data/vendor/pygments-main/pygments/lexers/felix.py +1 -2
- data/vendor/pygments-main/pygments/lexers/floscript.py +2 -3
- data/vendor/pygments-main/pygments/lexers/forth.py +2 -3
- data/vendor/pygments-main/pygments/lexers/fortran.py +9 -7
- data/vendor/pygments-main/pygments/lexers/foxpro.py +1 -2
- data/vendor/pygments-main/pygments/lexers/freefem.py +1 -2
- data/vendor/pygments-main/pygments/lexers/functional.py +1 -2
- data/vendor/pygments-main/pygments/lexers/futhark.py +111 -0
- data/vendor/pygments-main/pygments/lexers/gcodelexer.py +36 -0
- data/vendor/pygments-main/pygments/lexers/gdscript.py +1 -2
- data/vendor/pygments-main/pygments/lexers/go.py +3 -4
- data/vendor/pygments-main/pygments/lexers/grammar_notation.py +1 -2
- data/vendor/pygments-main/pygments/lexers/graph.py +1 -2
- data/vendor/pygments-main/pygments/lexers/graphics.py +4 -5
- data/vendor/pygments-main/pygments/lexers/graphviz.py +58 -0
- data/vendor/pygments-main/pygments/lexers/gsql.py +92 -0
- data/vendor/pygments-main/pygments/lexers/haskell.py +5 -6
- data/vendor/pygments-main/pygments/lexers/haxe.py +4 -5
- data/vendor/pygments-main/pygments/lexers/hdl.py +2 -6
- data/vendor/pygments-main/pygments/lexers/hexdump.py +1 -2
- data/vendor/pygments-main/pygments/lexers/html.py +7 -8
- data/vendor/pygments-main/pygments/lexers/idl.py +1 -2
- data/vendor/pygments-main/pygments/lexers/igor.py +1 -2
- data/vendor/pygments-main/pygments/lexers/inferno.py +1 -2
- data/vendor/pygments-main/pygments/lexers/installers.py +3 -4
- data/vendor/pygments-main/pygments/lexers/int_fiction.py +1 -2
- data/vendor/pygments-main/pygments/lexers/iolang.py +2 -3
- data/vendor/pygments-main/pygments/lexers/j.py +2 -3
- data/vendor/pygments-main/pygments/lexers/javascript.py +170 -156
- data/vendor/pygments-main/pygments/lexers/jslt.py +94 -0
- data/vendor/pygments-main/pygments/lexers/julia.py +136 -185
- data/vendor/pygments-main/pygments/lexers/jvm.py +433 -307
- data/vendor/pygments-main/pygments/lexers/kuin.py +299 -0
- data/vendor/pygments-main/pygments/lexers/lisp.py +25 -23
- data/vendor/pygments-main/pygments/lexers/make.py +3 -4
- data/vendor/pygments-main/pygments/lexers/markup.py +13 -16
- data/vendor/pygments-main/pygments/lexers/math.py +1 -2
- data/vendor/pygments-main/pygments/lexers/matlab.py +2666 -93
- data/vendor/pygments-main/pygments/lexers/meson.py +155 -0
- data/vendor/pygments-main/pygments/lexers/mime.py +7 -23
- data/vendor/pygments-main/pygments/lexers/ml.py +8 -9
- data/vendor/pygments-main/pygments/lexers/modeling.py +1 -2
- data/vendor/pygments-main/pygments/lexers/modula2.py +3 -4
- data/vendor/pygments-main/pygments/lexers/monte.py +1 -2
- data/vendor/pygments-main/pygments/lexers/mosel.py +1 -2
- data/vendor/pygments-main/pygments/lexers/ncl.py +1 -2
- data/vendor/pygments-main/pygments/lexers/nimrod.py +2 -3
- data/vendor/pygments-main/pygments/lexers/nit.py +1 -2
- data/vendor/pygments-main/pygments/lexers/nix.py +1 -2
- data/vendor/pygments-main/pygments/lexers/oberon.py +1 -2
- data/vendor/pygments-main/pygments/lexers/objective.py +6 -7
- data/vendor/pygments-main/pygments/lexers/ooc.py +1 -2
- data/vendor/pygments-main/pygments/lexers/other.py +1 -2
- data/vendor/pygments-main/pygments/lexers/parasail.py +1 -2
- data/vendor/pygments-main/pygments/lexers/parsers.py +26 -27
- data/vendor/pygments-main/pygments/lexers/pascal.py +1 -2
- data/vendor/pygments-main/pygments/lexers/pawn.py +2 -5
- data/vendor/pygments-main/pygments/lexers/perl.py +1 -2
- data/vendor/pygments-main/pygments/lexers/php.py +3 -4
- data/vendor/pygments-main/pygments/lexers/pointless.py +1 -2
- data/vendor/pygments-main/pygments/lexers/pony.py +1 -2
- data/vendor/pygments-main/pygments/lexers/praat.py +1 -2
- data/vendor/pygments-main/pygments/lexers/procfile.py +43 -0
- data/vendor/pygments-main/pygments/lexers/prolog.py +3 -4
- data/vendor/pygments-main/pygments/lexers/promql.py +2 -3
- data/vendor/pygments-main/pygments/lexers/python.py +38 -17
- data/vendor/pygments-main/pygments/lexers/qvt.py +1 -2
- data/vendor/pygments-main/pygments/lexers/r.py +1 -2
- data/vendor/pygments-main/pygments/lexers/rdf.py +1 -2
- data/vendor/pygments-main/pygments/lexers/rebol.py +1 -2
- data/vendor/pygments-main/pygments/lexers/resource.py +2 -3
- data/vendor/pygments-main/pygments/lexers/ride.py +1 -2
- data/vendor/pygments-main/pygments/lexers/rnc.py +2 -3
- data/vendor/pygments-main/pygments/lexers/roboconf.py +1 -2
- data/vendor/pygments-main/pygments/lexers/robotframework.py +1 -2
- data/vendor/pygments-main/pygments/lexers/ruby.py +31 -25
- data/vendor/pygments-main/pygments/lexers/rust.py +10 -12
- data/vendor/pygments-main/pygments/lexers/sas.py +1 -2
- data/vendor/pygments-main/pygments/lexers/scdoc.py +1 -2
- data/vendor/pygments-main/pygments/lexers/scripting.py +12 -13
- data/vendor/pygments-main/pygments/lexers/sgf.py +1 -2
- data/vendor/pygments-main/pygments/lexers/shell.py +15 -17
- data/vendor/pygments-main/pygments/lexers/sieve.py +1 -2
- data/vendor/pygments-main/pygments/lexers/slash.py +1 -2
- data/vendor/pygments-main/pygments/lexers/smalltalk.py +1 -2
- data/vendor/pygments-main/pygments/lexers/smithy.py +79 -0
- data/vendor/pygments-main/pygments/lexers/smv.py +2 -3
- data/vendor/pygments-main/pygments/lexers/snobol.py +1 -2
- data/vendor/pygments-main/pygments/lexers/solidity.py +1 -2
- data/vendor/pygments-main/pygments/lexers/special.py +44 -30
- data/vendor/pygments-main/pygments/lexers/sql.py +8 -13
- data/vendor/pygments-main/pygments/lexers/stata.py +1 -2
- data/vendor/pygments-main/pygments/lexers/supercollider.py +4 -5
- data/vendor/pygments-main/pygments/lexers/tcl.py +4 -5
- data/vendor/pygments-main/pygments/lexers/teal.py +88 -0
- data/vendor/pygments-main/pygments/lexers/templates.py +34 -35
- data/vendor/pygments-main/pygments/lexers/teraterm.py +2 -3
- data/vendor/pygments-main/pygments/lexers/testing.py +2 -3
- data/vendor/pygments-main/pygments/lexers/text.py +1 -2
- data/vendor/pygments-main/pygments/lexers/textedit.py +3 -4
- data/vendor/pygments-main/pygments/lexers/textfmts.py +1 -2
- data/vendor/pygments-main/pygments/lexers/theorem.py +11 -7
- data/vendor/pygments-main/pygments/lexers/thingsdb.py +118 -0
- data/vendor/pygments-main/pygments/lexers/tnt.py +26 -17
- data/vendor/pygments-main/pygments/lexers/trafficscript.py +2 -3
- data/vendor/pygments-main/pygments/lexers/typoscript.py +1 -2
- data/vendor/pygments-main/pygments/lexers/unicon.py +1 -2
- data/vendor/pygments-main/pygments/lexers/urbi.py +3 -4
- data/vendor/pygments-main/pygments/lexers/usd.py +1 -2
- data/vendor/pygments-main/pygments/lexers/varnish.py +2 -3
- data/vendor/pygments-main/pygments/lexers/verification.py +1 -2
- data/vendor/pygments-main/pygments/lexers/web.py +1 -2
- data/vendor/pygments-main/pygments/lexers/webassembly.py +120 -0
- data/vendor/pygments-main/pygments/lexers/webidl.py +1 -2
- data/vendor/pygments-main/pygments/lexers/webmisc.py +5 -5
- data/vendor/pygments-main/pygments/lexers/whiley.py +1 -2
- data/vendor/pygments-main/pygments/lexers/x10.py +2 -3
- data/vendor/pygments-main/pygments/lexers/xorg.py +1 -2
- data/vendor/pygments-main/pygments/lexers/yang.py +1 -2
- data/vendor/pygments-main/pygments/lexers/zig.py +1 -2
- data/vendor/pygments-main/pygments/modeline.py +1 -2
- data/vendor/pygments-main/pygments/plugin.py +2 -3
- data/vendor/pygments-main/pygments/regexopt.py +2 -3
- data/vendor/pygments-main/pygments/scanner.py +1 -2
- data/vendor/pygments-main/pygments/sphinxext.py +1 -2
- data/vendor/pygments-main/pygments/style.py +4 -5
- data/vendor/pygments-main/pygments/styles/__init__.py +5 -2
- data/vendor/pygments-main/pygments/styles/abap.py +1 -2
- data/vendor/pygments-main/pygments/styles/algol.py +1 -2
- data/vendor/pygments-main/pygments/styles/algol_nu.py +1 -2
- data/vendor/pygments-main/pygments/styles/arduino.py +1 -2
- data/vendor/pygments-main/pygments/styles/autumn.py +1 -2
- data/vendor/pygments-main/pygments/styles/borland.py +1 -2
- data/vendor/pygments-main/pygments/styles/bw.py +1 -2
- data/vendor/pygments-main/pygments/styles/colorful.py +1 -2
- data/vendor/pygments-main/pygments/styles/default.py +1 -2
- data/vendor/pygments-main/pygments/styles/emacs.py +1 -2
- data/vendor/pygments-main/pygments/styles/friendly.py +2 -2
- data/vendor/pygments-main/pygments/styles/fruity.py +1 -2
- data/vendor/pygments-main/pygments/styles/gruvbox.py +107 -0
- data/vendor/pygments-main/pygments/styles/igor.py +1 -2
- data/vendor/pygments-main/pygments/styles/inkpot.py +1 -2
- data/vendor/pygments-main/pygments/styles/lovelace.py +1 -2
- data/vendor/pygments-main/pygments/styles/manni.py +1 -2
- data/vendor/pygments-main/pygments/styles/material.py +118 -0
- data/vendor/pygments-main/pygments/styles/monokai.py +1 -2
- data/vendor/pygments-main/pygments/styles/murphy.py +1 -2
- data/vendor/pygments-main/pygments/styles/native.py +2 -2
- data/vendor/pygments-main/pygments/styles/paraiso_dark.py +1 -2
- data/vendor/pygments-main/pygments/styles/paraiso_light.py +1 -2
- data/vendor/pygments-main/pygments/styles/pastie.py +1 -2
- data/vendor/pygments-main/pygments/styles/perldoc.py +1 -2
- data/vendor/pygments-main/pygments/styles/rainbow_dash.py +1 -2
- data/vendor/pygments-main/pygments/styles/rrt.py +1 -2
- data/vendor/pygments-main/pygments/styles/sas.py +1 -2
- data/vendor/pygments-main/pygments/styles/solarized.py +4 -2
- data/vendor/pygments-main/pygments/styles/stata_dark.py +1 -2
- data/vendor/pygments-main/pygments/styles/stata_light.py +1 -2
- data/vendor/pygments-main/pygments/styles/tango.py +1 -2
- data/vendor/pygments-main/pygments/styles/trac.py +1 -2
- data/vendor/pygments-main/pygments/styles/vim.py +1 -2
- data/vendor/pygments-main/pygments/styles/vs.py +1 -2
- data/vendor/pygments-main/pygments/styles/xcode.py +1 -2
- data/vendor/pygments-main/pygments/styles/zenburn.py +80 -0
- data/vendor/pygments-main/pygments/token.py +1 -2
- data/vendor/pygments-main/pygments/unistring.py +1 -2
- data/vendor/pygments-main/pygments/util.py +2 -5
- metadata +48 -23
- data/cache-lexers.rb +0 -9
- data/lexers +0 -0
- data/vendor/pygments-main/Pygments-2.7.3.dist-info/RECORD +0 -482
data/lib/pygments/popen.rb
CHANGED
|
@@ -13,23 +13,13 @@ end
|
|
|
13
13
|
# Python process.
|
|
14
14
|
module Pygments
|
|
15
15
|
class Popen
|
|
16
|
-
def popen4(argv)
|
|
17
|
-
stdin, stdout, stderr, wait_thr = Open3.popen3(*argv)
|
|
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
|
-
end
|
|
23
|
-
|
|
24
16
|
# Get things started by opening a pipe to mentos (the freshmaker), a
|
|
25
17
|
# Python process that talks to the Pygments library. We'll talk back and
|
|
26
18
|
# forth across this pipe.
|
|
27
|
-
def start(pygments_path = File.
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
@log.datetime_format = '%Y-%m-%d %H:%M '
|
|
32
|
-
end
|
|
19
|
+
def start(pygments_path = File.join(__dir__, '..', '..', 'vendor', 'pygments-main'))
|
|
20
|
+
@log = Logger.new(ENV['MENTOS_LOG'] || File::NULL)
|
|
21
|
+
@log.level = Logger::INFO
|
|
22
|
+
@log.datetime_format = '%Y-%m-%d %H:%M '
|
|
33
23
|
|
|
34
24
|
ENV['PYGMENTS_PATH'] = pygments_path
|
|
35
25
|
|
|
@@ -38,11 +28,11 @@ module Pygments
|
|
|
38
28
|
|
|
39
29
|
# A pipe to the mentos python process. #popen4 gives us
|
|
40
30
|
# the pid and three IO objects to write and read.
|
|
41
|
-
argv = [*python_binary, File.
|
|
31
|
+
argv = [*python_binary, File.join(__dir__, 'mentos.py')]
|
|
42
32
|
@pid, @in, @out, @err = popen4(argv)
|
|
43
33
|
@in.binmode
|
|
44
34
|
@out.binmode
|
|
45
|
-
@log.info "Starting pid #{@pid} with
|
|
35
|
+
@log.info "Starting pid #{@pid} with python #{python_binary}."
|
|
46
36
|
end
|
|
47
37
|
|
|
48
38
|
def python_binary
|
|
@@ -53,29 +43,6 @@ module Pygments
|
|
|
53
43
|
@python_bin = python_bin
|
|
54
44
|
end
|
|
55
45
|
|
|
56
|
-
# Detect a suitable Python binary to use.
|
|
57
|
-
def find_python_binary
|
|
58
|
-
if Gem.win_platform?
|
|
59
|
-
return %w[py python3 python].first { |py| !which(py).nil? }
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
# On non-Windows platforms, we simply rely on shebang
|
|
63
|
-
[]
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
# Cross platform which command
|
|
67
|
-
# from http://stackoverflow.com/a/5471032/284795
|
|
68
|
-
def which(command)
|
|
69
|
-
exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
|
|
70
|
-
ENV['PATH'].split(File::PATH_SEPARATOR).each do |dir|
|
|
71
|
-
exts.each do |ext|
|
|
72
|
-
path = File.join(dir, "#{command}#{ext}")
|
|
73
|
-
return path if File.executable?(path) && !File.directory?(path)
|
|
74
|
-
end
|
|
75
|
-
end
|
|
76
|
-
nil
|
|
77
|
-
end
|
|
78
|
-
|
|
79
46
|
# Stop the child process by issuing a kill -9.
|
|
80
47
|
#
|
|
81
48
|
# We then call waitpid() with the pid, which waits for that particular
|
|
@@ -88,13 +55,15 @@ module Pygments
|
|
|
88
55
|
# Technically, kill() can also fail with EPERM or EINVAL (wherein
|
|
89
56
|
# the signal isn't sent); but we have permissions, and
|
|
90
57
|
# we're not doing anything invalid here.
|
|
58
|
+
# @param reason [String]
|
|
91
59
|
def stop(reason)
|
|
92
60
|
unless @pid.nil?
|
|
93
61
|
@log.info "Killing pid: #{@pid}. Reason: #{reason}"
|
|
94
62
|
begin
|
|
95
63
|
Process.kill('KILL', @pid)
|
|
96
64
|
Process.waitpid(@pid)
|
|
97
|
-
rescue Errno::ESRCH, Errno::ECHILD
|
|
65
|
+
rescue Errno::ESRCH, Errno::ECHILD => e
|
|
66
|
+
@log.warn(e)
|
|
98
67
|
end
|
|
99
68
|
end
|
|
100
69
|
@pid = nil
|
|
@@ -108,7 +77,7 @@ module Pygments
|
|
|
108
77
|
# process and the pid has already been re-used) we'll want to raise
|
|
109
78
|
# that as a more informative Mentos exception.
|
|
110
79
|
#
|
|
111
|
-
#
|
|
80
|
+
# @return [Boolean] true if the child is alive.
|
|
112
81
|
def alive?
|
|
113
82
|
return true if defined?(@pid) && @pid && Process.kill(0, @pid)
|
|
114
83
|
|
|
@@ -119,9 +88,16 @@ module Pygments
|
|
|
119
88
|
raise MentosError, 'EPERM checking if child process is alive.'
|
|
120
89
|
end
|
|
121
90
|
|
|
91
|
+
# Public: Returns version of underlying Pygments library
|
|
92
|
+
#
|
|
93
|
+
# @return [Integer]
|
|
94
|
+
def pygments_version
|
|
95
|
+
mentos(:version)[0]
|
|
96
|
+
end
|
|
97
|
+
|
|
122
98
|
# Public: Get an array of available Pygments formatters
|
|
123
99
|
#
|
|
124
|
-
#
|
|
100
|
+
# @return [Array<String>] an array of formatters
|
|
125
101
|
def formatters
|
|
126
102
|
mentos(:get_all_formatters).each_with_object({}) do |(name, desc, aliases), hash|
|
|
127
103
|
# Remove the long-winded and repetitive 'Formatter' suffix
|
|
@@ -134,23 +110,10 @@ module Pygments
|
|
|
134
110
|
end
|
|
135
111
|
end
|
|
136
112
|
|
|
137
|
-
#
|
|
138
|
-
#
|
|
139
|
-
#
|
|
140
|
-
# Should be preferred to #lexers!
|
|
141
|
-
#
|
|
142
|
-
# Returns an array of lexers.
|
|
143
|
-
def lexers
|
|
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?'
|
|
149
|
-
end
|
|
150
|
-
|
|
151
|
-
# Public: Get back all available lexers from mentos itself
|
|
113
|
+
# Get all available lexers from mentos itself
|
|
114
|
+
# Do not use this method directly, instead use Pygments#lexers
|
|
152
115
|
#
|
|
153
|
-
#
|
|
116
|
+
# @return [Array<String>] an array of lexers
|
|
154
117
|
def lexers!
|
|
155
118
|
mentos(:get_all_lexers).each_with_object({}) do |lxr, hash|
|
|
156
119
|
name = lxr[0]
|
|
@@ -163,17 +126,17 @@ module Pygments
|
|
|
163
126
|
end
|
|
164
127
|
end
|
|
165
128
|
|
|
166
|
-
#
|
|
129
|
+
# @return [Array<String>] an array of all available filters
|
|
167
130
|
def filters
|
|
168
131
|
mentos(:get_all_filters)
|
|
169
132
|
end
|
|
170
133
|
|
|
171
|
-
#
|
|
134
|
+
# @return [Array<String>] an array of all available styles
|
|
172
135
|
def styles
|
|
173
136
|
mentos(:get_all_styles)
|
|
174
137
|
end
|
|
175
138
|
|
|
176
|
-
#
|
|
139
|
+
# @return [String] css for highlighted code
|
|
177
140
|
def css(klass = '', opts = {})
|
|
178
141
|
if klass.is_a?(Hash)
|
|
179
142
|
opts = klass
|
|
@@ -182,8 +145,8 @@ module Pygments
|
|
|
182
145
|
mentos(:css, ['html', klass], opts)
|
|
183
146
|
end
|
|
184
147
|
|
|
185
|
-
#
|
|
186
|
-
def
|
|
148
|
+
# @return [[String], nil] aliases of a lexer.
|
|
149
|
+
def lexer_names_for(*args)
|
|
187
150
|
# Pop off the last arg if it's a hash, which becomes our opts
|
|
188
151
|
opts = if args.last.is_a?(Hash)
|
|
189
152
|
args.pop
|
|
@@ -193,13 +156,14 @@ module Pygments
|
|
|
193
156
|
|
|
194
157
|
code = (args.pop if args.last.is_a?(String))
|
|
195
158
|
|
|
196
|
-
mentos(:
|
|
159
|
+
mentos(:lexer_names_for, args, opts, code)
|
|
197
160
|
end
|
|
198
161
|
|
|
199
162
|
# Public: Highlight code.
|
|
200
163
|
#
|
|
201
|
-
# Takes a first-position argument of the code to be highlighted,
|
|
202
|
-
# second-position hash of various arguments specifying
|
|
164
|
+
# Takes a first-position argument of the code to be highlighted,
|
|
165
|
+
# and a second-position hash of various arguments specifying
|
|
166
|
+
# highlighting properties.
|
|
203
167
|
#
|
|
204
168
|
# Returns the highlighted string
|
|
205
169
|
# or nil when the request to the Python process timed out.
|
|
@@ -216,30 +180,63 @@ module Pygments
|
|
|
216
180
|
|
|
217
181
|
# Get back the string from mentos and force encoding if we can
|
|
218
182
|
str = mentos(:highlight, nil, opts, code)
|
|
219
|
-
if str.respond_to?(:force_encoding)
|
|
220
|
-
str.force_encoding(opts[:options][:outencoding])
|
|
221
|
-
end
|
|
183
|
+
str.force_encoding(opts[:options][:outencoding]) if str.respond_to?(:force_encoding)
|
|
222
184
|
str
|
|
223
185
|
end
|
|
224
186
|
|
|
225
187
|
private
|
|
226
188
|
|
|
227
|
-
|
|
189
|
+
# @param argv [Array<String>]
|
|
190
|
+
def popen4(argv)
|
|
191
|
+
stdin, stdout, stderr, wait_thr = Open3.popen3(*argv, { close_others: true })
|
|
192
|
+
while (pid = wait_thr.pid).nil? && wait_thr.alive?
|
|
193
|
+
# wait_thr.pid is not immediately available on JRuby. Why???
|
|
194
|
+
end
|
|
195
|
+
[pid, stdin, stdout, stderr]
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
# Detect a suitable Python binary to use.
|
|
199
|
+
def find_python_binary
|
|
200
|
+
return %w[py python3 python].first { |py| !which(py).nil? } if Gem.win_platform?
|
|
201
|
+
|
|
202
|
+
# On non-Windows platforms, we simply rely on shebang
|
|
203
|
+
[]
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
# Cross platform which command
|
|
207
|
+
# from http://stackoverflow.com/a/5471032/284795
|
|
208
|
+
def which(command)
|
|
209
|
+
exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
|
|
210
|
+
ENV['PATH'].split(File::PATH_SEPARATOR).each do |dir|
|
|
211
|
+
exts.each do |ext|
|
|
212
|
+
path = File.join(dir, "#{command}#{ext}")
|
|
213
|
+
return path if File.executable?(path) && !File.directory?(path)
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
nil
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
# @param timeout [Integer]
|
|
220
|
+
# @param error_message [String]
|
|
221
|
+
# @yield
|
|
222
|
+
def with_watchdog(timeout, error_message)
|
|
228
223
|
state_mutex = Mutex.new
|
|
229
224
|
state = :alive
|
|
230
225
|
wd_cleanup = ConditionVariable.new
|
|
231
226
|
|
|
232
|
-
watchdog =
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
227
|
+
watchdog = if timeout.positive?
|
|
228
|
+
Thread.new do
|
|
229
|
+
state_mutex.synchronize do
|
|
230
|
+
wd_cleanup.wait(state_mutex, timeout) if state != :finished
|
|
231
|
+
if state != :finished
|
|
232
|
+
@log.error error_message
|
|
233
|
+
stop error_message
|
|
234
|
+
state = :timeout
|
|
235
|
+
end
|
|
236
|
+
end
|
|
237
|
+
end
|
|
238
|
+
end
|
|
240
239
|
|
|
241
|
-
end
|
|
242
|
-
end : nil
|
|
243
240
|
begin
|
|
244
241
|
yield
|
|
245
242
|
ensure
|
|
@@ -258,53 +255,20 @@ module Pygments
|
|
|
258
255
|
|
|
259
256
|
# Our 'rpc'-ish request to mentos. Requires a method name, and then optional
|
|
260
257
|
# args, kwargs, code.
|
|
261
|
-
def mentos(method, args = [], kwargs = {},
|
|
258
|
+
def mentos(method, args = [], kwargs = {}, code = nil)
|
|
262
259
|
# Open the pipe if necessary
|
|
263
260
|
start unless alive?
|
|
264
261
|
|
|
265
|
-
# Timeout requests that take too long.
|
|
266
|
-
# Invalid MENTOS_TIMEOUT results in just using default.
|
|
267
|
-
timeout_time = kwargs.delete(:timeout)
|
|
268
|
-
if timeout_time.nil?
|
|
269
|
-
timeout_time = begin
|
|
270
|
-
Integer(ENV['MENTOS_TIMEOUT'])
|
|
271
|
-
rescue TypeError
|
|
272
|
-
0
|
|
273
|
-
end
|
|
274
|
-
end
|
|
275
|
-
|
|
276
|
-
# For sanity checking on both sides of the pipe when highlighting, we prepend and
|
|
277
|
-
# append an id. mentos checks that these are 8 character ids and that they match.
|
|
278
|
-
# It then returns the id's back to Rubyland.
|
|
279
|
-
id = (0...8).map { rand(65..89).chr }.join
|
|
280
|
-
code = original_code ? add_ids(original_code, id) : nil
|
|
281
|
-
|
|
282
262
|
# Add metadata to the header and generate it.
|
|
283
|
-
|
|
284
|
-
code.bytesize
|
|
285
|
-
else
|
|
286
|
-
0
|
|
287
|
-
end
|
|
288
|
-
|
|
289
|
-
kwargs.freeze
|
|
290
|
-
kwargs = kwargs.merge('fd' => @out.to_i, 'id' => id, 'bytes' => bytesize)
|
|
263
|
+
kwargs = kwargs.merge('bytes' => (code.nil? ? 0 : code.bytesize))
|
|
291
264
|
out_header = JSON.generate(method: method, args: args, kwargs: kwargs)
|
|
292
265
|
|
|
293
266
|
begin
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
@log.info "Size out: #{out_header.bytesize}"
|
|
298
|
-
|
|
299
|
-
# mentos is now waiting for the header, and, potentially, code.
|
|
300
|
-
@in.write(out_header)
|
|
301
|
-
@log.info "Out header: #{out_header}"
|
|
302
|
-
@in.write(code) unless code.nil?
|
|
303
|
-
|
|
304
|
-
@in.flush
|
|
267
|
+
timeout = get_timeout(kwargs.delete(:timeout))
|
|
268
|
+
res = with_watchdog(timeout, "Timeout on a mentos #{method} call") do
|
|
269
|
+
write_header(out_header, code)
|
|
305
270
|
|
|
306
271
|
# mentos will now return data to us. First it sends the header.
|
|
307
|
-
|
|
308
272
|
header_len_bytes = @out.read(4)
|
|
309
273
|
if header_len_bytes.nil?
|
|
310
274
|
raise Errno::EPIPE, %(Failed to read response from Python process on a mentos #{method} call)
|
|
@@ -315,7 +279,7 @@ module Pygments
|
|
|
315
279
|
header = @out.read(header_len)
|
|
316
280
|
|
|
317
281
|
# Now handle the header, any read any more data required.
|
|
318
|
-
handle_header_and_return(header
|
|
282
|
+
handle_header_and_return(header)
|
|
319
283
|
end
|
|
320
284
|
|
|
321
285
|
# Finally, return what we got.
|
|
@@ -338,74 +302,70 @@ module Pygments
|
|
|
338
302
|
end
|
|
339
303
|
end
|
|
340
304
|
|
|
305
|
+
# @param header [String]
|
|
306
|
+
# @param code [String, nil]
|
|
307
|
+
def write_header(header, code)
|
|
308
|
+
# Get the size of the header itself and write that.
|
|
309
|
+
@in.write([header.bytesize].pack('N'))
|
|
310
|
+
@log.info "Size out: #{header.bytesize}"
|
|
311
|
+
|
|
312
|
+
# mentos is now waiting for the header, and, potentially, code.
|
|
313
|
+
@in.write(header)
|
|
314
|
+
@log.info "Out header: #{header}"
|
|
315
|
+
@in.write(code) unless code.nil?
|
|
316
|
+
@in.flush
|
|
317
|
+
end
|
|
318
|
+
|
|
319
|
+
# @param timeout [Integer, nil]
|
|
320
|
+
# @return [Integer]
|
|
321
|
+
def get_timeout(timeout)
|
|
322
|
+
return timeout unless timeout.nil?
|
|
323
|
+
|
|
324
|
+
begin
|
|
325
|
+
Integer(ENV['MENTOS_TIMEOUT'])
|
|
326
|
+
rescue TypeError
|
|
327
|
+
0
|
|
328
|
+
end
|
|
329
|
+
end
|
|
330
|
+
|
|
341
331
|
# Based on the header we receive, determine if we need
|
|
342
332
|
# to read more bytes, and read those bytes if necessary.
|
|
343
333
|
#
|
|
344
|
-
#
|
|
345
|
-
#
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
@log.info 'Highlight in process.'
|
|
361
|
-
|
|
362
|
-
# Get the id's
|
|
363
|
-
start_id = res[0..7]
|
|
364
|
-
end_id = res[-8..-1]
|
|
365
|
-
|
|
366
|
-
# Sanity check.
|
|
367
|
-
if !((start_id == id) && (end_id == id))
|
|
368
|
-
raise MentosError, "ID's did not match. Aborting."
|
|
369
|
-
else
|
|
370
|
-
# We're good. Remove the padding
|
|
371
|
-
res = res[10..-11]
|
|
372
|
-
@log.info 'Highlighting complete.'
|
|
373
|
-
res
|
|
374
|
-
end
|
|
375
|
-
end
|
|
376
|
-
res
|
|
377
|
-
else
|
|
378
|
-
raise MentosError, 'No header received back.'
|
|
334
|
+
# @param header [String, nil]
|
|
335
|
+
# @return [String, nil] either highlighted text or metadata.
|
|
336
|
+
def handle_header_and_return(header)
|
|
337
|
+
raise MentosError, 'No header received back.' if header.nil?
|
|
338
|
+
|
|
339
|
+
@log.info "In header: #{header}"
|
|
340
|
+
header = header_to_json(header)
|
|
341
|
+
bytes = header[:bytes]
|
|
342
|
+
|
|
343
|
+
# Read more bytes (the actual response body)
|
|
344
|
+
res = @out.read(bytes.to_i)
|
|
345
|
+
|
|
346
|
+
if header[:method] == 'highlight' && res.nil?
|
|
347
|
+
# Make sure we have a result back; else consider this an error.
|
|
348
|
+
raise MentosError, 'No highlight result back from mentos.'
|
|
379
349
|
end
|
|
380
|
-
end
|
|
381
350
|
|
|
382
|
-
|
|
383
|
-
# the following text starts with a slash (like terminal code), and append the
|
|
384
|
-
# id, with two padding also. This means we are sending over the 8 characters +
|
|
385
|
-
# code + 8 characters.
|
|
386
|
-
def add_ids(code, id)
|
|
387
|
-
(id + " #{code} #{id}").freeze
|
|
351
|
+
res
|
|
388
352
|
end
|
|
389
353
|
|
|
390
|
-
#
|
|
391
|
-
# want them, text otherwise.
|
|
354
|
+
# @return Ruby objects for the methods that want them, text otherwise.
|
|
392
355
|
def return_result(res, method)
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
end
|
|
396
|
-
res = res.rstrip if res.class == String
|
|
356
|
+
res = JSON.parse(res, symbolize_names: true) unless %i[highlight css].include?(method)
|
|
357
|
+
res = res.rstrip if res.instance_of?(String)
|
|
397
358
|
res
|
|
398
359
|
end
|
|
399
360
|
|
|
400
361
|
# Convert a text header into JSON for easy access.
|
|
362
|
+
# @param header [String]
|
|
363
|
+
# @return [JSON]
|
|
401
364
|
def header_to_json(header)
|
|
402
|
-
|
|
365
|
+
json = JSON.parse(header, symbolize_names: true)
|
|
366
|
+
raise MentosError, json[:error] unless json[:error].nil?
|
|
403
367
|
|
|
404
|
-
|
|
405
|
-
raise MentosError, header[:error]
|
|
406
|
-
else
|
|
407
|
-
header
|
|
408
|
-
end
|
|
368
|
+
json
|
|
409
369
|
end
|
|
410
370
|
end
|
|
411
371
|
end
|
data/lib/pygments/version.rb
CHANGED
data/lib/pygments.rb
CHANGED
|
@@ -1,28 +1,37 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require File.join(File.dirname(__FILE__), 'pygments/popen')
|
|
4
3
|
require 'forwardable'
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
require_relative 'pygments/lexer'
|
|
6
|
+
require_relative 'pygments/popen'
|
|
8
7
|
|
|
8
|
+
module Pygments
|
|
9
9
|
class << self
|
|
10
10
|
extend Forwardable
|
|
11
11
|
|
|
12
|
+
def lexers
|
|
13
|
+
LexerCache.instance.raw_lexers
|
|
14
|
+
end
|
|
15
|
+
|
|
12
16
|
def engine
|
|
13
17
|
Thread.current.thread_variable_get(:pygments_engine) ||
|
|
14
18
|
Thread.current.thread_variable_set(:pygments_engine, Pygments::Popen.new)
|
|
15
19
|
end
|
|
16
20
|
|
|
21
|
+
def lexer_name_for(*args)
|
|
22
|
+
names = engine.lexer_names_for(*args)
|
|
23
|
+
names&.[](0)
|
|
24
|
+
end
|
|
25
|
+
|
|
17
26
|
def_delegators :engine,
|
|
18
27
|
:formatters,
|
|
19
|
-
:lexers,
|
|
20
28
|
:lexers!,
|
|
21
29
|
:filters,
|
|
22
30
|
:styles,
|
|
23
31
|
:css,
|
|
24
|
-
:
|
|
32
|
+
:lexer_names_for,
|
|
25
33
|
:highlight,
|
|
26
|
-
:start
|
|
34
|
+
:start,
|
|
35
|
+
:pygments_version
|
|
27
36
|
end
|
|
28
37
|
end
|
data/pygments.rb.gemspec
CHANGED
|
@@ -1,27 +1,32 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
require_relative 'lib/pygments/version'
|
|
4
4
|
|
|
5
5
|
Gem::Specification.new do |s|
|
|
6
6
|
s.name = 'pygments.rb'
|
|
7
7
|
s.version = Pygments::VERSION
|
|
8
8
|
|
|
9
9
|
s.summary = 'pygments wrapper for ruby'
|
|
10
|
-
s.description = 'pygments.rb
|
|
11
|
-
|
|
10
|
+
s.description = 'pygments.rb is a Ruby wrapper for Pygments syntax highlighter'
|
|
11
|
+
s.license = 'MIT'
|
|
12
12
|
s.homepage = 'https://github.com/pygments/pygments.rb'
|
|
13
|
-
s.required_ruby_version = '>= 2.3.0'
|
|
14
13
|
|
|
15
14
|
s.authors = ['Aman Gupta', 'Ted Nyman', 'Marat Radchenko']
|
|
16
15
|
s.email = ['marat@slonopotamus.org']
|
|
17
|
-
s.license = 'MIT'
|
|
18
16
|
|
|
19
|
-
s.
|
|
20
|
-
|
|
21
|
-
|
|
17
|
+
s.metadata = {
|
|
18
|
+
'homepage_uri' => s.homepage,
|
|
19
|
+
'bug_tracker_uri' => "#{s.homepage}/issues",
|
|
20
|
+
'changelog_uri' => "#{s.homepage}/blob/master/CHANGELOG.adoc",
|
|
21
|
+
'documentation_uri' => "https://www.rubydoc.info/gems/#{s.name}",
|
|
22
|
+
'source_code_uri' => s.homepage
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
s.required_ruby_version = '>= 2.3.0'
|
|
22
26
|
|
|
23
|
-
|
|
24
|
-
s.
|
|
27
|
+
s.add_development_dependency 'rake', '~> 13.0.0'
|
|
28
|
+
s.add_development_dependency 'rubocop', '~> 0.81.0'
|
|
29
|
+
s.add_development_dependency 'test-unit', '~> 3.5.0'
|
|
25
30
|
|
|
26
|
-
s.files = `git ls-files`.split("\
|
|
31
|
+
s.files = `git ls-files -z`.split("\0").reject { |f| File.symlink?(f) }
|
|
27
32
|
end
|
data/test/test_pygments.rb
CHANGED
|
@@ -10,7 +10,9 @@ PE = Pygments.engine
|
|
|
10
10
|
class PygmentsHighlightTest < Test::Unit::TestCase
|
|
11
11
|
RUBY_CODE = "#!/usr/bin/ruby\nputs 'foo'"
|
|
12
12
|
RUBY_CODE_TRAILING_NEWLINE = "#!/usr/bin/ruby\nputs 'foo'\n"
|
|
13
|
-
TEST_CODE = File.read(
|
|
13
|
+
TEST_CODE = File.read(
|
|
14
|
+
File.join(__dir__, '..', 'lib', 'pygments', 'mentos.py')
|
|
15
|
+
)
|
|
14
16
|
|
|
15
17
|
def test_highlight_defaults_to_html
|
|
16
18
|
code = P.highlight(RUBY_CODE)
|
|
@@ -21,13 +23,9 @@ class PygmentsHighlightTest < Test::Unit::TestCase
|
|
|
21
23
|
def test_full_html_highlight
|
|
22
24
|
code = P.highlight(RUBY_CODE)
|
|
23
25
|
assert_match '<span class="ch">#!/usr/bin/ruby</span>', code
|
|
24
|
-
assert_equal
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
def test_full_table_highlight
|
|
28
|
-
code = P.highlight(RUBY_CODE, options: { linenos: true })
|
|
29
|
-
assert_match '<span class="ch">#!/usr/bin/ruby</span>', code
|
|
30
|
-
assert_equal "<table class=\"highlighttable\"><tr><td class=\"linenos\"><div class=\"linenodiv\"><pre>1\n2</pre></div></td><td class=\"code\"><div class=\"highlight\"><pre><span></span><span class=\"ch\">#!/usr/bin/ruby</span>\n<span class=\"nb\">puts</span> <span class=\"s1\">'foo'</span>\n</pre></div>\n</td></tr></table>", code
|
|
26
|
+
assert_equal %(<div class="highlight"><pre><span></span><span class="ch">#!/usr/bin/ruby</span>
|
|
27
|
+
<span class="nb">puts</span> <span class="s1">'foo'</span>
|
|
28
|
+
</pre></div>), code
|
|
31
29
|
end
|
|
32
30
|
|
|
33
31
|
def test_highlight_works_with_larger_files
|
|
@@ -94,12 +92,12 @@ class PygmentsHighlightTest < Test::Unit::TestCase
|
|
|
94
92
|
end
|
|
95
93
|
|
|
96
94
|
def test_highlight_works_with_multiple_newlines
|
|
97
|
-
code = P.highlight(RUBY_CODE_TRAILING_NEWLINE
|
|
95
|
+
code = P.highlight("#{RUBY_CODE_TRAILING_NEWLINE}derp\n\n")
|
|
98
96
|
assert_match '<span class="ch">#!/usr/bin/ruby</span>', code
|
|
99
97
|
end
|
|
100
98
|
|
|
101
99
|
def test_highlight_works_with_trailing_cr
|
|
102
|
-
code = P.highlight(RUBY_CODE_TRAILING_NEWLINE
|
|
100
|
+
code = P.highlight("#{RUBY_CODE_TRAILING_NEWLINE}\r")
|
|
103
101
|
assert_match '<span class="ch">#!/usr/bin/ruby</span>', code
|
|
104
102
|
end
|
|
105
103
|
|
|
@@ -108,6 +106,12 @@ class PygmentsHighlightTest < Test::Unit::TestCase
|
|
|
108
106
|
assert_match '>importr</span>', code
|
|
109
107
|
end
|
|
110
108
|
|
|
109
|
+
def test_version
|
|
110
|
+
version_str = P.pygments_version
|
|
111
|
+
# This will throw "Malformed version number string" ArgumentError if version_str is not a valid version string
|
|
112
|
+
Gem::Version.new(version_str)
|
|
113
|
+
end
|
|
114
|
+
|
|
111
115
|
def test_highlight_on_multi_threads
|
|
112
116
|
omit 'We do not actually support multithreading'
|
|
113
117
|
|
|
@@ -119,56 +123,31 @@ class PygmentsHighlightTest < Test::Unit::TestCase
|
|
|
119
123
|
end
|
|
120
124
|
end
|
|
121
125
|
|
|
122
|
-
# Philosophically, I'm not the biggest fan of testing private
|
|
123
|
-
# methods, but given the relative delicacy of validity checking
|
|
124
|
-
# over the pipe I think it's necessary and informative.
|
|
125
|
-
class PygmentsValidityTest < Test::Unit::TestCase
|
|
126
|
-
def test_add_ids_with_padding
|
|
127
|
-
res = PE.send(:add_ids, 'herp derp baz boo foo', 'ABCDEFGH')
|
|
128
|
-
assert_equal 'ABCDEFGH herp derp baz boo foo ABCDEFGH', res
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
def test_add_ids_on_empty_string
|
|
132
|
-
res = PE.send(:add_ids, '', 'ABCDEFGH')
|
|
133
|
-
assert_equal 'ABCDEFGH ABCDEFGH', res
|
|
134
|
-
end
|
|
135
|
-
|
|
136
|
-
def test_add_ids_with_unicode_data
|
|
137
|
-
res = PE.send(:add_ids, '# ø ø ø', 'ABCDEFGH')
|
|
138
|
-
assert_equal 'ABCDEFGH # ø ø ø ABCDEFGH', res
|
|
139
|
-
end
|
|
140
|
-
|
|
141
|
-
def test_add_ids_with_starting_slashes
|
|
142
|
-
res = PE.send(:add_ids, '\\# ø ø ø..//', 'ABCDEFGH')
|
|
143
|
-
assert_equal 'ABCDEFGH \\# ø ø ø..// ABCDEFGH', res
|
|
144
|
-
end
|
|
145
|
-
end
|
|
146
|
-
|
|
147
126
|
class PygmentsLexerTest < Test::Unit::TestCase
|
|
148
127
|
RUBY_CODE = "#!/usr/bin/ruby\nputs 'foo'"
|
|
149
128
|
|
|
150
129
|
def test_lexer_by_mimetype
|
|
151
|
-
|
|
130
|
+
assert_includes P.lexer_names_for(mimetype: 'text/x-ruby'), 'rb'
|
|
152
131
|
assert_equal 'json', P.lexer_name_for(mimetype: 'application/json')
|
|
153
132
|
end
|
|
154
133
|
|
|
155
134
|
def test_lexer_by_filename
|
|
156
|
-
|
|
135
|
+
assert_includes P.lexer_names_for(filename: 'test.rb'), 'rb'
|
|
157
136
|
assert_equal 'scala', P.lexer_name_for(filename: 'test.scala')
|
|
158
137
|
end
|
|
159
138
|
|
|
160
139
|
def test_lexer_by_name
|
|
161
|
-
|
|
140
|
+
assert_includes P.lexer_names_for(lexer: 'ruby'), 'rb'
|
|
162
141
|
assert_equal 'python', P.lexer_name_for(lexer: 'python')
|
|
163
142
|
assert_equal 'c', P.lexer_name_for(lexer: 'c')
|
|
164
143
|
end
|
|
165
144
|
|
|
166
145
|
def test_lexer_by_filename_and_content
|
|
167
|
-
|
|
146
|
+
assert_includes P.lexer_names_for(RUBY_CODE, filename: 'test.rb'), 'rb'
|
|
168
147
|
end
|
|
169
148
|
|
|
170
149
|
def test_lexer_by_content
|
|
171
|
-
|
|
150
|
+
assert_includes P.lexer_names_for(RUBY_CODE), 'rb'
|
|
172
151
|
end
|
|
173
152
|
|
|
174
153
|
def test_lexer_by_nothing
|