diff options
author | Tim Hatch <tim@timhatch.com> | 2014-04-14 17:18:09 -0400 |
---|---|---|
committer | Tim Hatch <tim@timhatch.com> | 2014-04-14 17:18:09 -0400 |
commit | d5fbe891177b85ada9d54239b1e86be059c63fc9 (patch) | |
tree | 5a25c483b54a330edb54940a98f5dfa36295d8d1 | |
parent | 653fafe1d33ceb7c4c0771c113e77926157db192 (diff) | |
parent | ad810cad22484e52bacc1b065d187c67dd1220bb (diff) | |
download | pygments-d5fbe891177b85ada9d54239b1e86be059c63fc9.tar.gz |
Merged in tboyt/pygments-main (pull request #186)
Conflicts:
pygments/lexers/_mapping.py
pygments/lexers/templates.py
-rw-r--r-- | pygments/lexers/_mapping.py | 4 | ||||
-rw-r--r-- | pygments/lexers/templates.py | 64 | ||||
-rw-r--r-- | tests/examplefiles/demo.hbs | 12 | ||||
-rw-r--r-- | tests/examplefiles/ember.handlebars | 33 |
4 files changed, 111 insertions, 2 deletions
diff --git a/pygments/lexers/_mapping.py b/pygments/lexers/_mapping.py index 79da0b5f..88909fb4 100644 --- a/pygments/lexers/_mapping.py +++ b/pygments/lexers/_mapping.py @@ -137,6 +137,8 @@ LEXERS = { 'GroffLexer': ('pygments.lexers.text', 'Groff', ('groff', 'nroff', 'man'), ('*.[1234567]', '*.man'), ('application/x-troff', 'text/troff')), 'GroovyLexer': ('pygments.lexers.jvm', 'Groovy', ('groovy',), ('*.groovy',), ('text/x-groovy',)), 'HamlLexer': ('pygments.lexers.web', 'Haml', ('haml',), ('*.haml',), ('text/x-haml',)), + 'HandlebarsHtmlLexer': ('pygments.lexers.templates', 'HTML+Handlebars', ('html+handlebars',), ('*.handlebars', '*.hbs'), ('text/html+handlebars', 'text/x-handlebars-template')), + 'HandlebarsLexer': ('pygments.lexers.templates', 'Handlebars', ('handlebars',), (), ()), 'HaskellLexer': ('pygments.lexers.functional', 'Haskell', ('haskell', 'hs'), ('*.hs',), ('text/x-haskell',)), 'HaxeLexer': ('pygments.lexers.web', 'Haxe', ('hx', 'haxe', 'hxsl'), ('*.hx', '*.hxsl'), ('text/haxe', 'text/x-haxe', 'text/x-hx')), 'HtmlDjangoLexer': ('pygments.lexers.templates', 'HTML+Django/Jinja', ('html+django', 'html+jinja', 'htmldjango'), (), ('text/html+django', 'text/html+jinja')), @@ -287,7 +289,7 @@ LEXERS = { 'RubyConsoleLexer': ('pygments.lexers.agile', 'Ruby irb session', ('rbcon', 'irb'), (), ('text/x-ruby-shellsession',)), 'RubyLexer': ('pygments.lexers.agile', 'Ruby', ('rb', 'ruby', 'duby'), ('*.rb', '*.rbw', 'Rakefile', '*.rake', '*.gemspec', '*.rbx', '*.duby'), ('text/x-ruby', 'application/x-ruby')), 'RustLexer': ('pygments.lexers.compiled', 'Rust', ('rust',), ('*.rs',), ('text/x-rustsrc',)), - 'SLexer': ('pygments.lexers.math', 'S', ('splus', 's', 'r'), ('*.S', '*.R', '.Rhistory', '.Rprofile'), ('text/S-plus', 'text/S', 'text/x-r-source', 'text/x-r', 'text/x-R', 'text/x-r-history', 'text/x-r-profile')), + 'SLexer': ('pygments.lexers.math', 'S', ('splus', 's', 'r'), ('*.S', '*.R', '.Rhistory', '.Rprofile', '.Renviron'), ('text/S-plus', 'text/S', 'text/x-r-source', 'text/x-r', 'text/x-R', 'text/x-r-history', 'text/x-r-profile')), 'SMLLexer': ('pygments.lexers.functional', 'Standard ML', ('sml',), ('*.sml', '*.sig', '*.fun'), ('text/x-standardml', 'application/x-standardml')), 'SassLexer': ('pygments.lexers.web', 'Sass', ('sass',), ('*.sass',), ('text/x-sass',)), 'ScalaLexer': ('pygments.lexers.jvm', 'Scala', ('scala',), ('*.scala',), ('text/x-scala',)), diff --git a/pygments/lexers/templates.py b/pygments/lexers/templates.py index 72f81d63..a2de2f9c 100644 --- a/pygments/lexers/templates.py +++ b/pygments/lexers/templates.py @@ -39,7 +39,8 @@ __all__ = ['HtmlPhpLexer', 'XmlPhpLexer', 'CssPhpLexer', 'ColdfusionHtmlLexer', 'ColdfusionCFCLexer', 'VelocityLexer', 'VelocityHtmlLexer', 'VelocityXmlLexer', 'SspLexer', 'TeaTemplateLexer', 'LassoHtmlLexer', 'LassoXmlLexer', - 'LassoCssLexer', 'LassoJavascriptLexer'] + 'LassoCssLexer', 'LassoJavascriptLexer', 'HandlebarsLexer', + 'HandlebarsHtmlLexer'] class ErbLexer(Lexer): @@ -1762,3 +1763,64 @@ class LassoJavascriptLexer(DelegatingLexer): if 'function' in text: rv += 0.2 return rv + +class HandlebarsLexer(RegexLexer): + """ + Generic `handlebars <http://handlebarsjs.com/>` template lexer. + + Highlights only the Handlebars template tags (stuff between `{{` and `}}`). + Everything else is left for a delegating lexer. + """ + + name = "Handlebars" + aliases = ['handlebars'] + + tokens = { + 'root': [ + (r'[^{]+', Other), + + (r'{{!.*}}', Comment), + + (r'({{{)(\s*)', bygroups(Comment.Special, Text), 'tag'), + (r'({{)(\s*)', bygroups(Comment.Preproc, Text), 'tag'), + ], + + 'tag': [ + (r'\s+', Text), + (r'\}\}\}', Comment.Special, '#pop'), + (r'\}\}', Comment.Preproc, '#pop'), + + # Handlebars + (r'([\#/]*)(each|if|unless|else|with|log|in)', bygroups(Keyword, + Keyword)), + + # General {{#block}} + (r'([\#/])(\w+)', bygroups(Name.Function, Name.Function)), + + # {{opt=something}} + (r'(\w+)(=)', bygroups(Name.Attribute, Operator)), + + # borrowed from DjangoLexer + (r':?"(\\\\|\\"|[^"])*"', String.Double), + (r":?'(\\\\|\\'|[^'])*'", String.Single), + (r'[a-zA-Z][a-zA-Z0-9_-]*', Name.Variable), + (r'\.[a-zA-Z0-9_]+', Name.Variable), + (r"[0-9](\.[0-9]*)?(eE[+-][0-9])?[flFLdD]?|" + r"0[xX][0-9a-fA-F]+[Ll]?", Number), + ] + } + + +class HandlebarsHtmlLexer(DelegatingLexer): + """ + Subclass of the `HandlebarsLexer` that highlights unlexed data with the + `HtmlLexer`. + """ + + name = "HTML+Handlebars" + aliases = ["html+handlebars"] + filenames = ['*.handlebars', '*.hbs'] + mimetypes = ['text/html+handlebars', 'text/x-handlebars-template'] + + def __init__(self, **options): + super(HandlebarsHtmlLexer, self).__init__(HtmlLexer, HandlebarsLexer, **options) diff --git a/tests/examplefiles/demo.hbs b/tests/examplefiles/demo.hbs new file mode 100644 index 00000000..1b9ed5a7 --- /dev/null +++ b/tests/examplefiles/demo.hbs @@ -0,0 +1,12 @@ +<!-- post.handlebars --> + +<div class='intro'> + {{intro}} +</div> + +{{#if isExpanded}} + <div class='body'>{{body}}</div> + <button {{action contract}}>Contract</button> +{{else}} + <button {{action expand}}>Show More...</button> +{{/if}} diff --git a/tests/examplefiles/ember.handlebars b/tests/examplefiles/ember.handlebars new file mode 100644 index 00000000..515dffbd --- /dev/null +++ b/tests/examplefiles/ember.handlebars @@ -0,0 +1,33 @@ +{{#view EmberFirebaseChat.ChatView class="chat-container"}} + <div class="chat-messages-container"> + <ul class="chat-messages"> + {{#each message in content}} + <li> + [{{formatTimestamp "message.timestamp" fmtString="h:mm:ss A"}}] + <strong>{{message.sender}}</strong>: {{message.content}} + </li> + {{/each}} + </ul> + </div> + + {{! Comment }} + {{{unescaped value}}} + + {{#view EmberFirebaseChat.InputView class="chat-input-container"}} + <form class="form-inline"> + {{#if "auth.authed"}} + {{#if "auth.hasName"}} + <input type="text" id="message" placeholder="Message"> + <button {{action "postMessage" target="view"}} class="btn">Send</button> + {{else}} + <input type="text" id="username" placeholder="Enter your username..."> + <button {{action "pickName" target="view"}} class="btn">Send</button> + {{/if}} + {{else}} + <input type="text" placeholder="Log in with Persona to chat!" disabled="disabled"> + <button {{action "login"}} class="btn">Login</button> + {{/if}} + </form> + {{/view}} +{{/view}} + |