rouge 3.13.0 → 3.18.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. checksums.yaml +4 -4
  2. data/lib/rouge.rb +65 -50
  3. data/lib/rouge/cli.rb +18 -1
  4. data/lib/rouge/demos/cypher +5 -0
  5. data/lib/rouge/demos/datastudio +21 -0
  6. data/lib/rouge/demos/ecl +18 -0
  7. data/lib/rouge/demos/freefem +16 -0
  8. data/lib/rouge/demos/ghc-cmm +23 -0
  9. data/lib/rouge/demos/ghc-core +26 -0
  10. data/lib/rouge/demos/isbl +4 -0
  11. data/lib/rouge/demos/nasm +6 -6
  12. data/lib/rouge/demos/nesasm +11 -0
  13. data/lib/rouge/demos/objective_cpp +17 -0
  14. data/lib/rouge/demos/rego +8 -0
  15. data/lib/rouge/demos/slice +10 -0
  16. data/lib/rouge/demos/solidity +13 -0
  17. data/lib/rouge/demos/vcl +12 -0
  18. data/lib/rouge/demos/yang +17 -0
  19. data/lib/rouge/formatters/terminal256.rb +22 -6
  20. data/lib/rouge/formatters/terminal_truecolor.rb +37 -0
  21. data/lib/rouge/lexer.rb +5 -3
  22. data/lib/rouge/lexers/apache.rb +4 -8
  23. data/lib/rouge/lexers/apache/keywords.rb +15 -0
  24. data/lib/rouge/lexers/cmake.rb +1 -0
  25. data/lib/rouge/lexers/coffeescript.rb +47 -15
  26. data/lib/rouge/lexers/console.rb +88 -35
  27. data/lib/rouge/lexers/cpp.rb +12 -5
  28. data/lib/rouge/lexers/cypher.rb +108 -0
  29. data/lib/rouge/lexers/d.rb +4 -4
  30. data/lib/rouge/lexers/datastudio.rb +138 -0
  31. data/lib/rouge/lexers/dot.rb +2 -2
  32. data/lib/rouge/lexers/ecl.rb +175 -0
  33. data/lib/rouge/lexers/freefem.rb +240 -0
  34. data/lib/rouge/lexers/fsharp.rb +1 -0
  35. data/lib/rouge/lexers/ghc_cmm.rb +340 -0
  36. data/lib/rouge/lexers/ghc_core.rb +151 -0
  37. data/lib/rouge/lexers/gherkin.rb +1 -1
  38. data/lib/rouge/lexers/io.rb +2 -2
  39. data/lib/rouge/lexers/isbl.rb +97 -0
  40. data/lib/rouge/lexers/isbl/builtins.rb +17 -0
  41. data/lib/rouge/lexers/java.rb +4 -5
  42. data/lib/rouge/lexers/jinja.rb +5 -3
  43. data/lib/rouge/lexers/json.rb +3 -0
  44. data/lib/rouge/lexers/json_doc.rb +5 -3
  45. data/lib/rouge/lexers/kotlin.rb +4 -0
  46. data/lib/rouge/lexers/lasso.rb +4 -9
  47. data/lib/rouge/lexers/lasso/keywords.rb +14 -0
  48. data/lib/rouge/lexers/liquid.rb +1 -1
  49. data/lib/rouge/lexers/llvm.rb +55 -46
  50. data/lib/rouge/lexers/lua.rb +40 -2
  51. data/lib/rouge/lexers/m68k.rb +2 -2
  52. data/lib/rouge/lexers/magik.rb +1 -1
  53. data/lib/rouge/lexers/markdown.rb +9 -5
  54. data/lib/rouge/lexers/mathematica.rb +1 -1
  55. data/lib/rouge/lexers/matlab.rb +3 -4
  56. data/lib/rouge/lexers/matlab/builtins.rb +11 -0
  57. data/lib/rouge/lexers/nasm.rb +42 -168
  58. data/lib/rouge/lexers/nesasm.rb +78 -0
  59. data/lib/rouge/lexers/nginx.rb +1 -1
  60. data/lib/rouge/lexers/objective_c.rb +3 -172
  61. data/lib/rouge/lexers/objective_c/common.rb +184 -0
  62. data/lib/rouge/lexers/objective_cpp.rb +31 -0
  63. data/lib/rouge/lexers/pascal.rb +1 -1
  64. data/lib/rouge/lexers/php.rb +47 -32
  65. data/lib/rouge/lexers/pony.rb +1 -1
  66. data/lib/rouge/lexers/powershell.rb +5 -0
  67. data/lib/rouge/lexers/protobuf.rb +1 -1
  68. data/lib/rouge/lexers/python.rb +68 -58
  69. data/lib/rouge/lexers/racket.rb +24 -1
  70. data/lib/rouge/lexers/rego.rb +45 -0
  71. data/lib/rouge/lexers/ruby.rb +16 -3
  72. data/lib/rouge/lexers/rust.rb +3 -11
  73. data/lib/rouge/lexers/scala.rb +4 -4
  74. data/lib/rouge/lexers/shell.rb +1 -1
  75. data/lib/rouge/lexers/sieve.rb +1 -1
  76. data/lib/rouge/lexers/slice.rb +32 -0
  77. data/lib/rouge/lexers/solidity.rb +185 -0
  78. data/lib/rouge/lexers/sqf.rb +2 -2
  79. data/lib/rouge/lexers/swift.rb +2 -1
  80. data/lib/rouge/lexers/terraform.rb +15 -0
  81. data/lib/rouge/lexers/toml.rb +39 -1
  82. data/lib/rouge/lexers/typescript.rb +11 -0
  83. data/lib/rouge/lexers/varnish.rb +168 -0
  84. data/lib/rouge/lexers/verilog.rb +1 -1
  85. data/lib/rouge/lexers/viml.rb +1 -1
  86. data/lib/rouge/lexers/vue.rb +4 -1
  87. data/lib/rouge/lexers/yang.rb +147 -0
  88. data/lib/rouge/version.rb +1 -1
  89. metadata +37 -6
  90. data/lib/rouge/lexers/apache/keywords.yml +0 -764
  91. data/lib/rouge/lexers/lasso/keywords.yml +0 -446
  92. data/lib/rouge/lexers/matlab/builtins.yml +0 -3515
@@ -0,0 +1,37 @@
1
+ # -*- coding: utf-8 -*- #
2
+ # frozen_string_literal: true
3
+ module Rouge
4
+ module Formatters
5
+ class TerminalTruecolor < Terminal256
6
+ tag 'terminal_truecolor'
7
+
8
+ class TruecolorEscapeSequence < Terminal256::EscapeSequence
9
+ def style_string
10
+ @style_string ||= begin
11
+ out = String.new('')
12
+ out << escape(['48', '2', *get_rgb(style.bg)]) if style.bg
13
+ out << escape(['38', '2', *get_rgb(style.fg)]) if style.fg
14
+ out << escape(['1']) if style[:bold] || style[:italic]
15
+ out
16
+ end
17
+ end
18
+
19
+ def get_rgb(color)
20
+ color = $1 if color =~ /#(\h+)/
21
+
22
+ case color.size
23
+ when 3 then color.chars.map { |c| c.to_i(16) * 2 }
24
+ when 6 then color.scan(/../).map { |cc| cc.to_i(16) }
25
+ else
26
+ raise "invalid color: #{color.inspect}"
27
+ end
28
+ end
29
+ end
30
+
31
+ # @override
32
+ def make_escape_sequence(style)
33
+ TruecolorEscapeSequence.new(style)
34
+ end
35
+ end
36
+ end
37
+ end
@@ -209,7 +209,8 @@ module Rouge
209
209
  # Determine if a lexer has a method named +:detect?+ defined in its
210
210
  # singleton class.
211
211
  def detectable?
212
- @detectable ||= methods(false).include?(:detect?)
212
+ return @detectable if defined?(@detectable)
213
+ @detectable = singleton_methods(false).include?(:detect?)
213
214
  end
214
215
 
215
216
  protected
@@ -318,7 +319,7 @@ module Rouge
318
319
 
319
320
  def as_bool(val)
320
321
  case val
321
- when nil, false, 0, '0', 'off'
322
+ when nil, false, 0, '0', 'false', 'off'
322
323
  false
323
324
  when Array
324
325
  val.empty? ? true : as_bool(val.last)
@@ -504,12 +505,13 @@ module Rouge
504
505
  end
505
506
 
506
507
  module Lexers
508
+ BASE_DIR = "#{__dir__}/lexers".freeze
507
509
  @_loaded_lexers = {}
508
510
 
509
511
  def self.load_lexer(relpath)
510
512
  return if @_loaded_lexers.key?(relpath)
511
513
  @_loaded_lexers[relpath] = true
512
- load File.join(__dir__, 'lexers', relpath)
514
+ load File.join(BASE_DIR, relpath)
513
515
  end
514
516
  end
515
517
  end
@@ -11,14 +11,10 @@ module Rouge
11
11
  mimetypes 'text/x-httpd-conf', 'text/x-apache-conf'
12
12
  filenames '.htaccess', 'httpd.conf'
13
13
 
14
- class << self
15
- attr_reader :keywords
16
- end
17
- # Load Apache keywords from separate YML file
18
- @keywords = ::YAML.load_file(File.join(__dir__, 'apache/keywords.yml')).tap do |h|
19
- h.each do |k,v|
20
- h[k] = Set.new v
21
- end
14
+ # self-modifying method that loads the keywords file
15
+ def self.keywords
16
+ load File.join(Lexers::BASE_DIR, 'apache/keywords.rb')
17
+ keywords
22
18
  end
23
19
 
24
20
  def name_for_token(token, kwtype, tktype)
@@ -0,0 +1,15 @@
1
+ # -*- coding: utf-8 -*- #
2
+ # frozen_string_literal: true
3
+
4
+ # automatically generated by `rake builtins:apache`
5
+ module Rouge
6
+ module Lexers
7
+ def Apache.keywords
8
+ @keywords ||= {}.tap do |h|
9
+ h[:sections] = Set.new ["directory", "directorymatch", "files", "filesmatch", "ifdefine", "ifmodule", "limit", "limitexcept", "location", "locationmatch", "proxy", "proxymatch", "virtualhost"]
10
+ h[:directives] = Set.new ["acceptfilter", "acceptmutex", "acceptpathinfo", "accessconfig", "accessfilename", "action", "addalt", "addaltbyencoding", "addaltbytype", "addcharset", "adddefaultcharset", "adddescription", "addencoding", "addhandler", "addicon", "addiconbyencoding", "addiconbytype", "addinputfilter", "addlanguage", "addmodule", "addmoduleinfo", "addoutputfilter", "addoutputfilterbytype", "addtype", "agentlog", "alias", "aliasmatch", "allow", "allowconnect", "allowencodedslashes", "allowmethods", "allowoverride", "allowoverridelist", "anonymous", "anonymous_authoritative", "anonymous_logemail", "anonymous_mustgiveemail", "anonymous_nouserid", "anonymous_verifyemail", "assignuserid", "authauthoritative", "authdbauthoritative", "authdbgroupfile", "authdbmauthoritative", "asyncrequestworkerfactor", "authbasicauthoritative", "authbasicfake", "authbasicprovider", "authbasicusedigestalgorithm", "authdbduserpwquery", "authdbduserrealmquery", "authdbmgroupfile", "authdbmtype", "authdbmuserfile", "authdbuserfile", "authdigestalgorithm", "authdigestdomain", "authdigestfile", "authdigestgroupfile", "authdigestnccheck", "authdigestnonceformat", "authdigestnoncelifetime", "authdigestprovider", "authdigestqop", "authdigestshmemsize", "authformauthoritative", "authformbody", "authformdisablenostore", "authformfakebasicauth", "authformlocation", "authformloginrequiredlocation", "authformloginsuccesslocation", "authformlogoutlocation", "authformmethod", "authformmimetype", "authformpassword", "authformprovider", "authformsitepassphrase", "authformsize", "authformusername", "authgroupfile", "authldapauthoritative", "authldapauthorizeprefix", "authldapbindauthoritative", "authldapbinddn", "authldapbindpassword", "authldapcharsetconfig", "authldapcompareasuser", "authldapcomparednonserver", "authldapdereferencealiases", "authldapenabled", "authldapfrontpagehack", "authldapgroupattribute", "authldapgroupattributeisdn", "authldapinitialbindasuser", "authldapinitialbindpattern", "authldapmaxsubgroupdepth", "authldapremoteuserattribute", "authldapremoteuserisdn", "authldapsearchasuser", "authldapsubgroupattribute", "authldapsubgroupclass", "authldapurl", "authmerging", "authname", "authncachecontext", "authncacheenable", "authncacheprovidefor", "authncachesocache", "authncachetimeout", "authnzfcgicheckauthnprovider", "authnzfcgidefineprovider", "authtype", "authuserfile", "authzdbdlogintoreferer", "authzdbdquery", "authzdbdredirectquery", "authzdbmtype", "authzsendforbiddenonfailure", "balancergrowth", "balancerinherit", "balancermember", "balancerpersist", "bindaddress", "browsermatch", "browsermatchnocase", "bs2000account", "bufferedlogs", "buffersize", "cachedefaultexpire", "cachedetailheader", "cachedirlength", "cachedirlevels", "cachedisable", "cacheenable", "cacheexpirycheck", "cachefile", "cacheforcecompletion", "cachegcclean", "cachegcdaily", "cachegcinterval", "cachegcmemusage", "cachegcunused", "cacheheader", "cacheignorecachecontrol", "cacheignoreheaders", "cacheignorenolastmod", "cacheignorequerystring", "cacheignoreurlsessionidentifiers", "cachekeybaseurl", "cachelastmodifiedfactor", "cachelock", "cachelockmaxage", "cachelockpath", "cachemaxexpire", "cachemaxfilesize", "cacheminexpire", "cacheminfilesize", "cachenegotiateddocs", "cachequickhandler", "cachereadsize", "cachereadtime", "cacheroot", "cachesize", "cachetimemargin", "cachesocache", "cachesocachemaxsize", "cachesocachemaxtime", "cachesocachemintime", "cachesocachereadsize", "cachesocachereadtime", "cachestaleonerror", "cachestoreexpired", "cachestorenostore", "cachestoreprivate", "cgidscripttimeout", "cgimapextension", "cgipassauth", "charsetdefault", "charsetoptions", "charsetsourceenc", "checkcaseonly", "checkspelling", "childperuserid", "clearmodulelist", "chrootdir", "contentdigest", "cookiedomain", "cookieexpires", "cookielog", "cookiename", "cookiestyle", "cookietracking", "coredumpdirectory", "customlog", "dav", "davdepthinfinity", "davgenericlockdb", "davlockdb", "davmintimeout", "dbdexptime", "dbdinitsql", "dbdkeep", "dbdmax", "dbdmin", "dbdparams", "dbdpersist", "dbdpreparesql", "dbdriver", "defaulticon", "defaultlanguage", "defaultmode", "defaultruntimedir", "defaulttype", "define", "deflatebuffersize", "deflatecompressionlevel", "deflatefilternote", "deflateinflatelimitrequestbody", "deflateinflateratioburst", "deflateinflateratiolimit", "deflatememlevel", "deflatewindowsize", "deny", "directorycheckhandler", "directoryindex", "directoryindexredirect", "directoryslash", "doctitle", "doctrailer", "documentroot", "dtraceprivileges", "dumpioinput", "dumpiooutput", "enableexceptionhook", "enablemmap", "enablesendfile", "error", "errordocument", "errorlog", "errorlogformat", "example", "expiresactive", "expiresbytype", "expiresdefault", "extendedstatus", "extfilterdefine", "extfilteroptions", "fallbackresource", "fancyindexing", "fileetag", "filterchain", "filterdeclare", "filterprotocol", "filterprovider", "filtertrace", "forcelanguagepriority", "forcetype", "forensiclog", "globallog", "gprofdir", "gracefulshutdowntimeout", "group", "h2direct", "h2keepalivetimeout", "h2maxsessionstreams", "h2maxworkeridleseconds", "h2maxworkers", "h2minworkers", "h2moderntlsonly", "h2push", "h2pushdiarysize", "h2pushpriority", "h2serializeheaders", "h2sessionextrafiles", "h2streammaxmemsize", "h2streamtimeout", "h2timeout", "h2tlscooldownsecs", "h2tlswarmupsize", "h2upgrade", "h2windowsize", "header", "headername", "headprefix", "headsuffix", "hidesys", "hideurl", "heartbeataddress", "heartbeatlisten", "heartbeatmaxservers", "heartbeatstorage", "heartbeatstorage", "hostnamelookups", "htmldir", "httplogfile", "identitycheck", "identitychecktimeout", "imapbase", "imapdefault", "imapmenu", "include", "includeoptional", "indexheadinsert", "indexignore", "indexignorereset", "indexoptions", "indexorderdefault", "indexstylesheet", "inputsed", "isapiappendlogtoerrors", "isapiappendlogtoquery", "isapicachefile", "isapifakeasync", "isapilognotsupported", "isapireadaheadbuffer", "keepalive", "keepalivetimeout", "keptbodysize", "languagepriority", "lasturls", "ldapcacheentries", "ldapcachettl", "ldapconnectionpoolttl", "ldapconnectiontimeout", "ldaplibrarydebug", "ldapopcacheentries", "ldapopcachettl", "ldapreferralhoplimit", "ldapreferrals", "ldapretries", "ldapretrydelay", "ldapsharedcachefile", "ldapsharedcachesize", "ldaptimeout", "ldaptrustedca", "ldaptrustedcatype", "ldaptrustedclientcert", "ldaptrustedglobalcert", "ldaptrustedmode", "ldapverifyservercert", "limitinternalrecursion", "limitrequestbody", "limitrequestfields", "limitrequestfieldsize", "limitrequestline", "limitxmlrequestbody", "listen", "listenbacklog", "listencoresbucketsratio", "loadfile", "loadmodule", "lockfile", "logformat", "logiotrackttfb", "loglevel", "logmessage", "luaauthzprovider", "luacodecache", "luahookaccesschecker", "luahookauthchecker", "luahookcheckuserid", "luahookfixups", "luahookinsertfilter", "luahooklog", "luahookmaptostorage", "luahooktranslatename", "luahooktypechecker", "luainherit", "luainputfilter", "luamaphandler", "luaoutputfilter", "luapackagecpath", "luapackagepath", "luaquickhandler", "luaroot", "luascope", "maxclients", "maxconnectionsperchild", "maxkeepaliverequests", "maxmemfree", "maxrequestsperchild", "maxrequestsperthread", "maxrangeoverlaps", "maxrangereversals", "maxranges", "maxrequestworkers", "maxspareservers", "maxsparethreads", "maxthreads", "maxthreadsperchild", "mcachemaxobjectcount", "mcachemaxobjectsize", "mcachemaxstreamingbuffer", "mcacheminobjectsize", "mcacheremovalalgorithm", "mcachesize", "memcacheconnttl", "mergetrailers", "metadir", "metafiles", "metasuffix", "mimemagicfile", "minspareservers", "minsparethreads", "mmapfile", "modemstandard", "modmimeusepathinfo", "multiviewsmatch", "mutex", "namevirtualhost", "nocache", "noproxy", "numservers", "nwssltrustedcerts", "nwsslupgradeable", "options", "order", "outputsed", "passenv", "pidfile", "port", "privatedir", "privilegesmode", "protocol", "protocolecho", "protocols", "protocolshonororder", "proxyaddheaders", "proxybadheader", "proxyblock", "proxydomain", "proxyerroroverride", "proxyexpressdbmfile", "proxyexpressdbmtype", "proxyexpressenable", "proxyftpdircharset", "proxyftpescapewildcards", "proxyftplistonwildcard", "proxyhtmlbufsize", "proxyhtmlcharsetout", "proxyhtmldoctype", "proxyhtmlenable", "proxyhtmlevents", "proxyhtmlextended", "proxyhtmlfixups", "proxyhtmlinterp", "proxyhtmllinks", "proxyhtmlmeta", "proxyhtmlstripcomments", "proxyhtmlurlmap", "proxyiobuffersize", "proxymaxforwards", "proxypass", "proxypassinherit", "proxypassinterpolateenv", "proxypassmatch", "proxypassreverse", "proxypassreversecookiedomain", "proxypassreversecookiepath", "proxypreservehost", "proxyreceivebuffersize", "proxyremote", "proxyremotematch", "proxyrequests", "proxyscgiinternalredirect", "proxyscgisendfile", "proxyset", "proxysourceaddress", "proxystatus", "proxytimeout", "proxyvia", "qualifyredirecturl", "readmename", "receivebuffersize", "redirect", "redirectmatch", "redirectpermanent", "redirecttemp", "refererignore", "refererlog", "reflectorheader", "remoteipheader", "remoteipinternalproxy", "remoteipinternalproxylist", "remoteipproxiesheader", "remoteiptrustedproxy", "remoteiptrustedproxylist", "removecharset", "removeencoding", "removehandler", "removeinputfilter", "removelanguage", "removeoutputfilter", "removetype", "requestheader", "requestreadtimeout", "require", "resourceconfig", "rewritebase", "rewritecond", "rewriteengine", "rewritelock", "rewritelog", "rewriteloglevel", "rewritemap", "rewriteoptions", "rewriterule", "rlimitcpu", "rlimitmem", "rlimitnproc", "satisfy", "scoreboardfile", "script", "scriptalias", "scriptaliasmatch", "scriptinterpretersource", "scriptlog", "scriptlogbuffer", "scriptloglength", "scriptsock", "securelisten", "seerequesttail", "sendbuffersize", "serveradmin", "serveralias", "serverlimit", "servername", "serverpath", "serverroot", "serversignature", "servertokens", "servertype", "session", "sessioncookiename", "sessioncookiename2", "sessioncookieremove", "sessioncryptocipher", "sessioncryptodriver", "sessioncryptopassphrase", "sessioncryptopassphrasefile", "sessiondbdcookiename", "sessiondbdcookiename2", "sessiondbdcookieremove", "sessiondbddeletelabel", "sessiondbdinsertlabel", "sessiondbdperuser", "sessiondbdselectlabel", "sessiondbdupdatelabel", "sessionenv", "sessionexclude", "sessionheader", "sessioninclude", "sessionmaxage", "setenv", "setenvif", "setenvifexpr", "setenvifnocase", "sethandler", "setinputfilter", "setoutputfilter", "ssiendtag", "ssierrormsg", "ssietag", "ssilastmodified", "ssilegacyexprparser", "ssistarttag", "ssitimeformat", "ssiundefinedecho", "sslcacertificatefile", "sslcacertificatepath", "sslcadnrequestfile", "sslcadnrequestpath", "sslcarevocationcheck", "sslcarevocationfile", "sslcarevocationpath", "sslcertificatechainfile", "sslcertificatefile", "sslcertificatekeyfile", "sslciphersuite", "sslcompression", "sslcryptodevice", "sslengine", "sslfips", "sslhonorcipherorder", "sslinsecurerenegotiation", "sslmutex", "sslocspdefaultresponder", "sslocspenable", "sslocspoverrideresponder", "sslocspproxyurl", "sslocsprespondertimeout", "sslocspresponsemaxage", "sslocspresponsetimeskew", "sslocspuserequestnonce", "sslopensslconfcmd", "ssloptions", "sslpassphrasedialog", "sslprotocol", "sslproxycacertificatefile", "sslproxycacertificatepath", "sslproxycarevocationcheck", "sslproxycarevocationfile", "sslproxycarevocationpath", "sslproxycheckpeercn", "sslproxycheckpeerexpire", "sslproxycheckpeername", "sslproxyciphersuite", "sslproxyengine", "sslproxymachinecertificatechainfile", "sslproxymachinecertificatefile", "sslproxymachinecertificatepath", "sslproxyprotocol", "sslproxyverify", "sslproxyverifydepth", "sslrandomseed", "sslrenegbuffersize", "sslrequire", "sslrequiressl", "sslsessioncache", "sslsessioncachetimeout", "sslsessionticketkeyfile", "sslsessiontickets", "sslsrpunknownuserseed", "sslsrpverifierfile", "sslstaplingcache", "sslstaplingerrorcachetimeout", "sslstaplingfaketrylater", "sslstaplingforceurl", "sslstaplingrespondertimeout", "sslstaplingresponsemaxage", "sslstaplingresponsetimeskew", "sslstaplingreturnrespondererrors", "sslstaplingstandardcachetimeout", "sslstrictsnivhostcheck", "sslusername", "sslusestapling", "sslverifyclient", "sslverifydepth", "startservers", "startthreads", "substitute", "substituteinheritbefore", "substitutemaxlinelength", "suexec", "suexecusergroup", "threadlimit", "threadsperchild", "threadstacksize", "timeout", "topsites", "topurls", "traceenable", "transferlog", "typesconfig", "undefine", "undefmacro", "unsetenv", "use", "usecanonicalname", "usecanonicalphysicalport", "user", "userdir", "vhostcgimode", "vhostcgiprivs", "vhostgroup", "vhostprivs", "vhostsecure", "vhostuser", "virtualdocumentroot", "virtualdocumentrootip", "virtualscriptalias", "virtualscriptaliasip", "win32disableacceptex", "watchdoginterval", "xbithack", "xml2encalias", "xml2encdefault", "xml2startparse"]
11
+ h[:values] = Set.new ["add", "All", "allow", "any", "append", "AuthConfig", "Basic", "CONNECT", "DELETE", "deny", "Digest", "double", "downgrade-1.0", "email", "env", "error", "ExecCGI", "FancyIndexing", "FileInfo", "FollowSymLinks", "force-response-1.0", "formatted", "from", "full", "Full", "GET", "gone", "group", "IconsAreLinks", "Includes", "IncludesNOEXEC", "Indexes", "inetd", "inherit", "Limit", "map", "Minimal", "MultiViews", "mutual-failure", "nocontent", "nokeepalive", "none", "None", "off", "on", "Options", "OPTIONS", "OS", "permanent", "POST", "PUT", "referer", "ScanHTMLTitles", "seeother", "semi-formatted", "set", "standalone", "SuppressDescription", "SuppressLastModified", "SuppressSize", "SymLinksIfOwnerMatch", "temporary", "unformatted", "unset", "URL", "user", "valid-user"]
12
+ end
13
+ end
14
+ end
15
+ end
@@ -164,6 +164,7 @@ module Rouge
164
164
  goto :bracket_string
165
165
  end
166
166
 
167
+ rule %r/\\"/, Text
167
168
  rule %r/"/, Str::Double, :quoted_argument
168
169
 
169
170
  rule %r/([A-Za-z_][A-Za-z0-9_]*)(#{SPACE}*)(\()/ do |m|
@@ -49,33 +49,54 @@ module Rouge
49
49
 
50
50
  id = /[$a-zA-Z_][a-zA-Z0-9_]*/
51
51
 
52
- state :comments_and_whitespace do
53
- rule %r/\s+/m, Text
52
+ state :comments do
54
53
  rule %r/###[^#].*?###/m, Comment::Multiline
55
54
  rule %r/#.*$/, Comment::Single
56
55
  end
57
56
 
58
- state :multiline_regex do
59
- # this order is important, so that #{ isn't interpreted
60
- # as a comment
61
- mixin :has_interpolation
62
- mixin :comments_and_whitespace
57
+ state :whitespace do
58
+ rule %r/\s+/m, Text
59
+ end
63
60
 
64
- rule %r(///([gim]+\b|\B)), Str::Regex, :pop!
65
- rule %r(/), Str::Regex
66
- rule %r([^/#]+), Str::Regex
61
+ state :regex_comment do
62
+ rule %r/^#(?!\{).*$/, Comment::Single
63
+ rule %r/(\s+)(#(?!\{).*)$/ do
64
+ groups Text, Comment::Single
65
+ end
67
66
  end
68
67
 
69
- state :slash_starts_regex do
70
- mixin :comments_and_whitespace
68
+ state :multiline_regex_begin do
71
69
  rule %r(///) do
72
70
  token Str::Regex
73
71
  goto :multiline_regex
74
72
  end
73
+ end
74
+
75
+ state :multiline_regex_end do
76
+ rule %r(///([gimy]+\b|\B)), Str::Regex, :pop!
77
+ end
78
+
79
+ state :multiline_regex do
80
+ mixin :multiline_regex_end
81
+ mixin :regex_comment
82
+ mixin :has_interpolation
83
+ mixin :comments
84
+ mixin :whitespace
85
+ mixin :code_escape
86
+
87
+ rule %r/\\\D/, Str::Escape
88
+ rule %r/\\\d+/, Name::Variable
89
+ rule %r/./m, Str::Regex
90
+ end
91
+
92
+ state :slash_starts_regex do
93
+ mixin :comments
94
+ mixin :whitespace
95
+ mixin :multiline_regex_begin
75
96
 
76
97
  rule %r(
77
98
  /(\\.|[^\[/\\\n]|\[(\\.|[^\]\\\n])*\])+/ # a regex
78
- ([gim]+\b|\B)
99
+ ([gimy]+\b|\B)
79
100
  )x, Str::Regex, :pop!
80
101
 
81
102
  rule(//) { pop! }
@@ -83,7 +104,9 @@ module Rouge
83
104
 
84
105
  state :root do
85
106
  rule(%r(^(?=\s|/|<!--))) { push :slash_starts_regex }
86
- mixin :comments_and_whitespace
107
+ mixin :comments
108
+ mixin :whitespace
109
+
87
110
  rule %r(
88
111
  [+][+]|--|~|&&|\band\b|\bor\b|\bis\b|\bisnt\b|\bnot\b|\bin\b|\bof\b|
89
112
  [?]|:|=|[|][|]|\\(?=\n)|(<<|>>>?|==?|!=?|[-<>+*`%&|^/])=?
@@ -129,10 +152,19 @@ module Rouge
129
152
  rule %r/'/, Str, :sqs
130
153
  end
131
154
 
155
+ state :code_escape do
156
+ rule %r(\\(
157
+ c[A-Z]|
158
+ x[0-9a-fA-F]{2}|
159
+ u[0-9a-fA-F]{4}|
160
+ u\{[0-9a-fA-F]{4}\}
161
+ ))x, Str::Escape
162
+ end
163
+
132
164
  state :strings do
133
165
  # all coffeescript strings are multi-line
134
166
  rule %r/[^#\\'"]+/m, Str
135
-
167
+ mixin :code_escape
136
168
  rule %r/\\./, Str::Escape
137
169
  rule %r/#/, Str
138
170
  end
@@ -3,16 +3,51 @@
3
3
 
4
4
  module Rouge
5
5
  module Lexers
6
+ # The {ConsoleLexer} class is intended to lex content that represents the
7
+ # text that would display in a console/terminal. As distinct from the
8
+ # {Shell} lexer, {ConsoleLexer} will try to parse out the prompt from each
9
+ # line before passing the remainder of the line to the language lexer for
10
+ # the shell (by default, the {Shell} lexer).
11
+ #
12
+ # The {ConsoleLexer} class accepts five options:
13
+ # 1. **lang**: the shell language to lex (default: `shell`);
14
+ # 2. **output**: the output language (default: `plaintext?token=Generic.Output`);
15
+ # 3. **prompt**: comma-separated list of strings that indicate the end of a
16
+ # prompt (default: `$,#,>,;`);
17
+ # 4. **comments**: whether to enable comments.
18
+ # 5. **error**: comma-separated list of strings that indicate the start of an
19
+ # error message
20
+ #
21
+ # The comments option, if enabled, will lex lines that begin with a `#` as a
22
+ # comment. Please note that this option will only work if the prompt is
23
+ # either not manually specified or, if manually specified, does not include
24
+ # the `#` character.
25
+ #
26
+ # Most Markdown lexers that recognise GitHub-Flavored Markdown syntax, will
27
+ # pass the language string to Rouge as written in the original document.
28
+ # This allows an end user to pass options to {ConsoleLexer} by passing them
29
+ # as CGI-style parameters as in the example below.
30
+ #
31
+ # @example
32
+ # <pre>Here's some regular text.
33
+ #
34
+ # ```console?comments=true
35
+ # # This is a comment
36
+ # $ cp foo bar
37
+ # ```
38
+ #
39
+ # Some more regular text.</pre>
6
40
  class ConsoleLexer < Lexer
7
41
  tag 'console'
8
42
  aliases 'terminal', 'shell_session', 'shell-session'
9
43
  filenames '*.cap'
10
- desc 'A generic lexer for shell sessions. Accepts ?lang and ?output lexer options, a ?prompt option, and ?comments to enable # comments.'
44
+ desc 'A generic lexer for shell sessions. Accepts ?lang and ?output lexer options, a ?prompt option, ?comments to enable # comments, and ?error to handle error messages.'
11
45
 
12
46
  option :lang, 'the shell language to lex (default: shell)'
13
47
  option :output, 'the output language (default: plaintext?token=Generic.Output)'
14
48
  option :prompt, 'comma-separated list of strings that indicate the end of a prompt. (default: $,#,>,;)'
15
49
  option :comments, 'enable hash-comments at the start of a line - otherwise interpreted as a prompt. (default: false, implied by ?prompt not containing `#`)'
50
+ option :error, 'comma-separated list of strings that indicate the start of an error message'
16
51
 
17
52
  def initialize(*)
18
53
  super
@@ -20,20 +55,7 @@ module Rouge
20
55
  @lang = lexer_option(:lang) { 'shell' }
21
56
  @output = lexer_option(:output) { PlainText.new(token: Generic::Output) }
22
57
  @comments = bool_option(:comments) { :guess }
23
- end
24
-
25
- def prompt_regex
26
- @prompt_regex ||= begin
27
- /^#{prompt_prefix_regex}(?:#{end_chars.map(&Regexp.method(:escape)).join('|')})/
28
- end
29
- end
30
-
31
- def end_chars
32
- @end_chars ||= if @prompt.any?
33
- @prompt.reject { |c| c.empty? }
34
- else
35
- %w($ # > ;)
36
- end
58
+ @error = list_option(:error) { nil }
37
59
  end
38
60
 
39
61
  # whether to allow comments. if manually specifying a prompt that isn't
@@ -47,11 +69,23 @@ module Rouge
47
69
  end
48
70
  end
49
71
 
50
- def prompt_prefix_regex
51
- if allow_comments?
52
- /[^<#]*?/m
72
+ def comment_regex
73
+ /\A\s*?#/
74
+ end
75
+
76
+ def end_chars
77
+ @end_chars ||= if @prompt.any?
78
+ @prompt.reject { |c| c.empty? }
79
+ elsif allow_comments?
80
+ %w($ > ;)
53
81
  else
54
- /.*?/m
82
+ %w($ # > ;)
83
+ end
84
+ end
85
+
86
+ def error_regex
87
+ @error_regex ||= if @error.any?
88
+ /^(?:#{@error.map(&Regexp.method(:escape)).join('|')})/
55
89
  end
56
90
  end
57
91
 
@@ -68,6 +102,10 @@ module Rouge
68
102
  end
69
103
  end
70
104
 
105
+ def line_regex
106
+ /(\\.|[^\\])*?(\n|$)/m
107
+ end
108
+
71
109
  def output_lexer
72
110
  @output_lexer ||= case @output
73
111
  when nil
@@ -81,25 +119,12 @@ module Rouge
81
119
  end
82
120
  end
83
121
 
84
- def line_regex
85
- /(\\.|[^\\])*?(\n|$)/m
86
- end
87
-
88
- def comment_regex
89
- /\A\s*?#/
90
- end
91
-
92
- def stream_tokens(input, &output)
93
- input = StringScanner.new(input)
94
- lang_lexer.reset!
95
- output_lexer.reset!
96
-
97
- process_line(input, &output) while !input.eos?
98
- end
99
-
100
122
  def process_line(input, &output)
101
123
  input.scan(line_regex)
102
124
 
125
+ # As a nicety, support the use of elisions in input text. A user can
126
+ # write a line with only `<...>` or one or more `.` characters and
127
+ # Rouge will treat it as a comment.
103
128
  if input[0] =~ /\A\s*(?:<[.]+>|[.]+)\s*\z/
104
129
  puts "console: matched snip #{input[0].inspect}" if @debug
105
130
  output_lexer.reset!
@@ -125,6 +150,12 @@ module Rouge
125
150
  lang_lexer.reset!
126
151
 
127
152
  yield Comment, input[0]
153
+ elsif error_regex =~ input[0]
154
+ puts "console: matched error #{input[0].inspect}" if @debug
155
+ output_lexer.reset!
156
+ lang_lexer.reset!
157
+
158
+ yield Generic::Error, input[0]
128
159
  else
129
160
  puts "console: matched output #{input[0].inspect}" if @debug
130
161
  lang_lexer.reset!
@@ -132,6 +163,28 @@ module Rouge
132
163
  output_lexer.continue_lex(input[0], &output)
133
164
  end
134
165
  end
166
+
167
+ def prompt_prefix_regex
168
+ if allow_comments?
169
+ /[^<#]*?/m
170
+ else
171
+ /.*?/m
172
+ end
173
+ end
174
+
175
+ def prompt_regex
176
+ @prompt_regex ||= begin
177
+ /^#{prompt_prefix_regex}(?:#{end_chars.map(&Regexp.method(:escape)).join('|')})/
178
+ end
179
+ end
180
+
181
+ def stream_tokens(input, &output)
182
+ input = StringScanner.new(input)
183
+ lang_lexer.reset!
184
+ output_lexer.reset!
185
+
186
+ process_line(input, &output) while !input.eos?
187
+ end
135
188
  end
136
189
  end
137
190
  end
@@ -22,10 +22,10 @@ module Rouge
22
22
 
23
23
  def self.keywords
24
24
  @keywords ||= super + Set.new(%w(
25
- asm auto catch const_cast delete dynamic_cast explicit export
26
- friend mutable namespace new operator private protected public
27
- reinterpret_cast restrict size_of static_cast template this throw
28
- throws typeid typename using virtual final override
25
+ asm auto catch const_cast delete dynamic_cast explicit export friend
26
+ mutable namespace new operator private protected public
27
+ reinterpret_cast restrict size_of static_cast this throw throws
28
+ typeid typename using virtual final override
29
29
 
30
30
  alignas alignof constexpr decltype noexcept static_assert
31
31
  thread_local try
@@ -57,7 +57,8 @@ module Rouge
57
57
  dq = /\d('?\d)*/
58
58
 
59
59
  prepend :statements do
60
- rule %r/class\b/, Keyword, :classname
60
+ rule %r/(class|struct)\b/, Keyword, :classname
61
+ rule %r/template\b/, Keyword, :template
61
62
  rule %r/\d+(\.\d+)?(?:h|(?:min)|s|(?:ms)|(?:us)|(?:ns))/, Num::Other
62
63
  rule %r((#{dq}[.]#{dq}?|[.]#{dq})(e[+-]?#{dq}[lu]*)?)i, Num::Float
63
64
  rule %r(#{dq}e[+-]?#{dq}[lu]*)i, Num::Float
@@ -77,6 +78,12 @@ module Rouge
77
78
  rule %r/[.]{3}/, Operator
78
79
  mixin :whitespace
79
80
  end
81
+
82
+ state :template do
83
+ rule %r/>/, Punctuation, :pop!
84
+ rule %r/typename\b/, Keyword, :classname
85
+ mixin :root
86
+ end
80
87
  end
81
88
  end
82
89
  end
@@ -0,0 +1,108 @@
1
+ # -*- coding: utf-8 -*- #
2
+ # frozen_string_literal: true
3
+
4
+ module Rouge
5
+ module Lexers
6
+ class Cypher < RegexLexer
7
+ tag 'cypher'
8
+ aliases 'cypher'
9
+ filenames '*.cypher'
10
+ mimetypes 'application/x-cypher-query'
11
+
12
+ title "Cypher"
13
+ desc 'The Cypher query language (neo4j.com/docs/cypher-manual)'
14
+
15
+ def self.functions
16
+ @functions ||= Set.new %w(
17
+ ABS ACOS ALLSHORTESTPATHS ASIN ATAN ATAN2 AVG CEIL COALESCE COLLECT
18
+ COS COT COUNT DATE DEGREES E ENDNODE EXP EXTRACT FILTER FLOOR
19
+ HAVERSIN HEAD ID KEYS LABELS LAST LEFT LENGTH LOG LOG10 LOWER LTRIM
20
+ MAX MIN NODE NODES PERCENTILECONT PERCENTILEDISC PI RADIANS RAND
21
+ RANGE REDUCE REL RELATIONSHIP RELATIONSHIPS REPLACE REVERSE RIGHT
22
+ ROUND RTRIM SHORTESTPATH SIGN SIN SIZE SPLIT SQRT STARTNODE STDEV
23
+ STDEVP STR SUBSTRING SUM TAIL TAN TIMESTAMP TOFLOAT TOINT TOINTEGER
24
+ TOSTRING TRIM TYPE UPPER
25
+ )
26
+ end
27
+
28
+ def self.predicates
29
+ @predicates ||= Set.new %w(
30
+ ALL AND ANY CONTAINS EXISTS HAS IN NONE NOT OR SINGLE XOR
31
+ )
32
+ end
33
+
34
+ def self.keywords
35
+ @keywords ||= Set.new %w(
36
+ AS ASC ASCENDING ASSERT BY CASE COMMIT CONSTRAINT CREATE CSV CYPHER
37
+ DELETE DESC DESCENDING DETACH DISTINCT DROP ELSE END ENDS EXPLAIN
38
+ FALSE FIELDTERMINATOR FOREACH FROM HEADERS IN INDEX IS JOIN LIMIT
39
+ LOAD MATCH MERGE NULL ON OPTIONAL ORDER PERIODIC PROFILE REMOVE
40
+ RETURN SCAN SET SKIP START STARTS THEN TRUE UNION UNIQUE UNWIND USING
41
+ WHEN WHERE WITH CALL YIELD
42
+ )
43
+ end
44
+
45
+ state :root do
46
+ rule %r/[\s]+/, Text
47
+ rule %r(//.*?$), Comment::Single
48
+
49
+ rule %r([*+\-<>=&|~%^]), Operator
50
+ rule %r/[{}),;\[\]]/, Str::Symbol
51
+
52
+ # literal number
53
+ rule %r/(\w+)(:)(\s*)(-?[._\d]+)/ do
54
+ groups Name::Label, Str::Delimiter, Text::Whitespace, Num
55
+ end
56
+
57
+ # function-like
58
+ # - "name("
59
+ # - "name ("
60
+ # - "name ("
61
+ rule %r/(\w+)(\s*)(\()/ do |m|
62
+ name = m[1].upcase
63
+ if self.class.functions.include? name
64
+ groups Name::Function, Text::Whitespace, Str::Symbol
65
+ elsif self.class.keywords.include? name
66
+ groups Keyword, Text::Whitespace, Str::Symbol
67
+ else
68
+ groups Name, Text::Whitespace, Str::Symbol
69
+ end
70
+ end
71
+
72
+ rule %r/:\w+/, Name::Class
73
+
74
+ # number range
75
+ rule %r/(-?\d+)(\.\.)(-?\d+)/ do
76
+ groups Num, Operator, Num
77
+ end
78
+
79
+ # numbers
80
+ rule %r/(\d+\.\d*|\d*\.\d+)(e[+-]?\d+)?/i, Num::Float
81
+ rule %r/\d+e[+-]?\d+/i, Num::Float
82
+ rule %r/0[0-7]+/, Num::Oct
83
+ rule %r/0x[a-f0-9]+/i, Num::Hex
84
+ rule %r/\d+/, Num::Integer
85
+
86
+ rule %r([.\w]+:), Name::Property
87
+
88
+ # remaining "("
89
+ rule %r/\(/, Str::Symbol
90
+
91
+ rule %r/[.\w$]+/ do |m|
92
+ match = m[0].upcase
93
+ if self.class.predicates.include? match
94
+ token Operator::Word
95
+ elsif self.class.keywords.include? match
96
+ token Keyword
97
+ else
98
+ token Name
99
+ end
100
+ end
101
+
102
+ rule %r/"(\\\\|\\"|[^"])*"/, Str::Double
103
+ rule %r/'(\\\\|\\'|[^'])*'/, Str::Single
104
+ rule %r/`(\\\\|\\`|[^`])*`/, Str::Backtick
105
+ end
106
+ end
107
+ end
108
+ end