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.
Files changed (429) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +40 -0
  3. data/LICENSE +186 -0
  4. data/bin/rougify +18 -0
  5. data/lib/rouge.rb +93 -0
  6. data/lib/rouge/cli.rb +498 -0
  7. data/lib/rouge/demos/abap +6 -0
  8. data/lib/rouge/demos/actionscript +4 -0
  9. data/lib/rouge/demos/ada +26 -0
  10. data/lib/rouge/demos/apache +21 -0
  11. data/lib/rouge/demos/apex +9 -0
  12. data/lib/rouge/demos/apiblueprint +33 -0
  13. data/lib/rouge/demos/applescript +2 -0
  14. data/lib/rouge/demos/armasm +12 -0
  15. data/lib/rouge/demos/awk +4 -0
  16. data/lib/rouge/demos/batchfile +3 -0
  17. data/lib/rouge/demos/bbcbasic +6 -0
  18. data/lib/rouge/demos/biml +38 -0
  19. data/lib/rouge/demos/bpf +7 -0
  20. data/lib/rouge/demos/brainfuck +5 -0
  21. data/lib/rouge/demos/bsl +7 -0
  22. data/lib/rouge/demos/c +8 -0
  23. data/lib/rouge/demos/ceylon +7 -0
  24. data/lib/rouge/demos/cfscript +18 -0
  25. data/lib/rouge/demos/clean +6 -0
  26. data/lib/rouge/demos/clojure +5 -0
  27. data/lib/rouge/demos/cmake +7 -0
  28. data/lib/rouge/demos/cmhg +8 -0
  29. data/lib/rouge/demos/coffeescript +5 -0
  30. data/lib/rouge/demos/common_lisp +1 -0
  31. data/lib/rouge/demos/conf +4 -0
  32. data/lib/rouge/demos/console +6 -0
  33. data/lib/rouge/demos/coq +13 -0
  34. data/lib/rouge/demos/cpp +8 -0
  35. data/lib/rouge/demos/crystal +45 -0
  36. data/lib/rouge/demos/csharp +5 -0
  37. data/lib/rouge/demos/css +4 -0
  38. data/lib/rouge/demos/csvs +8 -0
  39. data/lib/rouge/demos/cuda +11 -0
  40. data/lib/rouge/demos/cython +6 -0
  41. data/lib/rouge/demos/d +16 -0
  42. data/lib/rouge/demos/dart +6 -0
  43. data/lib/rouge/demos/diff +7 -0
  44. data/lib/rouge/demos/digdag +19 -0
  45. data/lib/rouge/demos/docker +9 -0
  46. data/lib/rouge/demos/dot +5 -0
  47. data/lib/rouge/demos/ecl +18 -0
  48. data/lib/rouge/demos/eex +1 -0
  49. data/lib/rouge/demos/eiffel +30 -0
  50. data/lib/rouge/demos/elixir +1 -0
  51. data/lib/rouge/demos/elm +4 -0
  52. data/lib/rouge/demos/epp +4 -0
  53. data/lib/rouge/demos/erb +1 -0
  54. data/lib/rouge/demos/erlang +7 -0
  55. data/lib/rouge/demos/escape +3 -0
  56. data/lib/rouge/demos/factor +5 -0
  57. data/lib/rouge/demos/fortran +22 -0
  58. data/lib/rouge/demos/freefem +16 -0
  59. data/lib/rouge/demos/fsharp +12 -0
  60. data/lib/rouge/demos/gdscript +18 -0
  61. data/lib/rouge/demos/ghc-core +26 -0
  62. data/lib/rouge/demos/gherkin +17 -0
  63. data/lib/rouge/demos/glsl +14 -0
  64. data/lib/rouge/demos/go +7 -0
  65. data/lib/rouge/demos/gradle +10 -0
  66. data/lib/rouge/demos/graphql +17 -0
  67. data/lib/rouge/demos/groovy +9 -0
  68. data/lib/rouge/demos/hack +5 -0
  69. data/lib/rouge/demos/haml +5 -0
  70. data/lib/rouge/demos/handlebars +7 -0
  71. data/lib/rouge/demos/haskell +6 -0
  72. data/lib/rouge/demos/haxe +5 -0
  73. data/lib/rouge/demos/hcl +7 -0
  74. data/lib/rouge/demos/hocon +8 -0
  75. data/lib/rouge/demos/hql +5 -0
  76. data/lib/rouge/demos/html +8 -0
  77. data/lib/rouge/demos/http +14 -0
  78. data/lib/rouge/demos/hylang +10 -0
  79. data/lib/rouge/demos/idlang +8 -0
  80. data/lib/rouge/demos/igorpro +9 -0
  81. data/lib/rouge/demos/ini +4 -0
  82. data/lib/rouge/demos/io +11 -0
  83. data/lib/rouge/demos/irb +4 -0
  84. data/lib/rouge/demos/irb_output +2 -0
  85. data/lib/rouge/demos/java +5 -0
  86. data/lib/rouge/demos/javascript +1 -0
  87. data/lib/rouge/demos/jinja +9 -0
  88. data/lib/rouge/demos/jsl +3 -0
  89. data/lib/rouge/demos/json +1 -0
  90. data/lib/rouge/demos/json-doc +1 -0
  91. data/lib/rouge/demos/jsonnet +28 -0
  92. data/lib/rouge/demos/jsp +29 -0
  93. data/lib/rouge/demos/jsx +17 -0
  94. data/lib/rouge/demos/julia +11 -0
  95. data/lib/rouge/demos/kotlin +3 -0
  96. data/lib/rouge/demos/lasso +12 -0
  97. data/lib/rouge/demos/liquid +10 -0
  98. data/lib/rouge/demos/literate_coffeescript +3 -0
  99. data/lib/rouge/demos/literate_haskell +7 -0
  100. data/lib/rouge/demos/llvm +20 -0
  101. data/lib/rouge/demos/lua +12 -0
  102. data/lib/rouge/demos/lustre +6 -0
  103. data/lib/rouge/demos/lutin +18 -0
  104. data/lib/rouge/demos/m68k +16 -0
  105. data/lib/rouge/demos/magik +6 -0
  106. data/lib/rouge/demos/make +6 -0
  107. data/lib/rouge/demos/markdown +4 -0
  108. data/lib/rouge/demos/mason +22 -0
  109. data/lib/rouge/demos/mathematica +8 -0
  110. data/lib/rouge/demos/matlab +6 -0
  111. data/lib/rouge/demos/minizinc +23 -0
  112. data/lib/rouge/demos/moonscript +16 -0
  113. data/lib/rouge/demos/mosel +10 -0
  114. data/lib/rouge/demos/msgtrans +4 -0
  115. data/lib/rouge/demos/mxml +22 -0
  116. data/lib/rouge/demos/nasm +26 -0
  117. data/lib/rouge/demos/nesasm +11 -0
  118. data/lib/rouge/demos/nginx +5 -0
  119. data/lib/rouge/demos/nim +27 -0
  120. data/lib/rouge/demos/nix +19 -0
  121. data/lib/rouge/demos/objective_c +18 -0
  122. data/lib/rouge/demos/objective_cpp +17 -0
  123. data/lib/rouge/demos/ocaml +12 -0
  124. data/lib/rouge/demos/openedge +4 -0
  125. data/lib/rouge/demos/opentype_feature_file +6 -0
  126. data/lib/rouge/demos/pascal +14 -0
  127. data/lib/rouge/demos/perl +5 -0
  128. data/lib/rouge/demos/php +3 -0
  129. data/lib/rouge/demos/plaintext +1 -0
  130. data/lib/rouge/demos/plist +11 -0
  131. data/lib/rouge/demos/pony +17 -0
  132. data/lib/rouge/demos/powershell +13 -0
  133. data/lib/rouge/demos/praat +26 -0
  134. data/lib/rouge/demos/prolog +9 -0
  135. data/lib/rouge/demos/prometheus +9 -0
  136. data/lib/rouge/demos/properties +7 -0
  137. data/lib/rouge/demos/protobuf +5 -0
  138. data/lib/rouge/demos/puppet +6 -0
  139. data/lib/rouge/demos/python +6 -0
  140. data/lib/rouge/demos/q +8 -0
  141. data/lib/rouge/demos/qml +9 -0
  142. data/lib/rouge/demos/r +8 -0
  143. data/lib/rouge/demos/racket +24 -0
  144. data/lib/rouge/demos/reasonml +12 -0
  145. data/lib/rouge/demos/robot_framework +27 -0
  146. data/lib/rouge/demos/ruby +9 -0
  147. data/lib/rouge/demos/rust +12 -0
  148. data/lib/rouge/demos/sas +13 -0
  149. data/lib/rouge/demos/sass +3 -0
  150. data/lib/rouge/demos/scala +3 -0
  151. data/lib/rouge/demos/scheme +4 -0
  152. data/lib/rouge/demos/scss +5 -0
  153. data/lib/rouge/demos/sed +4 -0
  154. data/lib/rouge/demos/shell +2 -0
  155. data/lib/rouge/demos/sieve +10 -0
  156. data/lib/rouge/demos/slice +10 -0
  157. data/lib/rouge/demos/slim +17 -0
  158. data/lib/rouge/demos/smalltalk +6 -0
  159. data/lib/rouge/demos/smarty +12 -0
  160. data/lib/rouge/demos/sml +4 -0
  161. data/lib/rouge/demos/sparql +6 -0
  162. data/lib/rouge/demos/sqf +14 -0
  163. data/lib/rouge/demos/sql +1 -0
  164. data/lib/rouge/demos/supercollider +11 -0
  165. data/lib/rouge/demos/swift +5 -0
  166. data/lib/rouge/demos/tap +5 -0
  167. data/lib/rouge/demos/tcl +1 -0
  168. data/lib/rouge/demos/terraform +16 -0
  169. data/lib/rouge/demos/tex +1 -0
  170. data/lib/rouge/demos/toml +9 -0
  171. data/lib/rouge/demos/tsx +17 -0
  172. data/lib/rouge/demos/ttcn3 +6 -0
  173. data/lib/rouge/demos/tulip +13 -0
  174. data/lib/rouge/demos/turtle +26 -0
  175. data/lib/rouge/demos/twig +9 -0
  176. data/lib/rouge/demos/typescript +1 -0
  177. data/lib/rouge/demos/vala +8 -0
  178. data/lib/rouge/demos/vb +4 -0
  179. data/lib/rouge/demos/vcl +12 -0
  180. data/lib/rouge/demos/verilog +27 -0
  181. data/lib/rouge/demos/vhdl +23 -0
  182. data/lib/rouge/demos/viml +14 -0
  183. data/lib/rouge/demos/vue +11 -0
  184. data/lib/rouge/demos/wollok +11 -0
  185. data/lib/rouge/demos/xml +2 -0
  186. data/lib/rouge/demos/xojo +14 -0
  187. data/lib/rouge/demos/xpath +2 -0
  188. data/lib/rouge/demos/xquery +22 -0
  189. data/lib/rouge/demos/yaml +4 -0
  190. data/lib/rouge/formatter.rb +112 -0
  191. data/lib/rouge/formatters/html.rb +56 -0
  192. data/lib/rouge/formatters/html_inline.rb +31 -0
  193. data/lib/rouge/formatters/html_legacy.rb +45 -0
  194. data/lib/rouge/formatters/html_line_table.rb +53 -0
  195. data/lib/rouge/formatters/html_linewise.rb +23 -0
  196. data/lib/rouge/formatters/html_pygments.rb +18 -0
  197. data/lib/rouge/formatters/html_table.rb +51 -0
  198. data/lib/rouge/formatters/null.rb +20 -0
  199. data/lib/rouge/formatters/terminal256.rb +198 -0
  200. data/lib/rouge/formatters/terminal_truecolor.rb +37 -0
  201. data/lib/rouge/formatters/tex.rb +92 -0
  202. data/lib/rouge/guesser.rb +57 -0
  203. data/lib/rouge/guessers/disambiguation.rb +136 -0
  204. data/lib/rouge/guessers/filename.rb +27 -0
  205. data/lib/rouge/guessers/glob_mapping.rb +45 -0
  206. data/lib/rouge/guessers/mimetype.rb +16 -0
  207. data/lib/rouge/guessers/modeline.rb +46 -0
  208. data/lib/rouge/guessers/source.rb +31 -0
  209. data/lib/rouge/guessers/util.rb +34 -0
  210. data/lib/rouge/lexer.rb +516 -0
  211. data/lib/rouge/lexers/abap.rb +240 -0
  212. data/lib/rouge/lexers/actionscript.rb +196 -0
  213. data/lib/rouge/lexers/ada.rb +162 -0
  214. data/lib/rouge/lexers/apache.rb +73 -0
  215. data/lib/rouge/lexers/apache/keywords.yml +764 -0
  216. data/lib/rouge/lexers/apex.rb +126 -0
  217. data/lib/rouge/lexers/apiblueprint.rb +49 -0
  218. data/lib/rouge/lexers/apple_script.rb +370 -0
  219. data/lib/rouge/lexers/armasm.rb +145 -0
  220. data/lib/rouge/lexers/awk.rb +162 -0
  221. data/lib/rouge/lexers/batchfile.rb +164 -0
  222. data/lib/rouge/lexers/bbcbasic.rb +112 -0
  223. data/lib/rouge/lexers/biml.rb +43 -0
  224. data/lib/rouge/lexers/bpf.rb +118 -0
  225. data/lib/rouge/lexers/brainfuck.rb +53 -0
  226. data/lib/rouge/lexers/bsl.rb +82 -0
  227. data/lib/rouge/lexers/c.rb +190 -0
  228. data/lib/rouge/lexers/ceylon.rb +96 -0
  229. data/lib/rouge/lexers/cfscript.rb +154 -0
  230. data/lib/rouge/lexers/clean.rb +156 -0
  231. data/lib/rouge/lexers/clojure.rb +113 -0
  232. data/lib/rouge/lexers/cmake.rb +207 -0
  233. data/lib/rouge/lexers/cmhg.rb +34 -0
  234. data/lib/rouge/lexers/coffeescript.rb +215 -0
  235. data/lib/rouge/lexers/common_lisp.rb +346 -0
  236. data/lib/rouge/lexers/conf.rb +25 -0
  237. data/lib/rouge/lexers/console.rb +174 -0
  238. data/lib/rouge/lexers/coq.rb +191 -0
  239. data/lib/rouge/lexers/cpp.rb +82 -0
  240. data/lib/rouge/lexers/crystal.rb +430 -0
  241. data/lib/rouge/lexers/csharp.rb +114 -0
  242. data/lib/rouge/lexers/css.rb +274 -0
  243. data/lib/rouge/lexers/csvs.rb +44 -0
  244. data/lib/rouge/lexers/cuda.rb +35 -0
  245. data/lib/rouge/lexers/cython.rb +151 -0
  246. data/lib/rouge/lexers/d.rb +177 -0
  247. data/lib/rouge/lexers/dart.rb +105 -0
  248. data/lib/rouge/lexers/diff.rb +37 -0
  249. data/lib/rouge/lexers/digdag.rb +70 -0
  250. data/lib/rouge/lexers/docker.rb +51 -0
  251. data/lib/rouge/lexers/dot.rb +69 -0
  252. data/lib/rouge/lexers/ecl.rb +175 -0
  253. data/lib/rouge/lexers/eex.rb +52 -0
  254. data/lib/rouge/lexers/eiffel.rb +66 -0
  255. data/lib/rouge/lexers/elixir.rb +149 -0
  256. data/lib/rouge/lexers/elm.rb +90 -0
  257. data/lib/rouge/lexers/epp.rb +51 -0
  258. data/lib/rouge/lexers/erb.rb +53 -0
  259. data/lib/rouge/lexers/erlang.rb +115 -0
  260. data/lib/rouge/lexers/escape.rb +58 -0
  261. data/lib/rouge/lexers/factor.rb +303 -0
  262. data/lib/rouge/lexers/fortran.rb +178 -0
  263. data/lib/rouge/lexers/freefem.rb +240 -0
  264. data/lib/rouge/lexers/fsharp.rb +119 -0
  265. data/lib/rouge/lexers/gdscript.rb +171 -0
  266. data/lib/rouge/lexers/ghc_core.rb +151 -0
  267. data/lib/rouge/lexers/gherkin.rb +140 -0
  268. data/lib/rouge/lexers/gherkin/keywords.rb +16 -0
  269. data/lib/rouge/lexers/glsl.rb +132 -0
  270. data/lib/rouge/lexers/go.rb +175 -0
  271. data/lib/rouge/lexers/gradle.rb +38 -0
  272. data/lib/rouge/lexers/graphql.rb +261 -0
  273. data/lib/rouge/lexers/groovy.rb +111 -0
  274. data/lib/rouge/lexers/hack.rb +49 -0
  275. data/lib/rouge/lexers/haml.rb +226 -0
  276. data/lib/rouge/lexers/handlebars.rb +91 -0
  277. data/lib/rouge/lexers/haskell.rb +199 -0
  278. data/lib/rouge/lexers/haxe.rb +246 -0
  279. data/lib/rouge/lexers/hcl.rb +163 -0
  280. data/lib/rouge/lexers/hocon.rb +86 -0
  281. data/lib/rouge/lexers/hql.rb +139 -0
  282. data/lib/rouge/lexers/html.rb +141 -0
  283. data/lib/rouge/lexers/http.rb +81 -0
  284. data/lib/rouge/lexers/hylang.rb +94 -0
  285. data/lib/rouge/lexers/idlang.rb +312 -0
  286. data/lib/rouge/lexers/igorpro.rb +664 -0
  287. data/lib/rouge/lexers/ini.rb +54 -0
  288. data/lib/rouge/lexers/io.rb +69 -0
  289. data/lib/rouge/lexers/irb.rb +67 -0
  290. data/lib/rouge/lexers/java.rb +91 -0
  291. data/lib/rouge/lexers/javascript.rb +279 -0
  292. data/lib/rouge/lexers/jinja.rb +154 -0
  293. data/lib/rouge/lexers/jsl.rb +55 -0
  294. data/lib/rouge/lexers/json.rb +69 -0
  295. data/lib/rouge/lexers/json_doc.rb +25 -0
  296. data/lib/rouge/lexers/jsonnet.rb +152 -0
  297. data/lib/rouge/lexers/jsp.rb +120 -0
  298. data/lib/rouge/lexers/jsx.rb +104 -0
  299. data/lib/rouge/lexers/julia.rb +290 -0
  300. data/lib/rouge/lexers/kotlin.rb +127 -0
  301. data/lib/rouge/lexers/lasso.rb +215 -0
  302. data/lib/rouge/lexers/lasso/keywords.yml +446 -0
  303. data/lib/rouge/lexers/liquid.rb +285 -0
  304. data/lib/rouge/lexers/literate_coffeescript.rb +34 -0
  305. data/lib/rouge/lexers/literate_haskell.rb +37 -0
  306. data/lib/rouge/lexers/llvm.rb +97 -0
  307. data/lib/rouge/lexers/lua.rb +164 -0
  308. data/lib/rouge/lexers/lua/builtins.rb +24 -0
  309. data/lib/rouge/lexers/lustre.rb +79 -0
  310. data/lib/rouge/lexers/lutin.rb +33 -0
  311. data/lib/rouge/lexers/m68k.rb +143 -0
  312. data/lib/rouge/lexers/magik.rb +127 -0
  313. data/lib/rouge/lexers/make.rb +135 -0
  314. data/lib/rouge/lexers/markdown.rb +182 -0
  315. data/lib/rouge/lexers/mason.rb +110 -0
  316. data/lib/rouge/lexers/mathematica.rb +96 -0
  317. data/lib/rouge/lexers/mathematica/builtins.rb +13 -0
  318. data/lib/rouge/lexers/matlab.rb +81 -0
  319. data/lib/rouge/lexers/matlab/builtins.yml +3515 -0
  320. data/lib/rouge/lexers/minizinc.rb +87 -0
  321. data/lib/rouge/lexers/moonscript.rb +115 -0
  322. data/lib/rouge/lexers/mosel.rb +232 -0
  323. data/lib/rouge/lexers/msgtrans.rb +26 -0
  324. data/lib/rouge/lexers/mxml.rb +69 -0
  325. data/lib/rouge/lexers/nasm.rb +72 -0
  326. data/lib/rouge/lexers/nesasm.rb +78 -0
  327. data/lib/rouge/lexers/nginx.rb +72 -0
  328. data/lib/rouge/lexers/nim.rb +154 -0
  329. data/lib/rouge/lexers/nix.rb +211 -0
  330. data/lib/rouge/lexers/objective_c.rb +21 -0
  331. data/lib/rouge/lexers/objective_c/common.rb +184 -0
  332. data/lib/rouge/lexers/objective_cpp.rb +31 -0
  333. data/lib/rouge/lexers/ocaml.rb +65 -0
  334. data/lib/rouge/lexers/ocaml/common.rb +53 -0
  335. data/lib/rouge/lexers/openedge.rb +429 -0
  336. data/lib/rouge/lexers/opentype_feature_file.rb +113 -0
  337. data/lib/rouge/lexers/pascal.rb +67 -0
  338. data/lib/rouge/lexers/perl.rb +231 -0
  339. data/lib/rouge/lexers/php.rb +216 -0
  340. data/lib/rouge/lexers/php/builtins.rb +203 -0
  341. data/lib/rouge/lexers/plain_text.rb +27 -0
  342. data/lib/rouge/lexers/plist.rb +47 -0
  343. data/lib/rouge/lexers/pony.rb +94 -0
  344. data/lib/rouge/lexers/powershell.rb +230 -0
  345. data/lib/rouge/lexers/praat.rb +351 -0
  346. data/lib/rouge/lexers/prolog.rb +67 -0
  347. data/lib/rouge/lexers/prometheus.rb +123 -0
  348. data/lib/rouge/lexers/properties.rb +52 -0
  349. data/lib/rouge/lexers/protobuf.rb +71 -0
  350. data/lib/rouge/lexers/puppet.rb +129 -0
  351. data/lib/rouge/lexers/python.rb +248 -0
  352. data/lib/rouge/lexers/q.rb +126 -0
  353. data/lib/rouge/lexers/qml.rb +74 -0
  354. data/lib/rouge/lexers/r.rb +89 -0
  355. data/lib/rouge/lexers/racket.rb +545 -0
  356. data/lib/rouge/lexers/reasonml.rb +65 -0
  357. data/lib/rouge/lexers/robot_framework.rb +249 -0
  358. data/lib/rouge/lexers/ruby.rb +444 -0
  359. data/lib/rouge/lexers/rust.rb +193 -0
  360. data/lib/rouge/lexers/sas.rb +563 -0
  361. data/lib/rouge/lexers/sass.rb +75 -0
  362. data/lib/rouge/lexers/sass/common.rb +181 -0
  363. data/lib/rouge/lexers/scala.rb +169 -0
  364. data/lib/rouge/lexers/scheme.rb +113 -0
  365. data/lib/rouge/lexers/scss.rb +35 -0
  366. data/lib/rouge/lexers/sed.rb +173 -0
  367. data/lib/rouge/lexers/shell.rb +201 -0
  368. data/lib/rouge/lexers/sieve.rb +97 -0
  369. data/lib/rouge/lexers/slice.rb +32 -0
  370. data/lib/rouge/lexers/slim.rb +229 -0
  371. data/lib/rouge/lexers/smalltalk.rb +117 -0
  372. data/lib/rouge/lexers/smarty.rb +81 -0
  373. data/lib/rouge/lexers/sml.rb +345 -0
  374. data/lib/rouge/lexers/sparql.rb +129 -0
  375. data/lib/rouge/lexers/sqf.rb +109 -0
  376. data/lib/rouge/lexers/sqf/commands.rb +15 -0
  377. data/lib/rouge/lexers/sql.rb +161 -0
  378. data/lib/rouge/lexers/supercollider.rb +116 -0
  379. data/lib/rouge/lexers/swift.rb +186 -0
  380. data/lib/rouge/lexers/tap.rb +89 -0
  381. data/lib/rouge/lexers/tcl.rb +193 -0
  382. data/lib/rouge/lexers/terraform.rb +113 -0
  383. data/lib/rouge/lexers/tex.rb +70 -0
  384. data/lib/rouge/lexers/toml.rb +106 -0
  385. data/lib/rouge/lexers/tsx.rb +20 -0
  386. data/lib/rouge/lexers/ttcn3.rb +119 -0
  387. data/lib/rouge/lexers/tulip.rb +108 -0
  388. data/lib/rouge/lexers/turtle.rb +61 -0
  389. data/lib/rouge/lexers/twig.rb +40 -0
  390. data/lib/rouge/lexers/typescript.rb +30 -0
  391. data/lib/rouge/lexers/typescript/common.rb +34 -0
  392. data/lib/rouge/lexers/vala.rb +78 -0
  393. data/lib/rouge/lexers/varnish.rb +168 -0
  394. data/lib/rouge/lexers/vb.rb +165 -0
  395. data/lib/rouge/lexers/verilog.rb +163 -0
  396. data/lib/rouge/lexers/vhdl.rb +98 -0
  397. data/lib/rouge/lexers/viml.rb +102 -0
  398. data/lib/rouge/lexers/viml/keywords.rb +14 -0
  399. data/lib/rouge/lexers/vue.rb +124 -0
  400. data/lib/rouge/lexers/wollok.rb +104 -0
  401. data/lib/rouge/lexers/xml.rb +54 -0
  402. data/lib/rouge/lexers/xojo.rb +61 -0
  403. data/lib/rouge/lexers/xpath.rb +332 -0
  404. data/lib/rouge/lexers/xquery.rb +145 -0
  405. data/lib/rouge/lexers/yaml.rb +376 -0
  406. data/lib/rouge/plugins/redcarpet.rb +37 -0
  407. data/lib/rouge/regex_lexer.rb +443 -0
  408. data/lib/rouge/template_lexer.rb +21 -0
  409. data/lib/rouge/tex_theme_renderer.rb +132 -0
  410. data/lib/rouge/text_analyzer.rb +50 -0
  411. data/lib/rouge/theme.rb +218 -0
  412. data/lib/rouge/themes/base16.rb +131 -0
  413. data/lib/rouge/themes/bw.rb +41 -0
  414. data/lib/rouge/themes/colorful.rb +68 -0
  415. data/lib/rouge/themes/github.rb +72 -0
  416. data/lib/rouge/themes/gruvbox.rb +168 -0
  417. data/lib/rouge/themes/igor_pro.rb +21 -0
  418. data/lib/rouge/themes/magritte.rb +78 -0
  419. data/lib/rouge/themes/molokai.rb +83 -0
  420. data/lib/rouge/themes/monokai.rb +93 -0
  421. data/lib/rouge/themes/monokai_sublime.rb +93 -0
  422. data/lib/rouge/themes/pastie.rb +70 -0
  423. data/lib/rouge/themes/thankful_eyes.rb +75 -0
  424. data/lib/rouge/themes/tulip.rb +70 -0
  425. data/lib/rouge/token.rb +191 -0
  426. data/lib/rouge/util.rb +102 -0
  427. data/lib/rouge/version.rb +8 -0
  428. data/rouge.gemspec +26 -0
  429. 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
@@ -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