rouge 3.17.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 +7 -0
- data/Gemfile +40 -0
- data/LICENSE +186 -0
- data/bin/rougify +18 -0
- data/lib/rouge.rb +93 -0
- data/lib/rouge/cli.rb +498 -0
- data/lib/rouge/demos/abap +6 -0
- data/lib/rouge/demos/actionscript +4 -0
- data/lib/rouge/demos/ada +26 -0
- data/lib/rouge/demos/apache +21 -0
- data/lib/rouge/demos/apex +9 -0
- data/lib/rouge/demos/apiblueprint +33 -0
- data/lib/rouge/demos/applescript +2 -0
- data/lib/rouge/demos/armasm +12 -0
- data/lib/rouge/demos/awk +4 -0
- data/lib/rouge/demos/batchfile +3 -0
- data/lib/rouge/demos/bbcbasic +6 -0
- data/lib/rouge/demos/biml +38 -0
- data/lib/rouge/demos/bpf +7 -0
- data/lib/rouge/demos/brainfuck +5 -0
- data/lib/rouge/demos/bsl +7 -0
- data/lib/rouge/demos/c +8 -0
- data/lib/rouge/demos/ceylon +7 -0
- data/lib/rouge/demos/cfscript +18 -0
- data/lib/rouge/demos/clean +6 -0
- data/lib/rouge/demos/clojure +5 -0
- data/lib/rouge/demos/cmake +7 -0
- data/lib/rouge/demos/cmhg +8 -0
- data/lib/rouge/demos/coffeescript +5 -0
- data/lib/rouge/demos/common_lisp +1 -0
- data/lib/rouge/demos/conf +4 -0
- data/lib/rouge/demos/console +6 -0
- data/lib/rouge/demos/coq +13 -0
- data/lib/rouge/demos/cpp +8 -0
- data/lib/rouge/demos/crystal +45 -0
- data/lib/rouge/demos/csharp +5 -0
- data/lib/rouge/demos/css +4 -0
- data/lib/rouge/demos/csvs +8 -0
- data/lib/rouge/demos/cuda +11 -0
- data/lib/rouge/demos/cython +6 -0
- data/lib/rouge/demos/d +16 -0
- data/lib/rouge/demos/dart +6 -0
- data/lib/rouge/demos/diff +7 -0
- data/lib/rouge/demos/digdag +19 -0
- data/lib/rouge/demos/docker +9 -0
- data/lib/rouge/demos/dot +5 -0
- data/lib/rouge/demos/ecl +18 -0
- data/lib/rouge/demos/eex +1 -0
- data/lib/rouge/demos/eiffel +30 -0
- data/lib/rouge/demos/elixir +1 -0
- data/lib/rouge/demos/elm +4 -0
- data/lib/rouge/demos/epp +4 -0
- data/lib/rouge/demos/erb +1 -0
- data/lib/rouge/demos/erlang +7 -0
- data/lib/rouge/demos/escape +3 -0
- data/lib/rouge/demos/factor +5 -0
- data/lib/rouge/demos/fortran +22 -0
- data/lib/rouge/demos/freefem +16 -0
- data/lib/rouge/demos/fsharp +12 -0
- data/lib/rouge/demos/gdscript +18 -0
- data/lib/rouge/demos/ghc-core +26 -0
- data/lib/rouge/demos/gherkin +17 -0
- data/lib/rouge/demos/glsl +14 -0
- data/lib/rouge/demos/go +7 -0
- data/lib/rouge/demos/gradle +10 -0
- data/lib/rouge/demos/graphql +17 -0
- data/lib/rouge/demos/groovy +9 -0
- data/lib/rouge/demos/hack +5 -0
- data/lib/rouge/demos/haml +5 -0
- data/lib/rouge/demos/handlebars +7 -0
- data/lib/rouge/demos/haskell +6 -0
- data/lib/rouge/demos/haxe +5 -0
- data/lib/rouge/demos/hcl +7 -0
- data/lib/rouge/demos/hocon +8 -0
- data/lib/rouge/demos/hql +5 -0
- data/lib/rouge/demos/html +8 -0
- data/lib/rouge/demos/http +14 -0
- data/lib/rouge/demos/hylang +10 -0
- data/lib/rouge/demos/idlang +8 -0
- data/lib/rouge/demos/igorpro +9 -0
- data/lib/rouge/demos/ini +4 -0
- data/lib/rouge/demos/io +11 -0
- data/lib/rouge/demos/irb +4 -0
- data/lib/rouge/demos/irb_output +2 -0
- data/lib/rouge/demos/java +5 -0
- data/lib/rouge/demos/javascript +1 -0
- data/lib/rouge/demos/jinja +9 -0
- data/lib/rouge/demos/jsl +3 -0
- data/lib/rouge/demos/json +1 -0
- data/lib/rouge/demos/json-doc +1 -0
- data/lib/rouge/demos/jsonnet +28 -0
- data/lib/rouge/demos/jsp +29 -0
- data/lib/rouge/demos/jsx +17 -0
- data/lib/rouge/demos/julia +11 -0
- data/lib/rouge/demos/kotlin +3 -0
- data/lib/rouge/demos/lasso +12 -0
- data/lib/rouge/demos/liquid +10 -0
- data/lib/rouge/demos/literate_coffeescript +3 -0
- data/lib/rouge/demos/literate_haskell +7 -0
- data/lib/rouge/demos/llvm +20 -0
- data/lib/rouge/demos/lua +12 -0
- data/lib/rouge/demos/lustre +6 -0
- data/lib/rouge/demos/lutin +18 -0
- data/lib/rouge/demos/m68k +16 -0
- data/lib/rouge/demos/magik +6 -0
- data/lib/rouge/demos/make +6 -0
- data/lib/rouge/demos/markdown +4 -0
- data/lib/rouge/demos/mason +22 -0
- data/lib/rouge/demos/mathematica +8 -0
- data/lib/rouge/demos/matlab +6 -0
- data/lib/rouge/demos/minizinc +23 -0
- data/lib/rouge/demos/moonscript +16 -0
- data/lib/rouge/demos/mosel +10 -0
- data/lib/rouge/demos/msgtrans +4 -0
- data/lib/rouge/demos/mxml +22 -0
- data/lib/rouge/demos/nasm +26 -0
- data/lib/rouge/demos/nesasm +11 -0
- data/lib/rouge/demos/nginx +5 -0
- data/lib/rouge/demos/nim +27 -0
- data/lib/rouge/demos/nix +19 -0
- data/lib/rouge/demos/objective_c +18 -0
- data/lib/rouge/demos/objective_cpp +17 -0
- data/lib/rouge/demos/ocaml +12 -0
- data/lib/rouge/demos/openedge +4 -0
- data/lib/rouge/demos/opentype_feature_file +6 -0
- data/lib/rouge/demos/pascal +14 -0
- data/lib/rouge/demos/perl +5 -0
- data/lib/rouge/demos/php +3 -0
- data/lib/rouge/demos/plaintext +1 -0
- data/lib/rouge/demos/plist +11 -0
- data/lib/rouge/demos/pony +17 -0
- data/lib/rouge/demos/powershell +13 -0
- data/lib/rouge/demos/praat +26 -0
- data/lib/rouge/demos/prolog +9 -0
- data/lib/rouge/demos/prometheus +9 -0
- data/lib/rouge/demos/properties +7 -0
- data/lib/rouge/demos/protobuf +5 -0
- data/lib/rouge/demos/puppet +6 -0
- data/lib/rouge/demos/python +6 -0
- data/lib/rouge/demos/q +8 -0
- data/lib/rouge/demos/qml +9 -0
- data/lib/rouge/demos/r +8 -0
- data/lib/rouge/demos/racket +24 -0
- data/lib/rouge/demos/reasonml +12 -0
- data/lib/rouge/demos/robot_framework +27 -0
- data/lib/rouge/demos/ruby +9 -0
- data/lib/rouge/demos/rust +12 -0
- data/lib/rouge/demos/sas +13 -0
- data/lib/rouge/demos/sass +3 -0
- data/lib/rouge/demos/scala +3 -0
- data/lib/rouge/demos/scheme +4 -0
- data/lib/rouge/demos/scss +5 -0
- data/lib/rouge/demos/sed +4 -0
- data/lib/rouge/demos/shell +2 -0
- data/lib/rouge/demos/sieve +10 -0
- data/lib/rouge/demos/slice +10 -0
- data/lib/rouge/demos/slim +17 -0
- data/lib/rouge/demos/smalltalk +6 -0
- data/lib/rouge/demos/smarty +12 -0
- data/lib/rouge/demos/sml +4 -0
- data/lib/rouge/demos/sparql +6 -0
- data/lib/rouge/demos/sqf +14 -0
- data/lib/rouge/demos/sql +1 -0
- data/lib/rouge/demos/supercollider +11 -0
- data/lib/rouge/demos/swift +5 -0
- data/lib/rouge/demos/tap +5 -0
- data/lib/rouge/demos/tcl +1 -0
- data/lib/rouge/demos/terraform +16 -0
- data/lib/rouge/demos/tex +1 -0
- data/lib/rouge/demos/toml +9 -0
- data/lib/rouge/demos/tsx +17 -0
- data/lib/rouge/demos/ttcn3 +6 -0
- data/lib/rouge/demos/tulip +13 -0
- data/lib/rouge/demos/turtle +26 -0
- data/lib/rouge/demos/twig +9 -0
- data/lib/rouge/demos/typescript +1 -0
- data/lib/rouge/demos/vala +8 -0
- data/lib/rouge/demos/vb +4 -0
- data/lib/rouge/demos/vcl +12 -0
- data/lib/rouge/demos/verilog +27 -0
- data/lib/rouge/demos/vhdl +23 -0
- data/lib/rouge/demos/viml +14 -0
- data/lib/rouge/demos/vue +11 -0
- data/lib/rouge/demos/wollok +11 -0
- data/lib/rouge/demos/xml +2 -0
- data/lib/rouge/demos/xojo +14 -0
- data/lib/rouge/demos/xpath +2 -0
- data/lib/rouge/demos/xquery +22 -0
- data/lib/rouge/demos/yaml +4 -0
- data/lib/rouge/formatter.rb +112 -0
- data/lib/rouge/formatters/html.rb +56 -0
- data/lib/rouge/formatters/html_inline.rb +31 -0
- data/lib/rouge/formatters/html_legacy.rb +45 -0
- data/lib/rouge/formatters/html_line_table.rb +53 -0
- data/lib/rouge/formatters/html_linewise.rb +23 -0
- data/lib/rouge/formatters/html_pygments.rb +18 -0
- data/lib/rouge/formatters/html_table.rb +51 -0
- data/lib/rouge/formatters/null.rb +20 -0
- data/lib/rouge/formatters/terminal256.rb +198 -0
- data/lib/rouge/formatters/terminal_truecolor.rb +37 -0
- data/lib/rouge/formatters/tex.rb +92 -0
- data/lib/rouge/guesser.rb +57 -0
- data/lib/rouge/guessers/disambiguation.rb +136 -0
- data/lib/rouge/guessers/filename.rb +27 -0
- data/lib/rouge/guessers/glob_mapping.rb +45 -0
- data/lib/rouge/guessers/mimetype.rb +16 -0
- data/lib/rouge/guessers/modeline.rb +46 -0
- data/lib/rouge/guessers/source.rb +31 -0
- data/lib/rouge/guessers/util.rb +34 -0
- data/lib/rouge/lexer.rb +516 -0
- data/lib/rouge/lexers/abap.rb +240 -0
- data/lib/rouge/lexers/actionscript.rb +196 -0
- data/lib/rouge/lexers/ada.rb +162 -0
- data/lib/rouge/lexers/apache.rb +73 -0
- data/lib/rouge/lexers/apache/keywords.yml +764 -0
- data/lib/rouge/lexers/apex.rb +126 -0
- data/lib/rouge/lexers/apiblueprint.rb +49 -0
- data/lib/rouge/lexers/apple_script.rb +370 -0
- data/lib/rouge/lexers/armasm.rb +145 -0
- data/lib/rouge/lexers/awk.rb +162 -0
- data/lib/rouge/lexers/batchfile.rb +164 -0
- data/lib/rouge/lexers/bbcbasic.rb +112 -0
- data/lib/rouge/lexers/biml.rb +43 -0
- data/lib/rouge/lexers/bpf.rb +118 -0
- data/lib/rouge/lexers/brainfuck.rb +53 -0
- data/lib/rouge/lexers/bsl.rb +82 -0
- data/lib/rouge/lexers/c.rb +190 -0
- data/lib/rouge/lexers/ceylon.rb +96 -0
- data/lib/rouge/lexers/cfscript.rb +154 -0
- data/lib/rouge/lexers/clean.rb +156 -0
- data/lib/rouge/lexers/clojure.rb +113 -0
- data/lib/rouge/lexers/cmake.rb +207 -0
- data/lib/rouge/lexers/cmhg.rb +34 -0
- data/lib/rouge/lexers/coffeescript.rb +215 -0
- data/lib/rouge/lexers/common_lisp.rb +346 -0
- data/lib/rouge/lexers/conf.rb +25 -0
- data/lib/rouge/lexers/console.rb +174 -0
- data/lib/rouge/lexers/coq.rb +191 -0
- data/lib/rouge/lexers/cpp.rb +82 -0
- data/lib/rouge/lexers/crystal.rb +430 -0
- data/lib/rouge/lexers/csharp.rb +114 -0
- data/lib/rouge/lexers/css.rb +274 -0
- data/lib/rouge/lexers/csvs.rb +44 -0
- data/lib/rouge/lexers/cuda.rb +35 -0
- data/lib/rouge/lexers/cython.rb +151 -0
- data/lib/rouge/lexers/d.rb +177 -0
- data/lib/rouge/lexers/dart.rb +105 -0
- data/lib/rouge/lexers/diff.rb +37 -0
- data/lib/rouge/lexers/digdag.rb +70 -0
- data/lib/rouge/lexers/docker.rb +51 -0
- data/lib/rouge/lexers/dot.rb +69 -0
- data/lib/rouge/lexers/ecl.rb +175 -0
- data/lib/rouge/lexers/eex.rb +52 -0
- data/lib/rouge/lexers/eiffel.rb +66 -0
- data/lib/rouge/lexers/elixir.rb +149 -0
- data/lib/rouge/lexers/elm.rb +90 -0
- data/lib/rouge/lexers/epp.rb +51 -0
- data/lib/rouge/lexers/erb.rb +53 -0
- data/lib/rouge/lexers/erlang.rb +115 -0
- data/lib/rouge/lexers/escape.rb +58 -0
- data/lib/rouge/lexers/factor.rb +303 -0
- data/lib/rouge/lexers/fortran.rb +178 -0
- data/lib/rouge/lexers/freefem.rb +240 -0
- data/lib/rouge/lexers/fsharp.rb +119 -0
- data/lib/rouge/lexers/gdscript.rb +171 -0
- data/lib/rouge/lexers/ghc_core.rb +151 -0
- data/lib/rouge/lexers/gherkin.rb +140 -0
- data/lib/rouge/lexers/gherkin/keywords.rb +16 -0
- data/lib/rouge/lexers/glsl.rb +132 -0
- data/lib/rouge/lexers/go.rb +175 -0
- data/lib/rouge/lexers/gradle.rb +38 -0
- data/lib/rouge/lexers/graphql.rb +261 -0
- data/lib/rouge/lexers/groovy.rb +111 -0
- data/lib/rouge/lexers/hack.rb +49 -0
- data/lib/rouge/lexers/haml.rb +226 -0
- data/lib/rouge/lexers/handlebars.rb +91 -0
- data/lib/rouge/lexers/haskell.rb +199 -0
- data/lib/rouge/lexers/haxe.rb +246 -0
- data/lib/rouge/lexers/hcl.rb +163 -0
- data/lib/rouge/lexers/hocon.rb +86 -0
- data/lib/rouge/lexers/hql.rb +139 -0
- data/lib/rouge/lexers/html.rb +141 -0
- data/lib/rouge/lexers/http.rb +81 -0
- data/lib/rouge/lexers/hylang.rb +94 -0
- data/lib/rouge/lexers/idlang.rb +312 -0
- data/lib/rouge/lexers/igorpro.rb +664 -0
- data/lib/rouge/lexers/ini.rb +54 -0
- data/lib/rouge/lexers/io.rb +69 -0
- data/lib/rouge/lexers/irb.rb +67 -0
- data/lib/rouge/lexers/java.rb +91 -0
- data/lib/rouge/lexers/javascript.rb +279 -0
- data/lib/rouge/lexers/jinja.rb +154 -0
- data/lib/rouge/lexers/jsl.rb +55 -0
- data/lib/rouge/lexers/json.rb +69 -0
- data/lib/rouge/lexers/json_doc.rb +25 -0
- data/lib/rouge/lexers/jsonnet.rb +152 -0
- data/lib/rouge/lexers/jsp.rb +120 -0
- data/lib/rouge/lexers/jsx.rb +104 -0
- data/lib/rouge/lexers/julia.rb +290 -0
- data/lib/rouge/lexers/kotlin.rb +127 -0
- data/lib/rouge/lexers/lasso.rb +215 -0
- data/lib/rouge/lexers/lasso/keywords.yml +446 -0
- data/lib/rouge/lexers/liquid.rb +285 -0
- data/lib/rouge/lexers/literate_coffeescript.rb +34 -0
- data/lib/rouge/lexers/literate_haskell.rb +37 -0
- data/lib/rouge/lexers/llvm.rb +97 -0
- data/lib/rouge/lexers/lua.rb +164 -0
- data/lib/rouge/lexers/lua/builtins.rb +24 -0
- data/lib/rouge/lexers/lustre.rb +79 -0
- data/lib/rouge/lexers/lutin.rb +33 -0
- data/lib/rouge/lexers/m68k.rb +143 -0
- data/lib/rouge/lexers/magik.rb +127 -0
- data/lib/rouge/lexers/make.rb +135 -0
- data/lib/rouge/lexers/markdown.rb +182 -0
- data/lib/rouge/lexers/mason.rb +110 -0
- data/lib/rouge/lexers/mathematica.rb +96 -0
- data/lib/rouge/lexers/mathematica/builtins.rb +13 -0
- data/lib/rouge/lexers/matlab.rb +81 -0
- data/lib/rouge/lexers/matlab/builtins.yml +3515 -0
- data/lib/rouge/lexers/minizinc.rb +87 -0
- data/lib/rouge/lexers/moonscript.rb +115 -0
- data/lib/rouge/lexers/mosel.rb +232 -0
- data/lib/rouge/lexers/msgtrans.rb +26 -0
- data/lib/rouge/lexers/mxml.rb +69 -0
- data/lib/rouge/lexers/nasm.rb +72 -0
- data/lib/rouge/lexers/nesasm.rb +78 -0
- data/lib/rouge/lexers/nginx.rb +72 -0
- data/lib/rouge/lexers/nim.rb +154 -0
- data/lib/rouge/lexers/nix.rb +211 -0
- data/lib/rouge/lexers/objective_c.rb +21 -0
- data/lib/rouge/lexers/objective_c/common.rb +184 -0
- data/lib/rouge/lexers/objective_cpp.rb +31 -0
- data/lib/rouge/lexers/ocaml.rb +65 -0
- data/lib/rouge/lexers/ocaml/common.rb +53 -0
- data/lib/rouge/lexers/openedge.rb +429 -0
- data/lib/rouge/lexers/opentype_feature_file.rb +113 -0
- data/lib/rouge/lexers/pascal.rb +67 -0
- data/lib/rouge/lexers/perl.rb +231 -0
- data/lib/rouge/lexers/php.rb +216 -0
- data/lib/rouge/lexers/php/builtins.rb +203 -0
- data/lib/rouge/lexers/plain_text.rb +27 -0
- data/lib/rouge/lexers/plist.rb +47 -0
- data/lib/rouge/lexers/pony.rb +94 -0
- data/lib/rouge/lexers/powershell.rb +230 -0
- data/lib/rouge/lexers/praat.rb +351 -0
- data/lib/rouge/lexers/prolog.rb +67 -0
- data/lib/rouge/lexers/prometheus.rb +123 -0
- data/lib/rouge/lexers/properties.rb +52 -0
- data/lib/rouge/lexers/protobuf.rb +71 -0
- data/lib/rouge/lexers/puppet.rb +129 -0
- data/lib/rouge/lexers/python.rb +248 -0
- data/lib/rouge/lexers/q.rb +126 -0
- data/lib/rouge/lexers/qml.rb +74 -0
- data/lib/rouge/lexers/r.rb +89 -0
- data/lib/rouge/lexers/racket.rb +545 -0
- data/lib/rouge/lexers/reasonml.rb +65 -0
- data/lib/rouge/lexers/robot_framework.rb +249 -0
- data/lib/rouge/lexers/ruby.rb +444 -0
- data/lib/rouge/lexers/rust.rb +193 -0
- data/lib/rouge/lexers/sas.rb +563 -0
- data/lib/rouge/lexers/sass.rb +75 -0
- data/lib/rouge/lexers/sass/common.rb +181 -0
- data/lib/rouge/lexers/scala.rb +169 -0
- data/lib/rouge/lexers/scheme.rb +113 -0
- data/lib/rouge/lexers/scss.rb +35 -0
- data/lib/rouge/lexers/sed.rb +173 -0
- data/lib/rouge/lexers/shell.rb +201 -0
- data/lib/rouge/lexers/sieve.rb +97 -0
- data/lib/rouge/lexers/slice.rb +32 -0
- data/lib/rouge/lexers/slim.rb +229 -0
- data/lib/rouge/lexers/smalltalk.rb +117 -0
- data/lib/rouge/lexers/smarty.rb +81 -0
- data/lib/rouge/lexers/sml.rb +345 -0
- data/lib/rouge/lexers/sparql.rb +129 -0
- data/lib/rouge/lexers/sqf.rb +109 -0
- data/lib/rouge/lexers/sqf/commands.rb +15 -0
- data/lib/rouge/lexers/sql.rb +161 -0
- data/lib/rouge/lexers/supercollider.rb +116 -0
- data/lib/rouge/lexers/swift.rb +186 -0
- data/lib/rouge/lexers/tap.rb +89 -0
- data/lib/rouge/lexers/tcl.rb +193 -0
- data/lib/rouge/lexers/terraform.rb +113 -0
- data/lib/rouge/lexers/tex.rb +70 -0
- data/lib/rouge/lexers/toml.rb +106 -0
- data/lib/rouge/lexers/tsx.rb +20 -0
- data/lib/rouge/lexers/ttcn3.rb +119 -0
- data/lib/rouge/lexers/tulip.rb +108 -0
- data/lib/rouge/lexers/turtle.rb +61 -0
- data/lib/rouge/lexers/twig.rb +40 -0
- data/lib/rouge/lexers/typescript.rb +30 -0
- data/lib/rouge/lexers/typescript/common.rb +34 -0
- data/lib/rouge/lexers/vala.rb +78 -0
- data/lib/rouge/lexers/varnish.rb +168 -0
- data/lib/rouge/lexers/vb.rb +165 -0
- data/lib/rouge/lexers/verilog.rb +163 -0
- data/lib/rouge/lexers/vhdl.rb +98 -0
- data/lib/rouge/lexers/viml.rb +102 -0
- data/lib/rouge/lexers/viml/keywords.rb +14 -0
- data/lib/rouge/lexers/vue.rb +124 -0
- data/lib/rouge/lexers/wollok.rb +104 -0
- data/lib/rouge/lexers/xml.rb +54 -0
- data/lib/rouge/lexers/xojo.rb +61 -0
- data/lib/rouge/lexers/xpath.rb +332 -0
- data/lib/rouge/lexers/xquery.rb +145 -0
- data/lib/rouge/lexers/yaml.rb +376 -0
- data/lib/rouge/plugins/redcarpet.rb +37 -0
- data/lib/rouge/regex_lexer.rb +443 -0
- data/lib/rouge/template_lexer.rb +21 -0
- data/lib/rouge/tex_theme_renderer.rb +132 -0
- data/lib/rouge/text_analyzer.rb +50 -0
- data/lib/rouge/theme.rb +218 -0
- data/lib/rouge/themes/base16.rb +131 -0
- data/lib/rouge/themes/bw.rb +41 -0
- data/lib/rouge/themes/colorful.rb +68 -0
- data/lib/rouge/themes/github.rb +72 -0
- data/lib/rouge/themes/gruvbox.rb +168 -0
- data/lib/rouge/themes/igor_pro.rb +21 -0
- data/lib/rouge/themes/magritte.rb +78 -0
- data/lib/rouge/themes/molokai.rb +83 -0
- data/lib/rouge/themes/monokai.rb +93 -0
- data/lib/rouge/themes/monokai_sublime.rb +93 -0
- data/lib/rouge/themes/pastie.rb +70 -0
- data/lib/rouge/themes/thankful_eyes.rb +75 -0
- data/lib/rouge/themes/tulip.rb +70 -0
- data/lib/rouge/token.rb +191 -0
- data/lib/rouge/util.rb +102 -0
- data/lib/rouge/version.rb +8 -0
- data/rouge.gemspec +26 -0
- metadata +476 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Rouge
|
|
4
|
+
module Guessers
|
|
5
|
+
class Source < Guesser
|
|
6
|
+
include Util
|
|
7
|
+
|
|
8
|
+
attr_reader :source
|
|
9
|
+
def initialize(source)
|
|
10
|
+
@source = source
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def filter(lexers)
|
|
14
|
+
# don't bother reading the input if
|
|
15
|
+
# we've already filtered to 1
|
|
16
|
+
return lexers if lexers.size == 1
|
|
17
|
+
|
|
18
|
+
source_text = get_source(@source)
|
|
19
|
+
|
|
20
|
+
Lexer.assert_utf8!(source_text)
|
|
21
|
+
|
|
22
|
+
source_text = TextAnalyzer.new(source_text)
|
|
23
|
+
|
|
24
|
+
collect_best(lexers) do |lexer|
|
|
25
|
+
next unless lexer.detectable?
|
|
26
|
+
lexer.detect?(source_text) ? 1 : nil
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Rouge
|
|
4
|
+
module Guessers
|
|
5
|
+
module Util
|
|
6
|
+
module SourceNormalizer
|
|
7
|
+
UTF8_BOM = "\xEF\xBB\xBF"
|
|
8
|
+
UTF8_BOM_RE = /\A#{UTF8_BOM}/
|
|
9
|
+
|
|
10
|
+
# @param [String,nil] source
|
|
11
|
+
# @return [String,nil]
|
|
12
|
+
def self.normalize(source)
|
|
13
|
+
source.sub(UTF8_BOM_RE, '').gsub(/\r\n/, "\n")
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def test_glob(pattern, path)
|
|
18
|
+
File.fnmatch?(pattern, path, File::FNM_DOTMATCH | File::FNM_CASEFOLD)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# @param [String,IO] source
|
|
22
|
+
# @return [String]
|
|
23
|
+
def get_source(source)
|
|
24
|
+
if source.respond_to?(:to_str)
|
|
25
|
+
SourceNormalizer.normalize(source.to_str)
|
|
26
|
+
elsif source.respond_to?(:read)
|
|
27
|
+
SourceNormalizer.normalize(source.read)
|
|
28
|
+
else
|
|
29
|
+
raise ArgumentError, "Invalid source: #{source.inspect}"
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
data/lib/rouge/lexer.rb
ADDED
|
@@ -0,0 +1,516 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*- #
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
# stdlib
|
|
5
|
+
require 'strscan'
|
|
6
|
+
require 'cgi'
|
|
7
|
+
require 'set'
|
|
8
|
+
|
|
9
|
+
module Rouge
|
|
10
|
+
# @abstract
|
|
11
|
+
# A lexer transforms text into a stream of `[token, chunk]` pairs.
|
|
12
|
+
class Lexer
|
|
13
|
+
include Token::Tokens
|
|
14
|
+
|
|
15
|
+
@option_docs = {}
|
|
16
|
+
|
|
17
|
+
class << self
|
|
18
|
+
# Lexes `stream` with the given options. The lex is delegated to a
|
|
19
|
+
# new instance.
|
|
20
|
+
#
|
|
21
|
+
# @see #lex
|
|
22
|
+
def lex(stream, opts={}, &b)
|
|
23
|
+
new(opts).lex(stream, &b)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# In case #continue_lex is called statically, we simply
|
|
27
|
+
# begin a new lex from the beginning, since there is no state.
|
|
28
|
+
#
|
|
29
|
+
# @see #continue_lex
|
|
30
|
+
def continue_lex(*a, &b)
|
|
31
|
+
lex(*a, &b)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Given a name in string, return the correct lexer class.
|
|
35
|
+
# @param [String] name
|
|
36
|
+
# @return [Class<Rouge::Lexer>,nil]
|
|
37
|
+
def find(name)
|
|
38
|
+
registry[name.to_s]
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Find a lexer, with fancy shiny features.
|
|
42
|
+
#
|
|
43
|
+
# * The string you pass can include CGI-style options
|
|
44
|
+
#
|
|
45
|
+
# Lexer.find_fancy('erb?parent=tex')
|
|
46
|
+
#
|
|
47
|
+
# * You can pass the special name 'guess' so we guess for you,
|
|
48
|
+
# and you can pass a second argument of the code to guess by
|
|
49
|
+
#
|
|
50
|
+
# Lexer.find_fancy('guess', "#!/bin/bash\necho Hello, world")
|
|
51
|
+
#
|
|
52
|
+
# If the code matches more than one lexer then Guesser::Ambiguous
|
|
53
|
+
# is raised.
|
|
54
|
+
#
|
|
55
|
+
# This is used in the Redcarpet plugin as well as Rouge's own
|
|
56
|
+
# markdown lexer for highlighting internal code blocks.
|
|
57
|
+
#
|
|
58
|
+
def find_fancy(str, code=nil, additional_options={})
|
|
59
|
+
|
|
60
|
+
if str && !str.include?('?') && str != 'guess'
|
|
61
|
+
lexer_class = find(str)
|
|
62
|
+
return lexer_class && lexer_class.new(additional_options)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
name, opts = str ? str.split('?', 2) : [nil, '']
|
|
66
|
+
|
|
67
|
+
# parse the options hash from a cgi-style string
|
|
68
|
+
opts = CGI.parse(opts || '').map do |k, vals|
|
|
69
|
+
val = case vals.size
|
|
70
|
+
when 0 then true
|
|
71
|
+
when 1 then vals[0]
|
|
72
|
+
else vals
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
[ k.to_s, val ]
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
opts = additional_options.merge(Hash[opts])
|
|
79
|
+
|
|
80
|
+
lexer_class = case name
|
|
81
|
+
when 'guess', nil
|
|
82
|
+
self.guess(:source => code, :mimetype => opts['mimetype'])
|
|
83
|
+
when String
|
|
84
|
+
self.find(name)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
lexer_class && lexer_class.new(opts)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# Specify or get this lexer's title. Meant to be human-readable.
|
|
91
|
+
def title(t=nil)
|
|
92
|
+
if t.nil?
|
|
93
|
+
t = tag.capitalize
|
|
94
|
+
end
|
|
95
|
+
@title ||= t
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# Specify or get this lexer's description.
|
|
99
|
+
def desc(arg=:absent)
|
|
100
|
+
if arg == :absent
|
|
101
|
+
@desc
|
|
102
|
+
else
|
|
103
|
+
@desc = arg
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def option_docs
|
|
108
|
+
@option_docs ||= InheritableHash.new(superclass.option_docs)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def option(name, desc)
|
|
112
|
+
option_docs[name.to_s] = desc
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# Specify or get the path name containing a small demo for
|
|
116
|
+
# this lexer (can be overriden by {demo}).
|
|
117
|
+
def demo_file(arg=:absent)
|
|
118
|
+
return @demo_file = Pathname.new(arg) unless arg == :absent
|
|
119
|
+
|
|
120
|
+
@demo_file = Pathname.new(File.join(__dir__, 'demos', tag))
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# Specify or get a small demo string for this lexer
|
|
124
|
+
def demo(arg=:absent)
|
|
125
|
+
return @demo = arg unless arg == :absent
|
|
126
|
+
|
|
127
|
+
@demo = File.read(demo_file, mode: 'rt:bom|utf-8')
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
# @return a list of all lexers.
|
|
131
|
+
def all
|
|
132
|
+
@all ||= registry.values.uniq
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
# Guess which lexer to use based on a hash of info.
|
|
136
|
+
#
|
|
137
|
+
# This accepts the same arguments as Lexer.guess, but will never throw
|
|
138
|
+
# an error. It will return a (possibly empty) list of potential lexers
|
|
139
|
+
# to use.
|
|
140
|
+
def guesses(info={})
|
|
141
|
+
mimetype, filename, source = info.values_at(:mimetype, :filename, :source)
|
|
142
|
+
custom_globs = info[:custom_globs]
|
|
143
|
+
|
|
144
|
+
guessers = (info[:guessers] || []).dup
|
|
145
|
+
|
|
146
|
+
guessers << Guessers::Mimetype.new(mimetype) if mimetype
|
|
147
|
+
guessers << Guessers::GlobMapping.by_pairs(custom_globs, filename) if custom_globs && filename
|
|
148
|
+
guessers << Guessers::Filename.new(filename) if filename
|
|
149
|
+
guessers << Guessers::Modeline.new(source) if source
|
|
150
|
+
guessers << Guessers::Source.new(source) if source
|
|
151
|
+
guessers << Guessers::Disambiguation.new(filename, source) if source && filename
|
|
152
|
+
|
|
153
|
+
Guesser.guess(guessers, Lexer.all)
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
# Guess which lexer to use based on a hash of info.
|
|
157
|
+
#
|
|
158
|
+
# @option info :mimetype
|
|
159
|
+
# A mimetype to guess by
|
|
160
|
+
# @option info :filename
|
|
161
|
+
# A filename to guess by
|
|
162
|
+
# @option info :source
|
|
163
|
+
# The source itself, which, if guessing by mimetype or filename
|
|
164
|
+
# fails, will be searched for shebangs, <!DOCTYPE ...> tags, and
|
|
165
|
+
# other hints.
|
|
166
|
+
# @param [Proc] fallback called if multiple lexers are detected.
|
|
167
|
+
# If omitted, Guesser::Ambiguous is raised.
|
|
168
|
+
#
|
|
169
|
+
# @see Lexer.detect?
|
|
170
|
+
# @see Lexer.guesses
|
|
171
|
+
# @return [Class<Rouge::Lexer>]
|
|
172
|
+
def guess(info={}, &fallback)
|
|
173
|
+
lexers = guesses(info)
|
|
174
|
+
|
|
175
|
+
return Lexers::PlainText if lexers.empty?
|
|
176
|
+
return lexers[0] if lexers.size == 1
|
|
177
|
+
|
|
178
|
+
if fallback
|
|
179
|
+
fallback.call(lexers)
|
|
180
|
+
else
|
|
181
|
+
raise Guesser::Ambiguous.new(lexers)
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
def guess_by_mimetype(mt)
|
|
186
|
+
guess :mimetype => mt
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
def guess_by_filename(fname)
|
|
190
|
+
guess :filename => fname
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
def guess_by_source(source)
|
|
194
|
+
guess :source => source
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
def enable_debug!
|
|
198
|
+
@debug_enabled = true
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
def disable_debug!
|
|
202
|
+
remove_instance_variable :@debug_enabled if defined? @debug_enabled
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
def debug_enabled?
|
|
206
|
+
(defined? @debug_enabled) ? true : false
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
# Determine if a lexer has a method named +:detect?+ defined in its
|
|
210
|
+
# singleton class.
|
|
211
|
+
def detectable?
|
|
212
|
+
return @detectable if defined?(@detectable)
|
|
213
|
+
@detectable = singleton_methods(false).include?(:detect?)
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
protected
|
|
217
|
+
# @private
|
|
218
|
+
def register(name, lexer)
|
|
219
|
+
# reset an existing list of lexers
|
|
220
|
+
@all = nil if defined?(@all)
|
|
221
|
+
registry[name.to_s] = lexer
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
public
|
|
225
|
+
# Used to specify or get the canonical name of this lexer class.
|
|
226
|
+
#
|
|
227
|
+
# @example
|
|
228
|
+
# class MyLexer < Lexer
|
|
229
|
+
# tag 'foo'
|
|
230
|
+
# end
|
|
231
|
+
#
|
|
232
|
+
# MyLexer.tag # => 'foo'
|
|
233
|
+
#
|
|
234
|
+
# Lexer.find('foo') # => MyLexer
|
|
235
|
+
def tag(t=nil)
|
|
236
|
+
return @tag if t.nil?
|
|
237
|
+
|
|
238
|
+
@tag = t.to_s
|
|
239
|
+
Lexer.register(@tag, self)
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
# Used to specify alternate names this lexer class may be found by.
|
|
243
|
+
#
|
|
244
|
+
# @example
|
|
245
|
+
# class Erb < Lexer
|
|
246
|
+
# tag 'erb'
|
|
247
|
+
# aliases 'eruby', 'rhtml'
|
|
248
|
+
# end
|
|
249
|
+
#
|
|
250
|
+
# Lexer.find('eruby') # => Erb
|
|
251
|
+
def aliases(*args)
|
|
252
|
+
args.map!(&:to_s)
|
|
253
|
+
args.each { |arg| Lexer.register(arg, self) }
|
|
254
|
+
(@aliases ||= []).concat(args)
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
# Specify a list of filename globs associated with this lexer.
|
|
258
|
+
#
|
|
259
|
+
# If a filename glob is associated with more than one lexer, this can
|
|
260
|
+
# cause a Guesser::Ambiguous error to be raised in various guessing
|
|
261
|
+
# methods. These errors can be avoided by disambiguation. Filename globs
|
|
262
|
+
# are disambiguated in one of two ways. Either the lexer will define a
|
|
263
|
+
# `self.detect?` method (intended for use with shebangs and doctypes) or a
|
|
264
|
+
# manual rule will be specified in Guessers::Disambiguation.
|
|
265
|
+
#
|
|
266
|
+
# @example
|
|
267
|
+
# class Ruby < Lexer
|
|
268
|
+
# filenames '*.rb', '*.ruby', 'Gemfile', 'Rakefile'
|
|
269
|
+
# end
|
|
270
|
+
def filenames(*fnames)
|
|
271
|
+
(@filenames ||= []).concat(fnames)
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
# Specify a list of mimetypes associated with this lexer.
|
|
275
|
+
#
|
|
276
|
+
# @example
|
|
277
|
+
# class Html < Lexer
|
|
278
|
+
# mimetypes 'text/html', 'application/xhtml+xml'
|
|
279
|
+
# end
|
|
280
|
+
def mimetypes(*mts)
|
|
281
|
+
(@mimetypes ||= []).concat(mts)
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
# @private
|
|
285
|
+
def assert_utf8!(str)
|
|
286
|
+
encoding = str.encoding.name
|
|
287
|
+
return if encoding == 'US-ASCII' || encoding == 'UTF-8' || encoding == 'ASCII-8BIT'
|
|
288
|
+
|
|
289
|
+
raise EncodingError.new(
|
|
290
|
+
"Bad encoding: #{str.encoding.names.join(',')}. " +
|
|
291
|
+
"Please convert your string to UTF-8."
|
|
292
|
+
)
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
private
|
|
296
|
+
def registry
|
|
297
|
+
@registry ||= {}
|
|
298
|
+
end
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
# -*- instance methods -*- #
|
|
302
|
+
|
|
303
|
+
attr_reader :options
|
|
304
|
+
# Create a new lexer with the given options. Individual lexers may
|
|
305
|
+
# specify extra options. The only current globally accepted option
|
|
306
|
+
# is `:debug`.
|
|
307
|
+
#
|
|
308
|
+
# @option opts :debug
|
|
309
|
+
# Prints debug information to stdout. The particular info depends
|
|
310
|
+
# on the lexer in question. In regex lexers, this will log the
|
|
311
|
+
# state stack at the beginning of each step, along with each regex
|
|
312
|
+
# tried and each stream consumed. Try it, it's pretty useful.
|
|
313
|
+
def initialize(opts={})
|
|
314
|
+
@options = {}
|
|
315
|
+
opts.each { |k, v| @options[k.to_s] = v }
|
|
316
|
+
|
|
317
|
+
@debug = Lexer.debug_enabled? && bool_option('debug')
|
|
318
|
+
end
|
|
319
|
+
|
|
320
|
+
def as_bool(val)
|
|
321
|
+
case val
|
|
322
|
+
when nil, false, 0, '0', 'false', 'off'
|
|
323
|
+
false
|
|
324
|
+
when Array
|
|
325
|
+
val.empty? ? true : as_bool(val.last)
|
|
326
|
+
else
|
|
327
|
+
true
|
|
328
|
+
end
|
|
329
|
+
end
|
|
330
|
+
|
|
331
|
+
def as_string(val)
|
|
332
|
+
return as_string(val.last) if val.is_a?(Array)
|
|
333
|
+
|
|
334
|
+
val ? val.to_s : nil
|
|
335
|
+
end
|
|
336
|
+
|
|
337
|
+
def as_list(val)
|
|
338
|
+
case val
|
|
339
|
+
when Array
|
|
340
|
+
val.flat_map { |v| as_list(v) }
|
|
341
|
+
when String
|
|
342
|
+
val.split(',')
|
|
343
|
+
else
|
|
344
|
+
[]
|
|
345
|
+
end
|
|
346
|
+
end
|
|
347
|
+
|
|
348
|
+
def as_lexer(val)
|
|
349
|
+
return as_lexer(val.last) if val.is_a?(Array)
|
|
350
|
+
return val.new(@options) if val.is_a?(Class) && val < Lexer
|
|
351
|
+
|
|
352
|
+
case val
|
|
353
|
+
when Lexer
|
|
354
|
+
val
|
|
355
|
+
when String
|
|
356
|
+
lexer_class = Lexer.find(val)
|
|
357
|
+
lexer_class && lexer_class.new(@options)
|
|
358
|
+
end
|
|
359
|
+
end
|
|
360
|
+
|
|
361
|
+
def as_token(val)
|
|
362
|
+
return as_token(val.last) if val.is_a?(Array)
|
|
363
|
+
case val
|
|
364
|
+
when Token
|
|
365
|
+
val
|
|
366
|
+
else
|
|
367
|
+
Token[val]
|
|
368
|
+
end
|
|
369
|
+
end
|
|
370
|
+
|
|
371
|
+
def bool_option(name, &default)
|
|
372
|
+
name_str = name.to_s
|
|
373
|
+
|
|
374
|
+
if @options.key?(name_str)
|
|
375
|
+
as_bool(@options[name_str])
|
|
376
|
+
else
|
|
377
|
+
default ? default.call : false
|
|
378
|
+
end
|
|
379
|
+
end
|
|
380
|
+
|
|
381
|
+
def string_option(name, &default)
|
|
382
|
+
as_string(@options.delete(name.to_s, &default))
|
|
383
|
+
end
|
|
384
|
+
|
|
385
|
+
def lexer_option(name, &default)
|
|
386
|
+
as_lexer(@options.delete(name.to_s, &default))
|
|
387
|
+
end
|
|
388
|
+
|
|
389
|
+
def list_option(name, &default)
|
|
390
|
+
as_list(@options.delete(name.to_s, &default))
|
|
391
|
+
end
|
|
392
|
+
|
|
393
|
+
def token_option(name, &default)
|
|
394
|
+
as_token(@options.delete(name.to_s, &default))
|
|
395
|
+
end
|
|
396
|
+
|
|
397
|
+
def hash_option(name, defaults, &val_cast)
|
|
398
|
+
name = name.to_s
|
|
399
|
+
out = defaults.dup
|
|
400
|
+
|
|
401
|
+
base = @options.delete(name.to_s)
|
|
402
|
+
base = {} unless base.is_a?(Hash)
|
|
403
|
+
base.each { |k, v| out[k.to_s] = val_cast ? val_cast.call(v) : v }
|
|
404
|
+
|
|
405
|
+
@options.keys.each do |key|
|
|
406
|
+
next unless key =~ /(\w+)\[(\w+)\]/ and $1 == name
|
|
407
|
+
value = @options.delete(key)
|
|
408
|
+
|
|
409
|
+
out[$2] = val_cast ? val_cast.call(value) : value
|
|
410
|
+
end
|
|
411
|
+
|
|
412
|
+
out
|
|
413
|
+
end
|
|
414
|
+
|
|
415
|
+
# @abstract
|
|
416
|
+
#
|
|
417
|
+
# Called after each lex is finished. The default implementation
|
|
418
|
+
# is a noop.
|
|
419
|
+
def reset!
|
|
420
|
+
end
|
|
421
|
+
|
|
422
|
+
# Given a string, yield [token, chunk] pairs. If no block is given,
|
|
423
|
+
# an enumerator is returned.
|
|
424
|
+
#
|
|
425
|
+
# @option opts :continue
|
|
426
|
+
# Continue the lex from the previous state (i.e. don't call #reset!)
|
|
427
|
+
#
|
|
428
|
+
# @note The use of :continue => true has been deprecated. A warning is
|
|
429
|
+
# issued if run with `$VERBOSE` set to true.
|
|
430
|
+
#
|
|
431
|
+
# @note The use of arbitrary `opts` has never been supported, but we
|
|
432
|
+
# previously ignored them with no error. We now warn unconditionally.
|
|
433
|
+
def lex(string, opts=nil, &b)
|
|
434
|
+
if opts
|
|
435
|
+
if (opts.keys - [:continue]).size > 0
|
|
436
|
+
# improper use of options hash
|
|
437
|
+
warn('Improper use of Lexer#lex - this method does not receive options.' +
|
|
438
|
+
' This will become an error in a future version.')
|
|
439
|
+
end
|
|
440
|
+
|
|
441
|
+
if opts[:continue]
|
|
442
|
+
warn '`lex :continue => true` is deprecated, please use #continue_lex instead'
|
|
443
|
+
return continue_lex(string, &b)
|
|
444
|
+
end
|
|
445
|
+
end
|
|
446
|
+
|
|
447
|
+
return enum_for(:lex, string) unless block_given?
|
|
448
|
+
|
|
449
|
+
Lexer.assert_utf8!(string)
|
|
450
|
+
reset!
|
|
451
|
+
|
|
452
|
+
continue_lex(string, &b)
|
|
453
|
+
end
|
|
454
|
+
|
|
455
|
+
# Continue the lex from the the current state without resetting
|
|
456
|
+
def continue_lex(string, &b)
|
|
457
|
+
return enum_for(:continue_lex, string, &b) unless block_given?
|
|
458
|
+
|
|
459
|
+
# consolidate consecutive tokens of the same type
|
|
460
|
+
last_token = nil
|
|
461
|
+
last_val = nil
|
|
462
|
+
stream_tokens(string) do |tok, val|
|
|
463
|
+
next if val.empty?
|
|
464
|
+
|
|
465
|
+
if tok == last_token
|
|
466
|
+
last_val << val
|
|
467
|
+
next
|
|
468
|
+
end
|
|
469
|
+
|
|
470
|
+
b.call(last_token, last_val) if last_token
|
|
471
|
+
last_token = tok
|
|
472
|
+
last_val = val
|
|
473
|
+
end
|
|
474
|
+
|
|
475
|
+
b.call(last_token, last_val) if last_token
|
|
476
|
+
end
|
|
477
|
+
|
|
478
|
+
# delegated to {Lexer.tag}
|
|
479
|
+
def tag
|
|
480
|
+
self.class.tag
|
|
481
|
+
end
|
|
482
|
+
|
|
483
|
+
# @abstract
|
|
484
|
+
#
|
|
485
|
+
# Yield `[token, chunk]` pairs, given a prepared input stream. This
|
|
486
|
+
# must be implemented.
|
|
487
|
+
#
|
|
488
|
+
# @param [StringScanner] stream
|
|
489
|
+
# the stream
|
|
490
|
+
def stream_tokens(stream, &b)
|
|
491
|
+
raise 'abstract'
|
|
492
|
+
end
|
|
493
|
+
|
|
494
|
+
# @abstract
|
|
495
|
+
#
|
|
496
|
+
# Return true if there is an in-text indication (such as a shebang
|
|
497
|
+
# or DOCTYPE declaration) that this lexer should be used.
|
|
498
|
+
#
|
|
499
|
+
# @param [TextAnalyzer] text
|
|
500
|
+
# the text to be analyzed, with a couple of handy methods on it,
|
|
501
|
+
# like {TextAnalyzer#shebang?} and {TextAnalyzer#doctype?}
|
|
502
|
+
def self.detect?(text)
|
|
503
|
+
false
|
|
504
|
+
end
|
|
505
|
+
end
|
|
506
|
+
|
|
507
|
+
module Lexers
|
|
508
|
+
@_loaded_lexers = {}
|
|
509
|
+
|
|
510
|
+
def self.load_lexer(relpath)
|
|
511
|
+
return if @_loaded_lexers.key?(relpath)
|
|
512
|
+
@_loaded_lexers[relpath] = true
|
|
513
|
+
load File.join(__dir__, 'lexers', relpath)
|
|
514
|
+
end
|
|
515
|
+
end
|
|
516
|
+
end
|