blusher 0.1.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 (241) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +29 -0
  3. data/Cargo.lock +373 -0
  4. data/Cargo.toml +6 -0
  5. data/LICENSE +25 -0
  6. data/README.md +98 -0
  7. data/ext/blusher/Cargo.toml +18 -0
  8. data/ext/blusher/extconf.rb +10 -0
  9. data/ext/blusher/src/lib.rs +167 -0
  10. data/lib/blusher/native.rb +115 -0
  11. data/lib/blusher/shim.rb +134 -0
  12. data/lib/blusher/tables/abap.json +1 -0
  13. data/lib/blusher/tables/actionscript.json +1 -0
  14. data/lib/blusher/tables/ada.json +1 -0
  15. data/lib/blusher/tables/apache.json +1 -0
  16. data/lib/blusher/tables/apex.json +1 -0
  17. data/lib/blusher/tables/apiblueprint.json +1 -0
  18. data/lib/blusher/tables/applescript.json +1 -0
  19. data/lib/blusher/tables/armasm.json +1 -0
  20. data/lib/blusher/tables/augeas.json +1 -0
  21. data/lib/blusher/tables/awk.json +1 -0
  22. data/lib/blusher/tables/batchfile.json +1 -0
  23. data/lib/blusher/tables/bbcbasic.json +1 -0
  24. data/lib/blusher/tables/bibtex.json +1 -0
  25. data/lib/blusher/tables/bicep.json +1 -0
  26. data/lib/blusher/tables/biml.json +1 -0
  27. data/lib/blusher/tables/bpf.json +1 -0
  28. data/lib/blusher/tables/brainfuck.json +1 -0
  29. data/lib/blusher/tables/brightscript.json +1 -0
  30. data/lib/blusher/tables/bsl.json +1 -0
  31. data/lib/blusher/tables/c.json +1 -0
  32. data/lib/blusher/tables/cfscript.json +1 -0
  33. data/lib/blusher/tables/cisco_ios.json +1 -0
  34. data/lib/blusher/tables/clean.json +1 -0
  35. data/lib/blusher/tables/clojure.json +1 -0
  36. data/lib/blusher/tables/cmake.json +1 -0
  37. data/lib/blusher/tables/cmhg.json +1 -0
  38. data/lib/blusher/tables/cobol.json +1 -0
  39. data/lib/blusher/tables/codeowners.json +1 -0
  40. data/lib/blusher/tables/coffeescript.json +1 -0
  41. data/lib/blusher/tables/common_lisp.json +1 -0
  42. data/lib/blusher/tables/conf.json +1 -0
  43. data/lib/blusher/tables/cpp.json +1 -0
  44. data/lib/blusher/tables/crystal.json +1 -0
  45. data/lib/blusher/tables/csharp.json +1 -0
  46. data/lib/blusher/tables/css.json +1 -0
  47. data/lib/blusher/tables/csvs.json +1 -0
  48. data/lib/blusher/tables/cuda.json +1 -0
  49. data/lib/blusher/tables/cypher.json +1 -0
  50. data/lib/blusher/tables/cython.json +1 -0
  51. data/lib/blusher/tables/d.json +1 -0
  52. data/lib/blusher/tables/dafny.json +1 -0
  53. data/lib/blusher/tables/dart.json +1 -0
  54. data/lib/blusher/tables/datastudio.json +1 -0
  55. data/lib/blusher/tables/diff.json +1 -0
  56. data/lib/blusher/tables/digdag.json +1 -0
  57. data/lib/blusher/tables/docker.json +1 -0
  58. data/lib/blusher/tables/dot.json +1 -0
  59. data/lib/blusher/tables/dylan.json +1 -0
  60. data/lib/blusher/tables/ecl.json +1 -0
  61. data/lib/blusher/tables/eex.json +1 -0
  62. data/lib/blusher/tables/eiffel.json +1 -0
  63. data/lib/blusher/tables/elixir.json +1 -0
  64. data/lib/blusher/tables/elm.json +1 -0
  65. data/lib/blusher/tables/email.json +1 -0
  66. data/lib/blusher/tables/epp.json +1 -0
  67. data/lib/blusher/tables/erb.json +1 -0
  68. data/lib/blusher/tables/erlang.json +1 -0
  69. data/lib/blusher/tables/factor.json +1 -0
  70. data/lib/blusher/tables/fluent.json +1 -0
  71. data/lib/blusher/tables/fortran.json +1 -0
  72. data/lib/blusher/tables/freefem.json +1 -0
  73. data/lib/blusher/tables/fsharp.json +1 -0
  74. data/lib/blusher/tables/gdscript.json +1 -0
  75. data/lib/blusher/tables/ghc-cmm.json +1 -0
  76. data/lib/blusher/tables/ghc-core.json +1 -0
  77. data/lib/blusher/tables/gjs.json +1 -0
  78. data/lib/blusher/tables/glsl.json +1 -0
  79. data/lib/blusher/tables/go.json +1 -0
  80. data/lib/blusher/tables/gradle.json +1 -0
  81. data/lib/blusher/tables/graphql.json +1 -0
  82. data/lib/blusher/tables/groovy.json +1 -0
  83. data/lib/blusher/tables/gts.json +1 -0
  84. data/lib/blusher/tables/hack.json +1 -0
  85. data/lib/blusher/tables/haml.json +1 -0
  86. data/lib/blusher/tables/handlebars.json +1 -0
  87. data/lib/blusher/tables/haskell.json +1 -0
  88. data/lib/blusher/tables/haxe.json +1 -0
  89. data/lib/blusher/tables/hcl.json +1 -0
  90. data/lib/blusher/tables/hlsl.json +1 -0
  91. data/lib/blusher/tables/hocon.json +1 -0
  92. data/lib/blusher/tables/hql.json +1 -0
  93. data/lib/blusher/tables/html.json +1 -0
  94. data/lib/blusher/tables/http.json +1 -0
  95. data/lib/blusher/tables/hylang.json +1 -0
  96. data/lib/blusher/tables/idlang.json +1 -0
  97. data/lib/blusher/tables/idris.json +1 -0
  98. data/lib/blusher/tables/iecst.json +1 -0
  99. data/lib/blusher/tables/igorpro.json +1 -0
  100. data/lib/blusher/tables/ini.json +1 -0
  101. data/lib/blusher/tables/io.json +1 -0
  102. data/lib/blusher/tables/irb_output.json +1 -0
  103. data/lib/blusher/tables/isabelle.json +1 -0
  104. data/lib/blusher/tables/isbl.json +1 -0
  105. data/lib/blusher/tables/j.json +1 -0
  106. data/lib/blusher/tables/janet.json +1 -0
  107. data/lib/blusher/tables/java.json +1 -0
  108. data/lib/blusher/tables/javascript.json +1 -0
  109. data/lib/blusher/tables/jinja.json +1 -0
  110. data/lib/blusher/tables/jsl.json +1 -0
  111. data/lib/blusher/tables/json-doc.json +1 -0
  112. data/lib/blusher/tables/json.json +1 -0
  113. data/lib/blusher/tables/json5.json +1 -0
  114. data/lib/blusher/tables/jsonnet.json +1 -0
  115. data/lib/blusher/tables/jsp.json +1 -0
  116. data/lib/blusher/tables/jsx.json +1 -0
  117. data/lib/blusher/tables/julia.json +1 -0
  118. data/lib/blusher/tables/kick_assembler.json +1 -0
  119. data/lib/blusher/tables/kotlin.json +1 -0
  120. data/lib/blusher/tables/lasso.json +1 -0
  121. data/lib/blusher/tables/lean.json +1 -0
  122. data/lib/blusher/tables/liquid.json +1 -0
  123. data/lib/blusher/tables/literate_coffeescript.json +1 -0
  124. data/lib/blusher/tables/literate_haskell.json +1 -0
  125. data/lib/blusher/tables/livescript.json +1 -0
  126. data/lib/blusher/tables/llvm.json +1 -0
  127. data/lib/blusher/tables/lua.json +1 -0
  128. data/lib/blusher/tables/lustre.json +1 -0
  129. data/lib/blusher/tables/lutin.json +1 -0
  130. data/lib/blusher/tables/m68k.json +1 -0
  131. data/lib/blusher/tables/magik.json +1 -0
  132. data/lib/blusher/tables/make.json +1 -0
  133. data/lib/blusher/tables/markdown.json +1 -0
  134. data/lib/blusher/tables/mason.json +1 -0
  135. data/lib/blusher/tables/mathematica.json +1 -0
  136. data/lib/blusher/tables/matlab.json +1 -0
  137. data/lib/blusher/tables/meson.json +1 -0
  138. data/lib/blusher/tables/minizinc.json +1 -0
  139. data/lib/blusher/tables/mojo.json +1 -0
  140. data/lib/blusher/tables/moonscript.json +1 -0
  141. data/lib/blusher/tables/mosel.json +1 -0
  142. data/lib/blusher/tables/msgtrans.json +1 -0
  143. data/lib/blusher/tables/mxml.json +1 -0
  144. data/lib/blusher/tables/nasm.json +1 -0
  145. data/lib/blusher/tables/nesasm.json +1 -0
  146. data/lib/blusher/tables/nginx.json +1 -0
  147. data/lib/blusher/tables/nial.json +1 -0
  148. data/lib/blusher/tables/nim.json +1 -0
  149. data/lib/blusher/tables/nix.json +1 -0
  150. data/lib/blusher/tables/objective_c.json +1 -0
  151. data/lib/blusher/tables/objective_cpp.json +1 -0
  152. data/lib/blusher/tables/ocaml.json +1 -0
  153. data/lib/blusher/tables/ocl.json +1 -0
  154. data/lib/blusher/tables/openedge.json +1 -0
  155. data/lib/blusher/tables/opentype_feature_file.json +1 -0
  156. data/lib/blusher/tables/p4.json +1 -0
  157. data/lib/blusher/tables/pascal.json +1 -0
  158. data/lib/blusher/tables/pdf.json +1 -0
  159. data/lib/blusher/tables/perl.json +1 -0
  160. data/lib/blusher/tables/php.json +1 -0
  161. data/lib/blusher/tables/plist.json +1 -0
  162. data/lib/blusher/tables/plsql.json +1 -0
  163. data/lib/blusher/tables/pony.json +1 -0
  164. data/lib/blusher/tables/postscript.json +1 -0
  165. data/lib/blusher/tables/powershell.json +1 -0
  166. data/lib/blusher/tables/praat.json +1 -0
  167. data/lib/blusher/tables/prolog.json +1 -0
  168. data/lib/blusher/tables/prometheus.json +1 -0
  169. data/lib/blusher/tables/properties.json +1 -0
  170. data/lib/blusher/tables/protobuf.json +1 -0
  171. data/lib/blusher/tables/puppet.json +1 -0
  172. data/lib/blusher/tables/python.json +1 -0
  173. data/lib/blusher/tables/q.json +1 -0
  174. data/lib/blusher/tables/qml.json +1 -0
  175. data/lib/blusher/tables/r.json +1 -0
  176. data/lib/blusher/tables/racket.json +1 -0
  177. data/lib/blusher/tables/reasonml.json +1 -0
  178. data/lib/blusher/tables/rego.json +1 -0
  179. data/lib/blusher/tables/rescript.json +1 -0
  180. data/lib/blusher/tables/rml.json +1 -0
  181. data/lib/blusher/tables/robot_framework.json +1 -0
  182. data/lib/blusher/tables/rocq.json +1 -0
  183. data/lib/blusher/tables/ruby.json +1 -0
  184. data/lib/blusher/tables/rust.json +1 -0
  185. data/lib/blusher/tables/sas.json +1 -0
  186. data/lib/blusher/tables/sass.json +1 -0
  187. data/lib/blusher/tables/scala.json +1 -0
  188. data/lib/blusher/tables/scheme.json +1 -0
  189. data/lib/blusher/tables/scss.json +1 -0
  190. data/lib/blusher/tables/sed.json +1 -0
  191. data/lib/blusher/tables/shell.json +1 -0
  192. data/lib/blusher/tables/sieve.json +1 -0
  193. data/lib/blusher/tables/slice.json +1 -0
  194. data/lib/blusher/tables/slim.json +1 -0
  195. data/lib/blusher/tables/smalltalk.json +1 -0
  196. data/lib/blusher/tables/smarty.json +1 -0
  197. data/lib/blusher/tables/sml.json +1 -0
  198. data/lib/blusher/tables/sparql.json +1 -0
  199. data/lib/blusher/tables/sqf.json +1 -0
  200. data/lib/blusher/tables/sql.json +1 -0
  201. data/lib/blusher/tables/ssh.json +1 -0
  202. data/lib/blusher/tables/stan.json +1 -0
  203. data/lib/blusher/tables/stata.json +1 -0
  204. data/lib/blusher/tables/supercollider.json +1 -0
  205. data/lib/blusher/tables/svelte.json +1 -0
  206. data/lib/blusher/tables/swift.json +1 -0
  207. data/lib/blusher/tables/systemd.json +1 -0
  208. data/lib/blusher/tables/syzlang.json +1 -0
  209. data/lib/blusher/tables/syzprog.json +1 -0
  210. data/lib/blusher/tables/tap.json +1 -0
  211. data/lib/blusher/tables/tcl.json +1 -0
  212. data/lib/blusher/tables/terraform.json +1 -0
  213. data/lib/blusher/tables/tex.json +1 -0
  214. data/lib/blusher/tables/thrift.json +1 -0
  215. data/lib/blusher/tables/toml.json +1 -0
  216. data/lib/blusher/tables/tsx.json +1 -0
  217. data/lib/blusher/tables/ttcn3.json +1 -0
  218. data/lib/blusher/tables/tulip.json +1 -0
  219. data/lib/blusher/tables/turtle.json +1 -0
  220. data/lib/blusher/tables/twig.json +1 -0
  221. data/lib/blusher/tables/typescript.json +1 -0
  222. data/lib/blusher/tables/vala.json +1 -0
  223. data/lib/blusher/tables/vb.json +1 -0
  224. data/lib/blusher/tables/vcl.json +1 -0
  225. data/lib/blusher/tables/velocity.json +1 -0
  226. data/lib/blusher/tables/verilog.json +1 -0
  227. data/lib/blusher/tables/veryl.json +1 -0
  228. data/lib/blusher/tables/vhdl.json +1 -0
  229. data/lib/blusher/tables/viml.json +1 -0
  230. data/lib/blusher/tables/vue.json +1 -0
  231. data/lib/blusher/tables/wollok.json +1 -0
  232. data/lib/blusher/tables/xml.json +1 -0
  233. data/lib/blusher/tables/xojo.json +1 -0
  234. data/lib/blusher/tables/xpath.json +1 -0
  235. data/lib/blusher/tables/xquery.json +1 -0
  236. data/lib/blusher/tables/yaml.json +1 -0
  237. data/lib/blusher/tables/yang.json +1 -0
  238. data/lib/blusher/tables/zig.json +1 -0
  239. data/lib/blusher/version.rb +5 -0
  240. data/lib/blusher.rb +18 -0
  241. metadata +320 -0
@@ -0,0 +1,167 @@
1
+ //! `blusher` CRuby extension (magnus): the carmine engine bound to MRI,
2
+ //! building the token array DIRECTLY as Ruby objects — no JSON round trip,
3
+ //! no per-token re-parse. This is what brings the gem to PARITY with rouge;
4
+ //! the FFI/JSON bootstrap was a net loss. carmine's raw lexing speedup does
5
+ //! not survive the Ruby-object marshaling at the boundary (token allocation
6
+ //! dominates and rouge pays it too); see benchmark/bench.rb and the README.
7
+ //!
8
+ //! `Blusher::Engine.lex(table_json, input, qualname_map)` returns:
9
+ //! - an Array of `[Rouge::Token, value]` pairs on success,
10
+ //! - `nil` when a callback rule blocks native lexing (caller → rouge),
11
+ //! - raises RuntimeError on a bad table.
12
+ //!
13
+ //! `qualname_map` is rouge's qualname→Token Hash (`Blusher::Shim::QUALNAME`).
14
+ //! Resolving the Token in Rust — via a `hash[name]` aref — lets us skip
15
+ //! building an intermediate `[name, value]` array that the Ruby side would
16
+ //! then have to re-map: we fold the old Ruby `to_rouge` pass into this one.
17
+ //! Unknown names fall back to the `"Error"` entry of the same map (rouge's
18
+ //! `Rouge::Token::Tokens::Error`, whose qualname is `"Error"`).
19
+
20
+ use std::cell::RefCell;
21
+ use std::collections::HashMap;
22
+ use std::rc::Rc;
23
+
24
+ use carmine::{Lexer, LexerTable, NoCallbacks};
25
+ use magnus::r_hash::ForEach;
26
+ use magnus::{function, prelude::*, value::Value, Error, RArray, RHash, RString, Ruby};
27
+
28
+ thread_local! {
29
+ // Parsed-and-compiled tables, keyed by lexer tag. Building a LexerTable
30
+ // (JSON parse + regex compile) is ~0.5ms and INPUT-INDEPENDENT, so re-doing
31
+ // it per call dwarfs the actual lex on small files. A lexer's table is
32
+ // immutable for the process lifetime, so caching it makes repeat lexes of a
33
+ // language pay that cost once. Thread-local (no lock); each Ruby thread that
34
+ // touches the engine builds its own — fine, tables are cheap to hold.
35
+ static TABLE_CACHE: RefCell<HashMap<String, Rc<LexerTable>>> = RefCell::new(HashMap::new());
36
+ }
37
+
38
+ /// Cached parse of `table_json` under `tag`. First call for a tag parses;
39
+ /// subsequent calls reuse the compiled table.
40
+ fn cached_table(ruby: &Ruby, tag: &str, table_json: &str) -> Result<Rc<LexerTable>, Error> {
41
+ if let Some(t) = TABLE_CACHE.with(|c| c.borrow().get(tag).cloned()) {
42
+ return Ok(t);
43
+ }
44
+ let table = LexerTable::from_json(table_json)
45
+ .map_err(|e| Error::new(ruby.exception_runtime_error(), format!("blusher table: {e}")))?;
46
+ let rc = Rc::new(table);
47
+ TABLE_CACHE.with(|c| c.borrow_mut().insert(tag.to_string(), rc.clone()));
48
+ Ok(rc)
49
+ }
50
+
51
+ /// Append `val` to `out` with rouge's HTML escaping: `& < >` become entities,
52
+ /// `\r` is dropped, everything else verbatim (mirrors `TABLE_FOR_ESCAPE_HTML`).
53
+ fn escape_html_into(val: &str, out: &mut String) {
54
+ for ch in val.chars() {
55
+ match ch {
56
+ '&' => out.push_str("&amp;"),
57
+ '<' => out.push_str("&lt;"),
58
+ '>' => out.push_str("&gt;"),
59
+ '\r' => {}
60
+ c => out.push(c),
61
+ }
62
+ }
63
+ }
64
+
65
+ /// Fused lex + `Rouge::Formatters::HTML` formatting, entirely in Rust, returning
66
+ /// a SINGLE Ruby String — the whole point: real rouge use produces HTML, and a
67
+ /// token stream is only an intermediate. Doing both here means O(1) Ruby
68
+ /// allocations instead of one String + one Array per token, so carmine's raw
69
+ /// lexing speed finally survives to the Ruby boundary.
70
+ ///
71
+ /// Byte-faithful to the DEFAULT path (escape disabled): `filter_escapes`
72
+ /// rewrites the `Escape` token to `Error`; the bare `Text` token (shortname "")
73
+ /// emits its escaped value with no span; every other token emits
74
+ /// `<span class="SHORTNAME">escaped</span>`. The caller only routes here for an
75
+ /// exact `Rouge::Formatters::HTML` instance with escape disabled and no block,
76
+ /// so subclasses (HTMLInline/Debug/Pygments/…) keep rouge's own output.
77
+ ///
78
+ /// `shortname` is rouge's qualname→shortname Hash; it is read into a Rust map
79
+ /// ONCE per call (≈1k entries) so the per-token lookups never touch Ruby.
80
+ /// Returns `nil` to decline (callback rule reached → caller falls back).
81
+ fn format_html(
82
+ ruby: &Ruby,
83
+ tag: String,
84
+ table_json: String,
85
+ input: String,
86
+ shortname: RHash,
87
+ ) -> Result<Value, Error> {
88
+ let table = cached_table(ruby, &tag, &table_json)?;
89
+
90
+ let mut sn: HashMap<String, String> = HashMap::new();
91
+ shortname.foreach(|k: String, v: String| {
92
+ sn.insert(k, v);
93
+ Ok(ForEach::Continue)
94
+ })?;
95
+
96
+ let mut lexer = Lexer::new(&table);
97
+ match lexer.lex(&input, &mut NoCallbacks) {
98
+ Ok(toks) => {
99
+ let mut out = String::with_capacity(input.len() * 2);
100
+ for (t, v) in &toks {
101
+ let mut name = table.token_name(*t);
102
+ if name == "Escape" {
103
+ name = "Error"; // filter_escapes (escape disabled — the default)
104
+ }
105
+ match sn.get(name).map(String::as_str) {
106
+ // bare Text token — no span wrapper
107
+ Some("") => escape_html_into(v.as_str(), &mut out),
108
+ Some(short) => {
109
+ out.push_str("<span class=\"");
110
+ out.push_str(short);
111
+ out.push_str("\">");
112
+ escape_html_into(v.as_str(), &mut out);
113
+ out.push_str("</span>");
114
+ }
115
+ // unknown token name: rouge would raise; decline to be safe.
116
+ None => return Ok(ruby.qnil().as_value()),
117
+ }
118
+ }
119
+ Ok(RString::new(&out).as_value())
120
+ }
121
+ Err(carmine::Error::CallbackRequired { .. }) => Ok(ruby.qnil().as_value()),
122
+ Err(e) => Err(Error::new(ruby.exception_runtime_error(), format!("blusher format: {e}"))),
123
+ }
124
+ }
125
+
126
+ fn lex(
127
+ ruby: &Ruby,
128
+ tag: String,
129
+ table_json: String,
130
+ input: String,
131
+ qualname: RHash,
132
+ ) -> Result<Value, Error> {
133
+ let table = cached_table(ruby, &tag, &table_json)?;
134
+
135
+ // Fallback token for names rouge doesn't know — resolved once from the map.
136
+ let error_tok: Value = qualname.get("Error").unwrap_or_else(|| ruby.qnil().as_value());
137
+
138
+ let mut lexer = Lexer::new(&table);
139
+ match lexer.lex(&input, &mut NoCallbacks) {
140
+ Ok(toks) => {
141
+ let out = RArray::with_capacity(toks.len());
142
+ for (t, v) in &toks {
143
+ let name = table.token_name(*t);
144
+ let tok: Value = match qualname.get(name) {
145
+ Some(found) => found,
146
+ None => error_tok,
147
+ };
148
+ let pair = RArray::with_capacity(2);
149
+ pair.push(tok)?;
150
+ pair.push(v.as_str())?;
151
+ out.push(pair)?;
152
+ }
153
+ Ok(out.as_value())
154
+ }
155
+ // Callback rule reachable — decline (the shim falls back to rouge).
156
+ Err(carmine::Error::CallbackRequired { .. }) => Ok(ruby.qnil().as_value()),
157
+ Err(e) => Err(Error::new(ruby.exception_runtime_error(), format!("blusher lex: {e}"))),
158
+ }
159
+ }
160
+
161
+ #[magnus::init(name = "blusher")]
162
+ fn init(ruby: &Ruby) -> Result<(), Error> {
163
+ let engine = ruby.define_module("Blusher")?.define_module("Engine")?;
164
+ engine.define_singleton_method("lex", function!(lex, 4))?;
165
+ engine.define_singleton_method("format_html", function!(format_html, 4))?;
166
+ Ok(())
167
+ }
@@ -0,0 +1,115 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rbconfig"
4
+
5
+ module Blusher
6
+ # The native boundary to the carmine engine. Coarse lex-or-decline contract:
7
+ # `Native.lex(table_json, input)` returns either
8
+ # - an Array of [token_qualname, value] String pairs (carmine lexed it), or
9
+ # - nil (a callback rule blocks native lexing → caller falls back to rouge).
10
+ #
11
+ # Two backends, in preference order:
12
+ # 1. the rb-sys/magnus native extension (`blusher.{bundle,so}`), which
13
+ # builds the token Array DIRECTLY as Ruby objects — no JSON round-trip.
14
+ # This is the release path and the only one that beats rouge.
15
+ # 2. the `carmine-ffi` cdylib via Fiddle, marshaling tokens through JSON.
16
+ # A dependency-light bootstrap kept for environments without the
17
+ # precompiled ext; the JSON serialize/parse makes it a net loss vs rouge,
18
+ # so it exists for correctness/coverage, not speed.
19
+ module Native
20
+ DLEXT = (RbConfig::CONFIG["host_os"] =~ /darwin/ ? "dylib" : "so")
21
+
22
+ # --- backend 1: magnus native extension --------------------------------
23
+ # The loadable object's name must match the `Init_blusher` symbol and use
24
+ # the platform's Ruby ext suffix (.bundle/.so) — `require` won't load a raw
25
+ # cargo `.dylib`. `rake compile` stages it here from the cargo target dir.
26
+ EXT_CANDIDATES = [
27
+ # gem-installed by rake-compiler: lib/blusher/blusher.<dlext>
28
+ File.expand_path("blusher.#{RbConfig::CONFIG["DLEXT"]}", __dir__),
29
+ # dev: `rake compile` stages the cargo build at lib/blusher.<dlext>
30
+ File.expand_path("../blusher.#{RbConfig::CONFIG["DLEXT"]}", __dir__),
31
+ File.expand_path("../blusher.bundle", __dir__),
32
+ File.expand_path("../blusher.so", __dir__),
33
+ ].freeze
34
+
35
+ @backend = nil
36
+
37
+ ext = EXT_CANDIDATES.find { |p| File.exist?(p) }
38
+ if ext
39
+ require ext
40
+ @backend = :ext
41
+ end
42
+
43
+ # --- backend 2: carmine-ffi via Fiddle ---------------------------------
44
+ unless @backend
45
+ require "fiddle"
46
+ require "json"
47
+
48
+ FFI_CANDIDATES = [
49
+ File.expand_path("../../ext/libcarmine_ffi.#{DLEXT}", __dir__),
50
+ File.expand_path("../../../target/release/libcarmine_ffi.#{DLEXT}", __dir__),
51
+ File.expand_path("../../../target/debug/libcarmine_ffi.#{DLEXT}", __dir__),
52
+ ].freeze
53
+
54
+ path = FFI_CANDIDATES.find { |p| File.exist?(p) }
55
+ unless path
56
+ raise LoadError,
57
+ "blusher: no native backend found (run `rake compile`). " \
58
+ "Looked for the magnus ext in #{EXT_CANDIDATES} and carmine-ffi in #{FFI_CANDIDATES}"
59
+ end
60
+
61
+ LIB = Fiddle.dlopen(path)
62
+ FFI_LEX = Fiddle::Function.new(
63
+ LIB["carmine_lex"],
64
+ [Fiddle::TYPE_VOIDP, Fiddle::TYPE_VOIDP, Fiddle::TYPE_SIZE_T],
65
+ Fiddle::TYPE_VOIDP
66
+ )
67
+ FFI_FREE = Fiddle::Function.new(LIB["carmine_free"], [Fiddle::TYPE_VOIDP], Fiddle::TYPE_VOID)
68
+ @backend = :ffi
69
+ end
70
+
71
+ class << self
72
+ attr_reader :backend
73
+ end
74
+
75
+ # Both backends return [Token, value] pairs (or nil to decline). `qualname`
76
+ # is rouge's qualname→Token Hash; the ext resolves Tokens in Rust (one pass,
77
+ # no intermediate name-string array), the FFI path maps in Ruby.
78
+ # `tag` keys the ext's parsed-table cache (parse+regex-compile is ~0.5ms and
79
+ # input-independent, so it must not repeat per call).
80
+ if @backend == :ext
81
+ def self.lex(tag, table_json, input, qualname)
82
+ Blusher::Engine.lex(tag, table_json, input, qualname)
83
+ end
84
+
85
+ # Fused lex + HTML formatting in Rust — returns one HTML String (or nil to
86
+ # decline). Only the magnus ext supports this; it is the path that makes
87
+ # blusher faster than rouge (no per-token Ruby object crosses the boundary).
88
+ def self.format_html(tag, table_json, input, shortname)
89
+ Blusher::Engine.format_html(tag, table_json, input, shortname)
90
+ end
91
+ else
92
+ def self.lex(_tag, table_json, input, qualname)
93
+ ptr = FFI_LEX.call(table_json, input, input.bytesize)
94
+ begin
95
+ result = JSON.parse(ptr.to_s)
96
+ ensure
97
+ FFI_FREE.call(ptr)
98
+ end
99
+ return nil unless result["status"] == "ok"
100
+ error = qualname["Error"]
101
+ result["tokens"].map { |name, val| [qualname[name] || error, val] }
102
+ end
103
+
104
+ # The FFI/JSON backend can't fuse profitably (it would re-cross the JSON
105
+ # boundary); decline so the shim uses rouge's formatter on FFI tokens.
106
+ def self.format_html(_tag, _table_json, _input, _shortname)
107
+ nil
108
+ end
109
+ end
110
+
111
+ def self.fused_html?
112
+ @backend == :ext
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,134 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rouge"
4
+
5
+ module Blusher
6
+ # The rouge-API drop-in: route every `RegexLexer#lex` through carmine when a
7
+ # table exists AND carmine handles the input natively; otherwise fall back to
8
+ # rouge unchanged. Zero-divergence by construction — carmine either returns a
9
+ # byte-identical token stream or declines.
10
+ module Shim
11
+ # qualified rouge token name ("Name.Builtin") → the Token object.
12
+ QUALNAME = {}
13
+ Rouge::Token.each_token { |t| QUALNAME[t.qualname] = t }
14
+ QUALNAME.freeze
15
+
16
+ # qualified token name → rouge HTML shortname ("Name.Function" → "nf",
17
+ # "Text" → ""). Passed to the fused Rust formatter so the whole lex+format
18
+ # pipeline produces one HTML String without materializing Ruby tokens.
19
+ SHORTNAME = {}
20
+ Rouge::Token.each_token { |t| SHORTNAME[t.qualname] = t.shortname if t.shortname }
21
+ SHORTNAME.freeze
22
+
23
+ # A deferred token stream: returned by the patched `RegexLexer#lex` when no
24
+ # block is given, so the lexer + source travel together to the formatter.
25
+ # `Rouge::Formatters::HTML#format` can then fuse lex+format in Rust (one
26
+ # String, no per-token Ruby objects). Any OTHER consumer just iterates it —
27
+ # `#each` lexes via carmine on demand, yielding the same [Token, value]
28
+ # pairs rouge would, so it is a transparent drop-in for `lex`'s old return.
29
+ class TokenStream
30
+ include Enumerable
31
+ attr_reader :lexer, :source
32
+
33
+ def initialize(lexer, source)
34
+ @lexer = lexer
35
+ @source = source
36
+ end
37
+
38
+ def tag
39
+ @lexer.class.tag
40
+ end
41
+
42
+ def each(&b)
43
+ return enum_for(:each) unless b
44
+ toks = Blusher::Native.lex(tag, Shim.table_for(tag), @source, QUALNAME)
45
+ toks ||= @lexer.__blusher_rouge_lex(@source).to_a
46
+ toks.each(&b)
47
+ end
48
+ end
49
+
50
+ @dir = File.expand_path("tables", __dir__)
51
+ @cache = {}
52
+ @routable = {}
53
+
54
+ class << self
55
+ # Directory of per-lexer carmine tables (`<tag>.json`). Generated by
56
+ # `rake tables` (carmine's tools/extract.rb over the installed rouge).
57
+ attr_accessor :dir
58
+
59
+ def table_for(tag)
60
+ return @cache[tag] if @cache.key?(tag)
61
+ path = File.join(@dir, "#{tag}.json")
62
+ @cache[tag] = (File.read(path) if File.exist?(path))
63
+ end
64
+
65
+ # Whether a table is worth attempting natively. A table that contains a
66
+ # `callback` rule (rouge procs / recursion that carmine can't execute)
67
+ # DECLINES the moment that rule is reached — and then rouge re-lexes the
68
+ # whole input from scratch, so the carmine attempt was pure wasted work.
69
+ # For a performance drop-in that net-loses, so we skip such lexers up
70
+ # front and let rouge own them. Verdict is a cheap substring scan over
71
+ # the raw table JSON (no parse), cached per tag. Zero-divergence holds:
72
+ # callback-free tables never decline, skipped tables run rouge verbatim.
73
+ def routable?(tag)
74
+ return @routable[tag] if @routable.key?(tag)
75
+ table = table_for(tag)
76
+ @routable[tag] = !table.nil? && !table.include?('"kind":"callback"')
77
+ end
78
+ end
79
+ end
80
+ end
81
+
82
+ module Rouge
83
+ class RegexLexer
84
+ # Install once (idempotent if the gem is required twice).
85
+ unless method_defined?(:__blusher_rouge_lex)
86
+ alias_method :__blusher_rouge_lex, :lex
87
+
88
+ def lex(string, opts = nil, &b)
89
+ tag = self.class.tag
90
+ # :continue (incremental relex) isn't expressible against carmine — and
91
+ # non-routable lexers gain nothing — so hand those straight to rouge.
92
+ return __blusher_rouge_lex(string, opts, &b) if (opts && opts[:continue]) ||
93
+ !Blusher::Shim.routable?(tag)
94
+
95
+ if b
96
+ # Block form (the caller wants tokens now): lex via carmine and stream.
97
+ toks = Blusher::Native.lex(tag, Blusher::Shim.table_for(tag), string, Blusher::Shim::QUALNAME)
98
+ return toks ? toks.each(&b) : __blusher_rouge_lex(string, opts, &b)
99
+ end
100
+
101
+ # No block: defer, so HTML#format can fuse lex+format in Rust.
102
+ Blusher::Shim::TokenStream.new(self, string)
103
+ end
104
+ end
105
+ end
106
+
107
+ module Formatters
108
+ class HTML
109
+ # Fuse lex+format for the common, hot path — `Rouge.highlight`/Jekyll do
110
+ # `formatter.format(lexer.lex(src))`. When the tokens are a deferred
111
+ # blusher TokenStream and this is an unadorned HTML formatter (escape
112
+ # disabled, no streaming block, exact class — subclasses like HTMLInline
113
+ # render differently), carmine lexes AND formats in Rust, returning one
114
+ # HTML String. Otherwise (or if carmine declines) fall back to rouge's
115
+ # formatter over the iterated stream — byte-identical either way.
116
+ unless method_defined?(:__blusher_html_format)
117
+ alias_method :__blusher_html_format, :format
118
+
119
+ def format(tokens, &b)
120
+ if !b &&
121
+ instance_of?(Rouge::Formatters::HTML) &&
122
+ !Rouge::Formatter.escape_enabled? &&
123
+ tokens.is_a?(Blusher::Shim::TokenStream)
124
+ html = Blusher::Native.format_html(
125
+ tokens.tag, Blusher::Shim.table_for(tokens.tag), tokens.source, Blusher::Shim::SHORTNAME
126
+ )
127
+ return html if html
128
+ end
129
+ __blusher_html_format(tokens, &b)
130
+ end
131
+ end
132
+ end
133
+ end
134
+ end
@@ -0,0 +1 @@
1
+ {"lexer":"Rouge::Lexers::ABAP","start_push":[],"states":{"root":[{"kind":"tok","re":"\\s+","opts":4,"tok":"Text","next":null},{"kind":"tok","re":"(\".*?$)","opts":0,"tok":"Comment.Single","next":null},{"kind":"tok","re":"(^\\*.*?$)","opts":0,"tok":"Comment.Single","next":null},{"kind":"tok","re":"\\d+","opts":0,"tok":"Literal.Number.Integer","next":null},{"kind":"tok","re":"\\|","opts":0,"tok":"Literal.String.Interpol","next":"string_template"},{"kind":"tok","re":"('|`)","opts":0,"tok":"Literal.String.Single","next":"single_string"},{"kind":"callback","re":"(@)([A-Z][A-Za-z0-9_]*)(\\.)([A-Za-z][A-Za-z0-9_]*)","opts":0},{"kind":"ir","re":"([A-Za-z][A-Za-z0-9_]*)(\\.)([A-Za-z][A-Za-z0-9_]*)","opts":0,"ops":[["token","Name",["g",1]],["token","Punctuation",["g",2]],["token","Name",["g",3]]]},{"kind":"ir","re":"([A-Za-z][A-Za-z0-9_]*)(?=\\s*=)","opts":0,"ops":[["token","Name",["g",1]]]},{"kind":"tok","re":"[\\[\\]\\(\\)\\{\\}\\.,:]","opts":0,"tok":"Punctuation","next":null},{"kind":"callback","re":"(->|=>)?([A-Za-z][A-Za-z0-9_\\-]*)(\\()","opts":0},{"kind":"callback","re":"[A-Za-z][A-Za-z0-9_]*(-[A-Za-z][A-Za-z0-9_]*)+","opts":0},{"kind":"tok","re":"[A-Za-z][A-Za-z0-9_]*-[a-z][A-Za-z0-9_]*","opts":0,"tok":"Name","next":null},{"kind":"tok","re":"\\$[A-Za-z][A-Za-z0-9_]*","opts":0,"tok":"Name","next":null},{"kind":"callback","re":"\\w\\w*","opts":0},{"kind":"tok","re":"(->|->>|=>)","opts":0,"tok":"Operator","next":null},{"kind":"tok","re":"[-\\*\\+%/~=&\\?<>!#\\@\\^]+","opts":0,"tok":"Operator","next":null}],"operators":[{"kind":"tok","re":"(->|->>|=>)","opts":0,"tok":"Operator","next":null},{"kind":"tok","re":"[-\\*\\+%/~=&\\?<>!#\\@\\^]+","opts":0,"tok":"Operator","next":null}],"single_string":[{"kind":"tok","re":"\\\\.","opts":0,"tok":"Literal.String.Escape","next":null},{"kind":"tok","re":"(''|``)","opts":0,"tok":"Literal.String.Escape","next":null},{"kind":"tok","re":"['`]","opts":0,"tok":"Literal.String.Single","next":"pop!"},{"kind":"tok","re":"[^\\\\'`]+","opts":0,"tok":"Literal.String.Single","next":null}],"string_template":[{"kind":"tok","re":"\\{[^}]*\\}","opts":0,"tok":"Literal.String.Interpol","next":null},{"kind":"tok","re":"\\|","opts":0,"tok":"Literal.String.Interpol","next":"pop!"},{"kind":"tok","re":"[^|{]+","opts":0,"tok":"Literal.String.Interpol","next":null}]},"shortnames":{"Text":"","Text.Whitespace":"w","Escape":"esc","Error":"err","Other":"x","Keyword":"k","Keyword.Constant":"kc","Keyword.Declaration":"kd","Keyword.Namespace":"kn","Keyword.Pseudo":"kp","Keyword.Reserved":"kr","Keyword.Type":"kt","Keyword.Variable":"kv","Name":"n","Name.Attribute":"na","Name.Builtin":"nb","Name.Builtin.Pseudo":"bp","Name.Class":"nc","Name.Constant":"no","Name.Decorator":"nd","Name.Entity":"ni","Name.Exception":"ne","Name.Function":"nf","Name.Function.Magic":"fm","Name.Property":"py","Name.Label":"nl","Name.Namespace":"nn","Name.Other":"nx","Name.Tag":"nt","Name.Variable":"nv","Name.Variable.Class":"vc","Name.Variable.Global":"vg","Name.Variable.Instance":"vi","Name.Variable.Magic":"vm","Literal":"l","Literal.Date":"ld","Literal.String":"s","Literal.String.Affix":"sa","Literal.String.Backtick":"sb","Literal.String.Char":"sc","Literal.String.Delimiter":"dl","Literal.String.Doc":"sd","Literal.String.Double":"s2","Literal.String.Escape":"se","Literal.String.Heredoc":"sh","Literal.String.Interpol":"si","Literal.String.Other":"sx","Literal.String.Regex":"sr","Literal.String.Single":"s1","Literal.String.Symbol":"ss","Literal.Number":"m","Literal.Number.Bin":"mb","Literal.Number.Float":"mf","Literal.Number.Hex":"mh","Literal.Number.Integer":"mi","Literal.Number.Integer.Long":"il","Literal.Number.Oct":"mo","Literal.Number.Other":"mx","Operator":"o","Operator.Word":"ow","Punctuation":"p","Punctuation.Indicator":"pi","Comment":"c","Comment.Hashbang":"ch","Comment.Doc":"cd","Comment.Multiline":"cm","Comment.Preproc":"cp","Comment.PreprocFile":"cpf","Comment.Single":"c1","Comment.Special":"cs","Generic":"g","Generic.Deleted":"gd","Generic.Emph":"ge","Generic.EmphStrong":"ges","Generic.Error":"gr","Generic.Heading":"gh","Generic.Inserted":"gi","Generic.Lineno":"gl","Generic.Output":"go","Generic.Prompt":"gp","Generic.Strong":"gs","Generic.Subheading":"gu","Generic.Traceback":"gt"}}
@@ -0,0 +1 @@
1
+ {"lexer":"Rouge::Lexers::Actionscript","start_push":[],"states":{"comments_and_whitespace":[{"kind":"tok","re":"\\s+","opts":0,"tok":"Text","next":null},{"kind":"tok","re":"//.*?$","opts":0,"tok":"Comment.Single","next":null},{"kind":"tok","re":"/\\*.*?\\*/","opts":4,"tok":"Comment.Multiline","next":null}],"expr_start":[{"kind":"mixin","state":"comments_and_whitespace"},{"kind":"actions","re":"/","opts":0,"actions":[["token","Literal.String.Regex"],["goto","regex"]]},{"kind":"tok","re":"[{]","opts":0,"tok":"Punctuation","next":"object"},{"kind":"tok","re":"","opts":0,"tok":"Text","next":"pop!"}],"regex":[{"kind":"actions","re":"/","opts":0,"actions":[["token","Literal.String.Regex"],["goto","regex_end"]]},{"kind":"tok","re":"[^/]\\n","opts":0,"tok":"Error","next":"pop!"},{"kind":"tok","re":"\\n","opts":0,"tok":"Error","next":"pop!"},{"kind":"tok","re":"\\[\\^","opts":0,"tok":"Literal.String.Escape","next":"regex_group"},{"kind":"tok","re":"\\[","opts":0,"tok":"Literal.String.Escape","next":"regex_group"},{"kind":"tok","re":"\\\\.","opts":0,"tok":"Literal.String.Escape","next":null},{"kind":"tok","re":"[(][?][:=<!]","opts":0,"tok":"Literal.String.Escape","next":null},{"kind":"tok","re":"[{][\\d,]+[}]","opts":0,"tok":"Literal.String.Escape","next":null},{"kind":"tok","re":"[()?]","opts":0,"tok":"Literal.String.Escape","next":null},{"kind":"tok","re":".","opts":0,"tok":"Literal.String.Regex","next":null}],"regex_end":[{"kind":"tok","re":"[gim]+","opts":0,"tok":"Literal.String.Regex","next":"pop!"},{"kind":"actions","re":"","opts":0,"actions":[["pop",1]]}],"regex_group":[{"kind":"tok","re":"/","opts":0,"tok":"Literal.String.Escape","next":null},{"kind":"actions","re":"[^/]\\n","opts":0,"actions":[["token","Error"],["pop",2]]},{"kind":"tok","re":"\\]","opts":0,"tok":"Literal.String.Escape","next":"pop!"},{"kind":"tok","re":"\\\\.","opts":0,"tok":"Literal.String.Escape","next":null},{"kind":"tok","re":".","opts":0,"tok":"Literal.String.Regex","next":null}],"bad_regex":[{"kind":"tok","re":"[^\\n]+","opts":0,"tok":"Error","next":"pop!"}],"root":[{"kind":"tok","re":"\\A\\s*#!.*?\\n","opts":4,"tok":"Comment.Preproc","next":"statement"},{"kind":"tok","re":"\\n","opts":0,"tok":"Text","next":"statement"},{"kind":"tok","re":"(?<=\\n)(?=\\s|/|<!--)","opts":0,"tok":"Text","next":"expr_start"},{"kind":"mixin","state":"comments_and_whitespace"},{"kind":"tok","re":"\\+\\+ | -- | ~ | && | \\|\\| | \\\\(?=\\n) | << | >>>? | ===\n | !== ","opts":2,"tok":"Operator","next":"expr_start"},{"kind":"tok","re":"[:-<>+*%&|\\^/!=]=?","opts":0,"tok":"Operator","next":"expr_start"},{"kind":"tok","re":"[(\\[,]","opts":0,"tok":"Punctuation","next":"expr_start"},{"kind":"tok","re":";","opts":0,"tok":"Punctuation","next":"statement"},{"kind":"tok","re":"[)\\].]","opts":0,"tok":"Punctuation","next":null},{"kind":"actions","re":"[?]","opts":0,"actions":[["token","Punctuation"],["push","ternary"],["push","expr_start"]]},{"kind":"tok","re":"[{}]","opts":0,"tok":"Punctuation","next":"statement"},{"kind":"ir","re":"[$a-zA-Z_][a-zA-Z0-9_]*","opts":0,"ops":[["if",["gin",0,["for","in","while","do","break","return","continue","switch","case","default","if","else","throw","try","catch","finally","new","delete","typeof","is","this","with"]],[["token","Keyword"],["push","expr_start"]],[["if",["gin",0,["var","with","function"]],[["token","Keyword.Declaration"],["push","expr_start"]],[["if",["gin",0,["dynamic","final","internal","native","public","protected","private","class","const","override","static","package","interface","extends","implements","namespace","set","get","import","include","super","flash_proxy","object_proxy","trace"]],[["token","Keyword.Reserved"]],[["if",["gin",0,["true","false","null","NaN","Infinity","undefined"]],[["token","Keyword.Constant"]],[["if",["gin",0,["void","Function","Math","Class","Object","RegExp","decodeURI","decodeURIComponent","encodeURI","encodeURIComponent","eval","isFinite","isNaN","parseFloat","parseInt","this"]],[["token","Name.Builtin"]],[["token","Name.Other"]]]]]]]]]]]]},{"kind":"tok","re":"\\-?[0-9][0-9]*\\.[0-9]+([eE][0-9]+)?[fd]?","opts":0,"tok":"Literal.Number.Float","next":null},{"kind":"tok","re":"0x[0-9a-fA-F]+","opts":0,"tok":"Literal.Number.Hex","next":null},{"kind":"tok","re":"\\-?[0-9]+","opts":0,"tok":"Literal.Number.Integer","next":null},{"kind":"tok","re":"\"(\\\\\\\\|\\\\\"|[^\"])*\"","opts":0,"tok":"Literal.String.Double","next":null},{"kind":"tok","re":"'(\\\\\\\\|\\\\'|[^'])*'","opts":0,"tok":"Literal.String.Single","next":null}],"statement":[{"kind":"actions","re":"((?-mix:[$a-zA-Z_][a-zA-Z0-9_]*))(\\s*)(:)","opts":0,"actions":[["groups",["Name.Label","Text","Punctuation"]]]},{"kind":"tok","re":"[{}]","opts":0,"tok":"Punctuation","next":null},{"kind":"mixin","state":"expr_start"}],"object":[{"kind":"mixin","state":"comments_and_whitespace"},{"kind":"actions","re":"[}]","opts":0,"actions":[["token","Punctuation"],["goto","statement"]]},{"kind":"actions","re":"((?-mix:[$a-zA-Z_][a-zA-Z0-9_]*))(\\s*)(:)","opts":0,"actions":[["groups",["Name.Attribute","Text","Punctuation"]],["push","expr_start"]]},{"kind":"tok","re":":","opts":0,"tok":"Punctuation","next":null},{"kind":"mixin","state":"root"}],"ternary":[{"kind":"actions","re":":","opts":0,"actions":[["token","Punctuation"],["goto","expr_start"]]},{"kind":"mixin","state":"root"}]},"shortnames":{"Text":"","Text.Whitespace":"w","Escape":"esc","Error":"err","Other":"x","Keyword":"k","Keyword.Constant":"kc","Keyword.Declaration":"kd","Keyword.Namespace":"kn","Keyword.Pseudo":"kp","Keyword.Reserved":"kr","Keyword.Type":"kt","Keyword.Variable":"kv","Name":"n","Name.Attribute":"na","Name.Builtin":"nb","Name.Builtin.Pseudo":"bp","Name.Class":"nc","Name.Constant":"no","Name.Decorator":"nd","Name.Entity":"ni","Name.Exception":"ne","Name.Function":"nf","Name.Function.Magic":"fm","Name.Property":"py","Name.Label":"nl","Name.Namespace":"nn","Name.Other":"nx","Name.Tag":"nt","Name.Variable":"nv","Name.Variable.Class":"vc","Name.Variable.Global":"vg","Name.Variable.Instance":"vi","Name.Variable.Magic":"vm","Literal":"l","Literal.Date":"ld","Literal.String":"s","Literal.String.Affix":"sa","Literal.String.Backtick":"sb","Literal.String.Char":"sc","Literal.String.Delimiter":"dl","Literal.String.Doc":"sd","Literal.String.Double":"s2","Literal.String.Escape":"se","Literal.String.Heredoc":"sh","Literal.String.Interpol":"si","Literal.String.Other":"sx","Literal.String.Regex":"sr","Literal.String.Single":"s1","Literal.String.Symbol":"ss","Literal.Number":"m","Literal.Number.Bin":"mb","Literal.Number.Float":"mf","Literal.Number.Hex":"mh","Literal.Number.Integer":"mi","Literal.Number.Integer.Long":"il","Literal.Number.Oct":"mo","Literal.Number.Other":"mx","Operator":"o","Operator.Word":"ow","Punctuation":"p","Punctuation.Indicator":"pi","Comment":"c","Comment.Hashbang":"ch","Comment.Doc":"cd","Comment.Multiline":"cm","Comment.Preproc":"cp","Comment.PreprocFile":"cpf","Comment.Single":"c1","Comment.Special":"cs","Generic":"g","Generic.Deleted":"gd","Generic.Emph":"ge","Generic.EmphStrong":"ges","Generic.Error":"gr","Generic.Heading":"gh","Generic.Inserted":"gi","Generic.Lineno":"gl","Generic.Output":"go","Generic.Prompt":"gp","Generic.Strong":"gs","Generic.Subheading":"gu","Generic.Traceback":"gt"}}
@@ -0,0 +1 @@
1
+ {"lexer":"Rouge::Lexers::Ada","start_push":[],"states":{"whitespace":[{"kind":"tok","re":"\\s+","opts":4,"tok":"Text","next":null},{"kind":"tok","re":"--.*$","opts":0,"tok":"Comment.Single","next":null}],"dquote_string":[{"kind":"tok","re":"[^\"\\n]+","opts":0,"tok":"Literal.String.Double","next":null},{"kind":"tok","re":"\"\"","opts":0,"tok":"Literal.String.Escape","next":null},{"kind":"tok","re":"\"","opts":0,"tok":"Literal.String.Double","next":"pop!"},{"kind":"tok","re":"\\n","opts":0,"tok":"Error","next":"pop!"}],"attr":[{"kind":"mixin","state":"whitespace"},{"kind":"tok","re":"[[:alpha:]](?:\\p{Pc}?[[:alnum:]])*\\b","opts":16,"tok":"Name.Attribute","next":"pop!"},{"kind":"tok","re":"","opts":0,"tok":"Text","next":"pop!"}],"decl_name":[{"kind":"mixin","state":"whitespace"},{"kind":"tok","re":"body\\b","opts":1,"tok":"Keyword.Declaration","next":null},{"kind":"actions","re":"((?-mix:[[:alpha:]](?:\\p{Pc}?[[:alnum:]])*\\b))(\\.)","opts":16,"actions":[["groups",["Name.Namespace","Punctuation"]]]},{"kind":"tok","re":"(?-mix:[[:alpha:]](?:\\p{Pc}?[[:alnum:]])*\\b)|\"(and|or|xor|/?=|<=?|>=?|\\+|–|&\\|/|mod|rem|\\*?\\*|abs|not)\"","opts":16,"tok":"Name.Function","next":"pop!"},{"kind":"tok","re":"","opts":0,"tok":"Text","next":"pop!"}],"libunit_name":[{"kind":"mixin","state":"whitespace"},{"kind":"callback","re":"[[:alpha:]](?:\\p{Pc}?[[:alnum:]])*\\b","opts":16},{"kind":"tok","re":"[.,]","opts":0,"tok":"Punctuation","next":null},{"kind":"tok","re":"","opts":0,"tok":"Text","next":"pop!"}],"root":[{"kind":"mixin","state":"whitespace"},{"kind":"tok","re":"'.'","opts":0,"tok":"Literal.String.Char","next":null},{"kind":"tok","re":"\"[^\"\\n]*","opts":0,"tok":"Literal.String.Double","next":"dquote_string"},{"kind":"tok","re":"(?-mix:\\d(_?\\d)*)\\.(?-mix:\\d(_?\\d)*)(?i-mx:(E[-+]?(?-mix:\\d(_?\\d)*))?)","opts":0,"tok":"Literal.Number.Float","next":null},{"kind":"tok","re":"(?-mix:\\d(_?\\d)*)#(?-mix:\\h(_?\\h)*)\\.(?-mix:\\h(_?\\h)*)#(?i-mx:(E[-+]?(?-mix:\\d(_?\\d)*))?)","opts":0,"tok":"Literal.Number.Float","next":null},{"kind":"tok","re":"2#[01](_?[01])*#(?i-mx:(E[-+]?(?-mix:\\d(_?\\d)*))?)","opts":0,"tok":"Literal.Number.Bin","next":null},{"kind":"tok","re":"8#[0-7](_?[0-7])*#(?i-mx:(E[-+]?(?-mix:\\d(_?\\d)*))?)","opts":0,"tok":"Literal.Number.Oct","next":null},{"kind":"tok","re":"16#(?-mix:\\h(_?\\h)*)*#(?i-mx:(E[-+]?(?-mix:\\d(_?\\d)*))?)","opts":0,"tok":"Literal.Number.Hex","next":null},{"kind":"tok","re":"(?-mix:\\d(_?\\d)*)#(?-mix:\\h(_?\\h)*)#(?i-mx:(E[-+]?(?-mix:\\d(_?\\d)*))?)","opts":0,"tok":"Literal.Number.Integer","next":null},{"kind":"tok","re":"(?-mix:\\d(_?\\d)*)#\\w+#","opts":0,"tok":"Error","next":null},{"kind":"tok","re":"(?-mix:\\d(_?\\d)*)(?i-mx:(E[-+]?(?-mix:\\d(_?\\d)*))?)","opts":0,"tok":"Literal.Number.Integer","next":null},{"kind":"tok","re":"'","opts":0,"tok":"Punctuation","next":"attr"},{"kind":"tok","re":"<<(?-mix:[[:alpha:]](?:\\p{Pc}?[[:alnum:]])*\\b)>>","opts":16,"tok":"Name.Label","next":null},{"kind":"actions","re":"^(?:(limited)(\\s+))?(?:(private)(\\s+))?(with)\\b","opts":1,"actions":[["groups",["Keyword.Namespace","Text","Keyword.Namespace","Text","Keyword.Namespace"]],["push","libunit_name"]]},{"kind":"tok","re":"[+*/&<=>|]|-|=>|\\.\\.|\\*\\*|[:></]=|<<|>>|<>|@","opts":0,"tok":"Operator","next":null},{"kind":"tok","re":"[.,:;()\\[\\]]","opts":0,"tok":"Punctuation","next":null},{"kind":"callback","re":"[[:alpha:]](?:\\p{Pc}?[[:alnum:]])*\\b","opts":16},{"kind":"tok","re":"\\b(\\p{Pc}|[[:alpha:]])\\p{Word}*","opts":16,"tok":"Error","next":null}]},"shortnames":{"Text":"","Text.Whitespace":"w","Escape":"esc","Error":"err","Other":"x","Keyword":"k","Keyword.Constant":"kc","Keyword.Declaration":"kd","Keyword.Namespace":"kn","Keyword.Pseudo":"kp","Keyword.Reserved":"kr","Keyword.Type":"kt","Keyword.Variable":"kv","Name":"n","Name.Attribute":"na","Name.Builtin":"nb","Name.Builtin.Pseudo":"bp","Name.Class":"nc","Name.Constant":"no","Name.Decorator":"nd","Name.Entity":"ni","Name.Exception":"ne","Name.Function":"nf","Name.Function.Magic":"fm","Name.Property":"py","Name.Label":"nl","Name.Namespace":"nn","Name.Other":"nx","Name.Tag":"nt","Name.Variable":"nv","Name.Variable.Class":"vc","Name.Variable.Global":"vg","Name.Variable.Instance":"vi","Name.Variable.Magic":"vm","Literal":"l","Literal.Date":"ld","Literal.String":"s","Literal.String.Affix":"sa","Literal.String.Backtick":"sb","Literal.String.Char":"sc","Literal.String.Delimiter":"dl","Literal.String.Doc":"sd","Literal.String.Double":"s2","Literal.String.Escape":"se","Literal.String.Heredoc":"sh","Literal.String.Interpol":"si","Literal.String.Other":"sx","Literal.String.Regex":"sr","Literal.String.Single":"s1","Literal.String.Symbol":"ss","Literal.Number":"m","Literal.Number.Bin":"mb","Literal.Number.Float":"mf","Literal.Number.Hex":"mh","Literal.Number.Integer":"mi","Literal.Number.Integer.Long":"il","Literal.Number.Oct":"mo","Literal.Number.Other":"mx","Operator":"o","Operator.Word":"ow","Punctuation":"p","Punctuation.Indicator":"pi","Comment":"c","Comment.Hashbang":"ch","Comment.Doc":"cd","Comment.Multiline":"cm","Comment.Preproc":"cp","Comment.PreprocFile":"cpf","Comment.Single":"c1","Comment.Special":"cs","Generic":"g","Generic.Deleted":"gd","Generic.Emph":"ge","Generic.EmphStrong":"ges","Generic.Error":"gr","Generic.Heading":"gh","Generic.Inserted":"gi","Generic.Lineno":"gl","Generic.Output":"go","Generic.Prompt":"gp","Generic.Strong":"gs","Generic.Subheading":"gu","Generic.Traceback":"gt"}}
@@ -0,0 +1 @@
1
+ {"lexer":"Rouge::Lexers::Apache","start_push":[],"states":{"whitespace":[{"kind":"tok","re":"\\#.*","opts":0,"tok":"Comment","next":null},{"kind":"tok","re":"\\s+","opts":4,"tok":"Text","next":null}],"root":[{"kind":"mixin","state":"whitespace"},{"kind":"callback","re":"(</?)(\\w+)","opts":0},{"kind":"callback","re":"\\w+","opts":0}],"section":[{"kind":"actions","re":"([^>]+)?(>(?:\\r\\n?|\\n)?)","opts":0,"actions":[["groups",["Literal.String.Regex","Punctuation"]],["pop",1]]},{"kind":"mixin","state":"whitespace"}],"directive":[{"kind":"tok","re":"\\r\\n?|\\n","opts":0,"tok":"Text","next":"pop!"},{"kind":"mixin","state":"whitespace"},{"kind":"callback","re":"\\S+","opts":0},{"kind":"actions","re":"(?=\\S)","opts":0,"actions":[["push","value"]]}],"value":[{"kind":"tok","re":"[ \\t]+","opts":0,"tok":"Text","next":"pop!"},{"kind":"tok","re":"[^\\s%]+","opts":0,"tok":"Text","next":null},{"kind":"tok","re":"%{.*?}","opts":0,"tok":"Name.Variable","next":null},{"kind":"tok","re":"[%]","opts":0,"tok":"Text","next":null},{"kind":"actions","re":"(?=\\n)","opts":0,"actions":[["pop",1]]}]},"shortnames":{"Text":"","Text.Whitespace":"w","Escape":"esc","Error":"err","Other":"x","Keyword":"k","Keyword.Constant":"kc","Keyword.Declaration":"kd","Keyword.Namespace":"kn","Keyword.Pseudo":"kp","Keyword.Reserved":"kr","Keyword.Type":"kt","Keyword.Variable":"kv","Name":"n","Name.Attribute":"na","Name.Builtin":"nb","Name.Builtin.Pseudo":"bp","Name.Class":"nc","Name.Constant":"no","Name.Decorator":"nd","Name.Entity":"ni","Name.Exception":"ne","Name.Function":"nf","Name.Function.Magic":"fm","Name.Property":"py","Name.Label":"nl","Name.Namespace":"nn","Name.Other":"nx","Name.Tag":"nt","Name.Variable":"nv","Name.Variable.Class":"vc","Name.Variable.Global":"vg","Name.Variable.Instance":"vi","Name.Variable.Magic":"vm","Literal":"l","Literal.Date":"ld","Literal.String":"s","Literal.String.Affix":"sa","Literal.String.Backtick":"sb","Literal.String.Char":"sc","Literal.String.Delimiter":"dl","Literal.String.Doc":"sd","Literal.String.Double":"s2","Literal.String.Escape":"se","Literal.String.Heredoc":"sh","Literal.String.Interpol":"si","Literal.String.Other":"sx","Literal.String.Regex":"sr","Literal.String.Single":"s1","Literal.String.Symbol":"ss","Literal.Number":"m","Literal.Number.Bin":"mb","Literal.Number.Float":"mf","Literal.Number.Hex":"mh","Literal.Number.Integer":"mi","Literal.Number.Integer.Long":"il","Literal.Number.Oct":"mo","Literal.Number.Other":"mx","Operator":"o","Operator.Word":"ow","Punctuation":"p","Punctuation.Indicator":"pi","Comment":"c","Comment.Hashbang":"ch","Comment.Doc":"cd","Comment.Multiline":"cm","Comment.Preproc":"cp","Comment.PreprocFile":"cpf","Comment.Single":"c1","Comment.Special":"cs","Generic":"g","Generic.Deleted":"gd","Generic.Emph":"ge","Generic.EmphStrong":"ges","Generic.Error":"gr","Generic.Heading":"gh","Generic.Inserted":"gi","Generic.Lineno":"gl","Generic.Output":"go","Generic.Prompt":"gp","Generic.Strong":"gs","Generic.Subheading":"gu","Generic.Traceback":"gt"}}
@@ -0,0 +1 @@
1
+ {"lexer":"Rouge::Lexers::Apex","start_push":[],"states":{"root":[{"kind":"tok","re":"\\s+","opts":4,"tok":"Text","next":null},{"kind":"tok","re":"//.*?$","opts":0,"tok":"Comment.Single","next":null},{"kind":"tok","re":"/\\*.*?\\*/","opts":4,"tok":"Comment.Multiline","next":null},{"kind":"tok","re":"(?:class|interface)\\b","opts":0,"tok":"Keyword.Declaration","next":"class"},{"kind":"tok","re":"import\\b","opts":0,"tok":"Keyword.Namespace","next":"import"},{"kind":"ir","re":"([@$.]?)((?i-mx:[a-z_][a-z0-9_]*))([:(]?)","opts":1,"ops":[["if",["ginf",0,"down",["assert","break","case","catch","continue","default","do","else","finally","for","if","goto","instanceof","new","return","switch","this","throw","try","while","insert","update","delete"]],[["token","Keyword"]],[["if",["ginf",0,"up",["SELECT","FROM","WHERE","UPDATE","LIKE","TYPEOF","END","USING","SCOPE","WITH","DATA","CATEGORY","GROUP","BY","ROLLUP","CUBE","HAVING","ORDER","ASC","DESC","NULLS","FIRST","LAST","LIMIT","OFFSET","FOR","VIEW","REFERENCE","TRACKING","VIEWSTAT","OR","AND"]],[["token","Keyword"]],[["if",["ginf",0,"down",["abstract","const","enum","extends","final","implements","native","private","protected","public","static","super","synchronized","throws","transient","volatile","with","sharing","without","inherited","virtual","global","testmethod"]],[["token","Keyword.Declaration"]],[["if",["ginf",0,"down",["String","boolean","byte","char","double","float","int","long","short","var","void"]],[["token","Keyword.Type"]],[["if",["ginf",0,"down",["true","false","null"]],[["token","Keyword.Constant"]],[["if",["geqf",0,"down","package"],[["token","Keyword.Namespace"]],[["if",["geq",1,"@"],[["token","Name.Decorator"]],[["if",["geq",3,":"],[["groups",["Operator","Name.Label","Punctuation"]]],[["if",["geq",3,"("],[["groups",["Operator","Name.Function","Punctuation"]]],[["if",["geq",1,"."],[["groups",["Operator","Name.Property","Punctuation"]]],[["token","Name"]]]]]]]]]]]]]]]]]]]]]]},{"kind":"tok","re":"\"","opts":0,"tok":"Literal.String.Double","next":"dq"},{"kind":"tok","re":"'","opts":0,"tok":"Literal.String.Single","next":"sq"},{"kind":"tok","re":"(?-mix:[0-9]_+[0-9]|[0-9])+\\.(?-mix:[0-9]_+[0-9]|[0-9])+([eE](?-mix:[0-9]_+[0-9]|[0-9])+)?[fd]?","opts":0,"tok":"Literal.Number.Float","next":null},{"kind":"tok","re":"0b(?:[01]_+[01]|[01])+","opts":1,"tok":"Literal.Number.Bin","next":null},{"kind":"tok","re":"0x(?:\\h_+\\h|\\h)+","opts":1,"tok":"Literal.Number.Hex","next":null},{"kind":"tok","re":"0(?:[0-7]_+[0-7]|[0-7])+","opts":0,"tok":"Literal.Number.Oct","next":null},{"kind":"tok","re":"(?-mix:[0-9]_+[0-9]|[0-9])+L?","opts":0,"tok":"Literal.Number.Integer","next":null},{"kind":"tok","re":"[-+/*~^!%&<>|=.?]","opts":0,"tok":"Operator","next":null},{"kind":"tok","re":"[\\[\\](){},:;]","opts":0,"tok":"Punctuation","next":null}],"class":[{"kind":"tok","re":"\\s+","opts":4,"tok":"Text","next":null},{"kind":"tok","re":"[a-z_][a-z0-9_]*","opts":1,"tok":"Name.Class","next":"pop!"}],"import":[{"kind":"tok","re":"\\s+","opts":4,"tok":"Text","next":null},{"kind":"tok","re":"[a-z0-9_.]+\\*?","opts":1,"tok":"Name.Namespace","next":"pop!"}],"escape":[{"kind":"tok","re":"\\\\[btnfr\\\\\"']","opts":0,"tok":"Literal.String.Escape","next":null}],"dq":[{"kind":"mixin","state":"escape"},{"kind":"tok","re":"[^\\\\\"]+","opts":0,"tok":"Literal.String.Double","next":null},{"kind":"tok","re":"\"","opts":0,"tok":"Literal.String.Double","next":"pop!"}],"sq":[{"kind":"mixin","state":"escape"},{"kind":"tok","re":"[^\\\\']+","opts":0,"tok":"Literal.String.Double","next":null},{"kind":"tok","re":"'","opts":0,"tok":"Literal.String.Double","next":"pop!"}]},"shortnames":{"Text":"","Text.Whitespace":"w","Escape":"esc","Error":"err","Other":"x","Keyword":"k","Keyword.Constant":"kc","Keyword.Declaration":"kd","Keyword.Namespace":"kn","Keyword.Pseudo":"kp","Keyword.Reserved":"kr","Keyword.Type":"kt","Keyword.Variable":"kv","Name":"n","Name.Attribute":"na","Name.Builtin":"nb","Name.Builtin.Pseudo":"bp","Name.Class":"nc","Name.Constant":"no","Name.Decorator":"nd","Name.Entity":"ni","Name.Exception":"ne","Name.Function":"nf","Name.Function.Magic":"fm","Name.Property":"py","Name.Label":"nl","Name.Namespace":"nn","Name.Other":"nx","Name.Tag":"nt","Name.Variable":"nv","Name.Variable.Class":"vc","Name.Variable.Global":"vg","Name.Variable.Instance":"vi","Name.Variable.Magic":"vm","Literal":"l","Literal.Date":"ld","Literal.String":"s","Literal.String.Affix":"sa","Literal.String.Backtick":"sb","Literal.String.Char":"sc","Literal.String.Delimiter":"dl","Literal.String.Doc":"sd","Literal.String.Double":"s2","Literal.String.Escape":"se","Literal.String.Heredoc":"sh","Literal.String.Interpol":"si","Literal.String.Other":"sx","Literal.String.Regex":"sr","Literal.String.Single":"s1","Literal.String.Symbol":"ss","Literal.Number":"m","Literal.Number.Bin":"mb","Literal.Number.Float":"mf","Literal.Number.Hex":"mh","Literal.Number.Integer":"mi","Literal.Number.Integer.Long":"il","Literal.Number.Oct":"mo","Literal.Number.Other":"mx","Operator":"o","Operator.Word":"ow","Punctuation":"p","Punctuation.Indicator":"pi","Comment":"c","Comment.Hashbang":"ch","Comment.Doc":"cd","Comment.Multiline":"cm","Comment.Preproc":"cp","Comment.PreprocFile":"cpf","Comment.Single":"c1","Comment.Special":"cs","Generic":"g","Generic.Deleted":"gd","Generic.Emph":"ge","Generic.EmphStrong":"ges","Generic.Error":"gr","Generic.Heading":"gh","Generic.Inserted":"gi","Generic.Lineno":"gl","Generic.Output":"go","Generic.Prompt":"gp","Generic.Strong":"gs","Generic.Subheading":"gu","Generic.Traceback":"gt"}}
@@ -0,0 +1 @@
1
+ {"lexer":"Rouge::Lexers::APIBlueprint","start_push":[],"states":{"root":[{"kind":"actions","re":"(\\S+)(:\\s*)(.*)$","opts":0,"actions":[["groups",["Name.Variable","Punctuation","Literal.String"]]]},{"kind":"actions","re":"^(#+)(\\s*Group\\s+)(.*)$","opts":0,"actions":[["groups",["Punctuation","Keyword","Generic.Heading"]]]},{"kind":"actions","re":"^(#+)(.*)(\\[.*\\])$","opts":0,"actions":[["groups",["Punctuation","Generic.Heading","Literal.String"]]]},{"kind":"actions","re":"^([\\+\\-\\*])(\\s*Relation:)(\\s*.*)$","opts":0,"actions":[["groups",["Punctuation","Keyword","Literal.String"]]]},{"kind":"actions","re":"^(\\s+[\\+\\-\\*]\\s*)(Attributes|Parameters)(.*)$","opts":0,"actions":[["groups",["Punctuation","Keyword","Literal.String"]]]},{"kind":"actions","re":"^([\\+\\-\\*]\\s*)(Request|Response)(\\s+\\d\\d\\d)?(.*)$","opts":0,"actions":[["groups",["Punctuation","Keyword","Literal.Number","Literal.String"]]]},{"kind":"callback","re":"\\A(---\\s*\\n.*?\\n?)^(---\\s*$\\n?)","opts":4},{"kind":"tok","re":"\\\\.","opts":0,"tok":"Literal.String.Escape","next":null},{"kind":"tok","re":"^[\\S ]+\\n(?:---*)\\n","opts":0,"tok":"Generic.Heading","next":null},{"kind":"tok","re":"^[\\S ]+\\n(?:===*)\\n","opts":0,"tok":"Generic.Subheading","next":null},{"kind":"tok","re":"^#(?=[^#]).*?$","opts":0,"tok":"Generic.Heading","next":null},{"kind":"tok","re":"^##*.*?$","opts":0,"tok":"Generic.Subheading","next":null},{"kind":"callback","re":"^([ \\t]*)(`{3,}|~{3,})([^\\n]*\\n)((.*?)(\\n\\1)(\\2))?","opts":4},{"kind":"tok","re":"\\n\\n(( |\\t).*?\\n|\\n)+","opts":0,"tok":"Literal.String.Backtick","next":null},{"kind":"tok","re":"(`+)(?:(?-mix:\\\\.|[^\\\\\\n])|\\n)+?\\1","opts":0,"tok":"Literal.String.Backtick","next":null},{"kind":"tok","re":"^(\\s*[*]){3,}\\s*$","opts":0,"tok":"Punctuation","next":null},{"kind":"tok","re":"^(\\s*[-]){3,}\\s*$","opts":0,"tok":"Punctuation","next":null},{"kind":"tok","re":"^\\s*[*+-](?=\\s)","opts":0,"tok":"Punctuation","next":null},{"kind":"tok","re":"^\\s*\\d+\\.","opts":0,"tok":"Punctuation","next":null},{"kind":"tok","re":"^\\s*>.*?$","opts":0,"tok":"Generic.Traceback","next":null},{"kind":"actions","re":"^\n (\\s*) # leading whitespace\n (\\[) ((?-mix:\\\\.|[^\\\\\\n])+?) (\\]) # the reference\n (\\s*) (:) # colon\n ","opts":2,"actions":[["groups",["Text","Punctuation","Literal.String.Symbol","Punctuation","Text","Punctuation"]],["push","title"],["push","url"]]},{"kind":"actions","re":"(!?\\[)((?-mix:\\\\.|[^\\\\\\n])*?|[^\\]]*?)(\\])(?=[\\[(])","opts":0,"actions":[["groups",["Punctuation","Name.Variable","Punctuation"]],["push","link"]]},{"kind":"tok","re":"[*]{2}[^* \\n][^*\\n]*[*]{2}","opts":0,"tok":"Generic.Strong","next":null},{"kind":"tok","re":"[*]{3}[^* \\n][^*\\n]*[*]{3}","opts":0,"tok":"Generic.EmphStrong","next":null},{"kind":"tok","re":"__(?-mix:\\\\.|[^\\\\\\n])*?__","opts":0,"tok":"Generic.Strong","next":null},{"kind":"tok","re":"[*](?-mix:\\\\.|[^\\\\\\n])*?[*]","opts":0,"tok":"Generic.Emph","next":null},{"kind":"tok","re":"_(?-mix:\\\\.|[^\\\\\\n])*?_","opts":0,"tok":"Generic.Emph","next":null},{"kind":"tok","re":"<.*?@.+[.].+>","opts":0,"tok":"Name.Variable","next":null},{"kind":"tok","re":"<(https?|mailto|ftp)://(?-mix:\\\\.|[^\\\\\\n])*?>","opts":0,"tok":"Name.Variable","next":null},{"kind":"tok","re":"[^\\\\`\\[*\\n&<]+","opts":0,"tok":"Text","next":null},{"kind":"callback","re":"&\\S*;","opts":0},{"kind":"callback","re":"<(?-mix:\\\\.|[^\\\\\\n])*?>","opts":0},{"kind":"tok","re":"[&<]","opts":0,"tok":"Text","next":null},{"kind":"tok","re":"\\[","opts":0,"tok":"Text","next":null},{"kind":"tok","re":"\\n","opts":0,"tok":"Text","next":null}],"link":[{"kind":"actions","re":"(\\[)((?-mix:\\\\.|[^\\\\\\n])*?)(\\])","opts":0,"actions":[["groups",["Punctuation","Literal.String.Symbol","Punctuation"]],["pop",1]]},{"kind":"actions","re":"[(]","opts":0,"actions":[["token","Punctuation"],["push","inline_title"],["push","inline_url"]]},{"kind":"tok","re":"[ \\t]+","opts":0,"tok":"Text","next":null},{"kind":"actions","re":"","opts":0,"actions":[["pop",1]]}],"url":[{"kind":"tok","re":"[ \\t]+","opts":0,"tok":"Text","next":null},{"kind":"actions","re":"(<)((?-mix:\\\\.|[^\\\\\\n])*?)(>)","opts":0,"actions":[["groups",["Name.Tag","Literal.String.Other","Name.Tag"]],["pop",1]]},{"kind":"tok","re":"\\S+","opts":0,"tok":"Literal.String.Other","next":"pop!"}],"title":[{"kind":"tok","re":"\"(?-mix:\\\\.|[^\\\\\\n])*?\"","opts":0,"tok":"Name.Namespace","next":null},{"kind":"tok","re":"'(?-mix:\\\\.|[^\\\\\\n])*?'","opts":0,"tok":"Name.Namespace","next":null},{"kind":"tok","re":"[(](?-mix:\\\\.|[^\\\\\\n])*?[)]","opts":0,"tok":"Name.Namespace","next":null},{"kind":"tok","re":"\\s*(?=[\"'()])","opts":0,"tok":"Text","next":null},{"kind":"actions","re":"","opts":0,"actions":[["pop",1]]}],"inline_title":[{"kind":"tok","re":"[)]","opts":0,"tok":"Punctuation","next":"pop!"},{"kind":"mixin","state":"title"}],"inline_url":[{"kind":"tok","re":"[^<\\s)]+","opts":0,"tok":"Literal.String.Other","next":"pop!"},{"kind":"tok","re":"\\s+","opts":4,"tok":"Text","next":null},{"kind":"mixin","state":"url"}]},"shortnames":{"Text":"","Text.Whitespace":"w","Escape":"esc","Error":"err","Other":"x","Keyword":"k","Keyword.Constant":"kc","Keyword.Declaration":"kd","Keyword.Namespace":"kn","Keyword.Pseudo":"kp","Keyword.Reserved":"kr","Keyword.Type":"kt","Keyword.Variable":"kv","Name":"n","Name.Attribute":"na","Name.Builtin":"nb","Name.Builtin.Pseudo":"bp","Name.Class":"nc","Name.Constant":"no","Name.Decorator":"nd","Name.Entity":"ni","Name.Exception":"ne","Name.Function":"nf","Name.Function.Magic":"fm","Name.Property":"py","Name.Label":"nl","Name.Namespace":"nn","Name.Other":"nx","Name.Tag":"nt","Name.Variable":"nv","Name.Variable.Class":"vc","Name.Variable.Global":"vg","Name.Variable.Instance":"vi","Name.Variable.Magic":"vm","Literal":"l","Literal.Date":"ld","Literal.String":"s","Literal.String.Affix":"sa","Literal.String.Backtick":"sb","Literal.String.Char":"sc","Literal.String.Delimiter":"dl","Literal.String.Doc":"sd","Literal.String.Double":"s2","Literal.String.Escape":"se","Literal.String.Heredoc":"sh","Literal.String.Interpol":"si","Literal.String.Other":"sx","Literal.String.Regex":"sr","Literal.String.Single":"s1","Literal.String.Symbol":"ss","Literal.Number":"m","Literal.Number.Bin":"mb","Literal.Number.Float":"mf","Literal.Number.Hex":"mh","Literal.Number.Integer":"mi","Literal.Number.Integer.Long":"il","Literal.Number.Oct":"mo","Literal.Number.Other":"mx","Operator":"o","Operator.Word":"ow","Punctuation":"p","Punctuation.Indicator":"pi","Comment":"c","Comment.Hashbang":"ch","Comment.Doc":"cd","Comment.Multiline":"cm","Comment.Preproc":"cp","Comment.PreprocFile":"cpf","Comment.Single":"c1","Comment.Special":"cs","Generic":"g","Generic.Deleted":"gd","Generic.Emph":"ge","Generic.EmphStrong":"ges","Generic.Error":"gr","Generic.Heading":"gh","Generic.Inserted":"gi","Generic.Lineno":"gl","Generic.Output":"go","Generic.Prompt":"gp","Generic.Strong":"gs","Generic.Subheading":"gu","Generic.Traceback":"gt"}}
@@ -0,0 +1 @@
1
+ {"lexer":"Rouge::Lexers::AppleScript","start_push":[],"states":{"root":[{"kind":"tok","re":"\\s+","opts":0,"tok":"Text.Whitespace","next":null},{"kind":"tok","re":"¬\\n","opts":16,"tok":"Literal.String.Escape","next":null},{"kind":"tok","re":"'s\\s+","opts":0,"tok":"Text","next":null},{"kind":"tok","re":"(--|#).*?$","opts":0,"tok":"Comment.Single","next":null},{"kind":"tok","re":"\\(\\*","opts":0,"tok":"Comment.Multiline","next":null},{"kind":"tok","re":"[\\(\\){}!,.:]","opts":0,"tok":"Punctuation","next":null},{"kind":"ir","re":"(«)([^»]+)(»)","opts":16,"ops":[["token","Text",["g",1]],["token","Name.Builtin",["g",2]],["token","Text",["g",3]]]},{"kind":"ir","re":"\\b((?:considering|ignoring)\\s*)(application responses|case|diacriticals|hyphens|numeric strings|punctuation|white space)","opts":0,"ops":[["token","Keyword",["g",1]],["token","Name.Builtin",["g",2]]]},{"kind":"tok","re":"(-|\\*|\\+|&|≠|>=?|<=?|=|≥|≤|/|÷|\\^)","opts":16,"tok":"Operator","next":null},{"kind":"tok","re":"\\b(and|or|is equal|equals|(is )?equal to|is not|isn't|isn't equal( to)?|is not equal( to)?|doesn't equal|does not equal|(is )?greater than|comes after|is not less than or equal( to)?|isn't less than or equal( to)?|(is )?less than|comes before|is not greater than or equal( to)?|isn't greater than or equal( to)?|(is )?greater than or equal( to)?|is not less than|isn't less than|does not come before|doesn't come before|(is )?less than or equal( to)?|is not greater than|isn't greater than|does not come after|doesn't come after|starts? with|begins? with|ends? with|contains?|does not contain|doesn't contain|is in|is contained by|is not in|is not contained by|isn't contained by|div|mod|not|(a )?(ref( to)?|reference to)|is|does)\\b","opts":0,"tok":"Operator.Word","next":null},{"kind":"ir","re":"^(\\s*(?:on|end)\\s+)'r'(%s)","opts":0,"ops":[["token","Keyword",["g",1]],["token","Name.Function",["g",2]]]},{"kind":"ir","re":"^(\\s*)(in|on|script|to)(\\s+)","opts":0,"ops":[["token","Text",["g",1]],["token","Keyword",["g",2]],["token","Text",["g",3]]]},{"kind":"ir","re":"\\b(as )(alias |application |boolean |class |constant |date |file |integer |list |number |POSIX file |real |record |reference |RGB color |script |text |unit types|(?:Unicode )?text|string)\\b","opts":0,"ops":[["token","Keyword",["g",1]],["token","Name.Class",["g",2]]]},{"kind":"tok","re":"\\b(AppleScript|current application|false|linefeed|missing value|pi|quote|result|return|space|tab|text item delimiters|true|version)\\b","opts":0,"tok":"Name.Builtin","next":null},{"kind":"tok","re":"\\b(ASCII (character|number)|activate|beep|choose URL|choose application|choose color|choose file( name)?|choose folder|choose from list|choose remote application|clipboard info|close( access)?|copy|count|current date|delay|delete|display (alert|dialog)|do shell script|duplicate|exists|get eof|get volume settings|info for|launch|list (disks|folder)|load script|log|make|mount volume|new|offset|open( (for access|location))?|path to|print|quit|random number|read|round|run( script)?|say|scripting components|set (eof|the clipboard to|volume)|store script|summarize|system attribute|system info|the clipboard|time to GMT|write|quoted form)\\b","opts":0,"tok":"Name.Builtin","next":null},{"kind":"tok","re":"\\b(considering|else|error|exit|from|if|ignoring|in|repeat|tell|then|times|to|try|until|using terms from|while|whith|with timeout( of)?|with transaction|by|continue|end|its?|me|my|return|of|as)\\b","opts":0,"tok":"Keyword","next":null},{"kind":"tok","re":"\\b(global|local|prop(erty)?|set|get)\\b","opts":0,"tok":"Keyword","next":null},{"kind":"tok","re":"\\b(but|put|returning|the)\\b","opts":0,"tok":"Name.Builtin","next":null},{"kind":"tok","re":"\\b(attachment|attribute run|character|day|month|paragraph|word|year)s?\\b","opts":0,"tok":"Name.Builtin","next":null},{"kind":"tok","re":"\\b(about|above|against|apart from|around|aside from|at|below|beneath|beside|between|for|given|instead of|on|onto|out of|over|since)\\b","opts":0,"tok":"Name.Builtin","next":null},{"kind":"tok","re":"\\b(accepts arrow key|action method|active|alignment|allowed identifiers|allows branch selection|allows column reordering|allows column resizing|allows column selection|allows customization|allows editing text attributes|allows empty selection|allows mixed state|allows multiple selection|allows reordering|allows undo|alpha( value)?|alternate image|alternate increment value|alternate title|animation delay|associated file name|associated object|auto completes|auto display|auto enables items|auto repeat|auto resizes( outline column)?|auto save expanded items|auto save name|auto save table columns|auto saves configuration|auto scroll|auto sizes all columns to fit|auto sizes cells|background color|bezel state|bezel style|bezeled|border rect|border type|bordered|bounds( rotation)?|box type|button returned|button type|can choose directories|can choose files|can draw|can hide|cell( (background color|size|type))?|characters|class|click count|clicked( data)? column|clicked data item|clicked( data)? row|closeable|collating|color( (mode|panel))|command key down|configuration|content(s| (size|view( margins)?))?|context|continuous|control key down|control size|control tint|control view|controller visible|coordinate system|copies( on scroll)?|corner view|current cell|current column|current( field)? editor|current( menu)? item|current row|current tab view item|data source|default identifiers|delta (x|y|z)|destination window|directory|display mode|displayed cell|document( (edited|rect|view))?|double value|dragged column|dragged distance|dragged items|draws( cell)? background|draws grid|dynamically scrolls|echos bullets|edge|editable|edited( data)? column|edited data item|edited( data)? row|enabled|enclosing scroll view|ending page|error handling|event number|event type|excluded from windows menu|executable path|expanded|fax number|field editor|file kind|file name|file type|first responder|first visible column|flipped|floating|font( panel)?|formatter|frameworks path|frontmost|gave up|grid color|has data items|has horizontal ruler|has horizontal scroller|has parent data item|has resize indicator|has shadow|has sub menu|has vertical ruler|has vertical scroller|header cell|header view|hidden|hides when deactivated|highlights by|horizontal line scroll|horizontal page scroll|horizontal ruler view|horizontally resizable|icon image|id|identifier|ignores multiple clicks|image( (alignment|dims when disabled|frame style|scaling))?|imports graphics|increment value|indentation per level|indeterminate|index|integer value|intercell spacing|item height|key( (code|equivalent( modifier)?|window))?|knob thickness|label|last( visible)? column|leading offset|leaf|level|line scroll|loaded|localized sort|location|loop mode|main( (bunde|menu|window))?|marker follows cell|matrix mode|maximum( content)? size|maximum visible columns|menu( form representation)?|miniaturizable|miniaturized|minimized image|minimized title|minimum column width|minimum( content)? size|modal|modified|mouse down state|movie( (controller|file|rect))?|muted|name|needs display|next state|next text|number of tick marks|only tick mark values|opaque|open panel|option key down|outline table column|page scroll|pages across|pages down|palette label|pane splitter|parent data item|parent window|pasteboard|path( (names|separator))?|playing|plays every frame|plays selection only|position|preferred edge|preferred type|pressure|previous text|prompt|properties|prototype cell|pulls down|rate|released when closed|repeated|requested print time|required file type|resizable|resized column|resource path|returns records|reuses columns|rich text|roll over|row height|rulers visible|save panel|scripts path|scrollable|selectable( identifiers)?|selected cell|selected( data)? columns?|selected data items?|selected( data)? rows?|selected item identifier|selection by rect|send action on arrow key|sends action when done editing|separates columns|separator item|sequence number|services menu|shared frameworks path|shared support path|sheet|shift key down|shows alpha|shows state by|size( mode)?|smart insert delete enabled|sort case sensitivity|sort column|sort order|sort type|sorted( data rows)?|sound|source( mask)?|spell checking enabled|starting page|state|string value|sub menu|super menu|super view|tab key traverses cells|tab state|tab type|tab view|table view|tag|target( printer)?|text color|text container insert|text container origin|text returned|tick mark position|time stamp|title(d| (cell|font|height|position|rect))?|tool tip|toolbar|trailing offset|transparent|treat packages as directories|truncated labels|types|unmodified characters|update views|use sort indicator|user defaults|uses data source|uses ruler|uses threaded animation|uses title from previous column|value wraps|version|vertical( (line scroll|page scroll|ruler view))?|vertically resizable|view|visible( document rect)?|volume|width|window|windows menu|wraps|zoomable|zoomed)\\b","opts":0,"tok":"Name.Attribute","next":null},{"kind":"tok","re":"\\b(action cell|alert reply|application|box|browser( cell)?|bundle|button( cell)?|cell|clip view|color well|color-panel|combo box( item)?|control|data( (cell|column|item|row|source))?|default entry|dialog reply|document|drag info|drawer|event|font(-panel)?|formatter|image( (cell|view))?|matrix|menu( item)?|item|movie( view)?|open-panel|outline view|panel|pasteboard|plugin|popup button|progress indicator|responder|save-panel|scroll view|secure text field( cell)?|slider|sound|split view|stepper|tab view( item)?|table( (column|header cell|header view|view))|text( (field( cell)?|view))?|toolbar( item)?|user-defaults|view|window)s?\\b","opts":0,"tok":"Name.Builtin","next":null},{"kind":"tok","re":"\\b(animate|append|call method|center|close drawer|close panel|display|display alert|display dialog|display panel|go|hide|highlight|increment|item for|load image|load movie|load nib|load panel|load sound|localized string|lock focus|log|open drawer|path for|pause|perform action|play|register|resume|scroll|select( all)?|show|size to fit|start|step back|step forward|stop|synchronize|unlock focus|update)\\b","opts":0,"tok":"Name.Builtin","next":null},{"kind":"tok","re":"\\b((in )?back of|(in )?front of|[0-9]+(st|nd|rd|th)|first|second|third|fourth|fifth|sixth|seventh|eighth|ninth|tenth|after|back|before|behind|every|front|index|last|middle|some|that|through|thru|where|whose)\\b","opts":0,"tok":"Name.Builtin","next":null},{"kind":"tok","re":"\"(\\\\\\\\|\\\\\"|[^\"])*\"","opts":0,"tok":"Literal.String.Double","next":null},{"kind":"tok","re":"\\b([a-zA-Z]\\w*)\\b","opts":0,"tok":"Name.Variable","next":null},{"kind":"tok","re":"[-+]?(\\d+\\.\\d*|\\d*\\.\\d+)(E[-+][0-9]+)?","opts":0,"tok":"Literal.Number.Float","next":null},{"kind":"tok","re":"[-+]?\\d+","opts":0,"tok":"Literal.Number.Integer","next":null}]},"shortnames":{"Text":"","Text.Whitespace":"w","Escape":"esc","Error":"err","Other":"x","Keyword":"k","Keyword.Constant":"kc","Keyword.Declaration":"kd","Keyword.Namespace":"kn","Keyword.Pseudo":"kp","Keyword.Reserved":"kr","Keyword.Type":"kt","Keyword.Variable":"kv","Name":"n","Name.Attribute":"na","Name.Builtin":"nb","Name.Builtin.Pseudo":"bp","Name.Class":"nc","Name.Constant":"no","Name.Decorator":"nd","Name.Entity":"ni","Name.Exception":"ne","Name.Function":"nf","Name.Function.Magic":"fm","Name.Property":"py","Name.Label":"nl","Name.Namespace":"nn","Name.Other":"nx","Name.Tag":"nt","Name.Variable":"nv","Name.Variable.Class":"vc","Name.Variable.Global":"vg","Name.Variable.Instance":"vi","Name.Variable.Magic":"vm","Literal":"l","Literal.Date":"ld","Literal.String":"s","Literal.String.Affix":"sa","Literal.String.Backtick":"sb","Literal.String.Char":"sc","Literal.String.Delimiter":"dl","Literal.String.Doc":"sd","Literal.String.Double":"s2","Literal.String.Escape":"se","Literal.String.Heredoc":"sh","Literal.String.Interpol":"si","Literal.String.Other":"sx","Literal.String.Regex":"sr","Literal.String.Single":"s1","Literal.String.Symbol":"ss","Literal.Number":"m","Literal.Number.Bin":"mb","Literal.Number.Float":"mf","Literal.Number.Hex":"mh","Literal.Number.Integer":"mi","Literal.Number.Integer.Long":"il","Literal.Number.Oct":"mo","Literal.Number.Other":"mx","Operator":"o","Operator.Word":"ow","Punctuation":"p","Punctuation.Indicator":"pi","Comment":"c","Comment.Hashbang":"ch","Comment.Doc":"cd","Comment.Multiline":"cm","Comment.Preproc":"cp","Comment.PreprocFile":"cpf","Comment.Single":"c1","Comment.Special":"cs","Generic":"g","Generic.Deleted":"gd","Generic.Emph":"ge","Generic.EmphStrong":"ges","Generic.Error":"gr","Generic.Heading":"gh","Generic.Inserted":"gi","Generic.Lineno":"gl","Generic.Output":"go","Generic.Prompt":"gp","Generic.Strong":"gs","Generic.Subheading":"gu","Generic.Traceback":"gt"}}