Skip to content

Commit

Permalink
Smarty lexer
Browse files Browse the repository at this point in the history
This is based off the pygments one, and also the handlebars rogue
lexer.
  • Loading branch information
tringenbach committed Mar 14, 2016
1 parent d989f18 commit 5dc3bea
Show file tree
Hide file tree
Showing 4 changed files with 160 additions and 0 deletions.
12 changes: 12 additions & 0 deletions lib/rouge/demos/smarty
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{foo bar='single quotes' baz="double quotes" test3=$test3}

<ul>
{foreach from=$myvariable item=data}
<li>{$data.field}</li>
{foreachelse}
<li>No Data</li>
{/foreach}
</ul>

<div class="{if $foo}class1{else}class2{/if}">{$foo.bar.baz}</div>

81 changes: 81 additions & 0 deletions lib/rouge/lexers/smarty.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# -*- coding: utf-8 -*- #

module Rouge
module Lexers
class Smarty < TemplateLexer
title "Smarty"
desc 'Smarty Template Engine'
tag 'smarty'
aliases 'smarty'
filenames '*.tpl', '*.smarty'
mimetypes 'application/x-smarty'


def self.builtins
@builtins ||= %w(
append assign block call capture config_load debug extends
for foreach foreachelse break continue function if elseif
else include include_php insert ldelim rdelim literal nocache
php section sectionelse setfilter strip while
counter cycle eval fetch html_checkboxes html_image html_options
html_radios html_select_date html_select_time html_table
mailto math textformat
capitalize cat count_characters count_paragraphs
count_sentences count_words date_format default escape
from_charset indent lower nl2br regex_replace replace spacify
string_format strip strip_tags to_charset truncate unescape
upper wordwrap
)
end


state :root do
rule(/\{\s+/) { delegate parent }

# block comments
rule /\{\*.*?\*\}/m, Comment

rule /\{\/?(?![\s*])/ do
token Keyword
push :smarty
end


rule(/.*?(?={[\/a-zA-Z0-9$#*"'])|.*/m) { delegate parent }
rule(/.+/m) { delegate parent }
end

state :comment do
rule(/{\*/) { token Comment; push }
rule(/\*}/) { token Comment; pop! }
rule(/[^{}]+/m) { token Comment }
end

state :smarty do
# allow nested tags
rule /\{\/?(?![\s*])/ do
token Keyword
push :smarty
end

rule /}/, Keyword, :pop!
rule /\s+/m, Text
rule %r([~!%^&*()+=|\[\]:;,.<>/@?-]), Operator
rule /#[a-zA-Z_]\w*#/, Name::Variable
rule /\$[a-zA-Z_]\w*(\.\w+)*/, Name::Variable
rule /(true|false|null)\b/, Keyword::Constant
rule /[0-9](\.[0-9]*)?(eE[+-][0-9])?[flFLdD]?|0[xX][0-9a-fA-F]+[Ll]?/, Num
rule /"(\\.|.)*?"/, Str::Double
rule /'(\\.|.)*?'/, Str::Single
rule /([a-zA-Z_]\w*)/ do |m|
if self.class.builtins.include? m[0]
token Name::Builtin
else
token Name::Attribute
end
end
end

end
end
end
18 changes: 18 additions & 0 deletions spec/lexers/smarty_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# -*- coding: utf-8 -*- #

describe Rouge::Lexers::Smarty do
let(:subject) { Rouge::Lexers::Smarty.new }

describe 'guessing' do
include Support::Guessing

it 'guesses by filename' do
assert_guess :filename => 'foo.tpl'
assert_guess :filename => 'foo.smarty'
end

it 'guesses by mimetype' do
assert_guess :mimetype => 'text/x-smarty'
end
end
end
49 changes: 49 additions & 0 deletions spec/visual/samples/smarty
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{$foo}

<div>test</div>

<script type="text/javascript">
console.log({
foo: 'bar',
'foo2': 'bar2',
});
function test() {
console.log("Making sure we don't treat javascript's { 's as smarty tags");
}
</script>

<script type="text/javascript">
// This shows how a smarty tag inside of javascript does sometimes
// break things. I'm not sure how to fix this.
console.log({
foo: 'bar',
{test}
'foo2': 'bar2',
});
</script>

{* test comment *}
{foo} {$baz}

{foo} {bar} {baz}

{foo bar='single quotes' baz="double quotes" test3=$test3}

<ul>
{foreach from=$myvariable item=data}
<li>{$data.field}</li>
{foreachelse}
<li>No Data</li>
{/foreach}
</ul>

<div class="{if $foo}class1{else}class2{/if}">{$foo.bar.baz}</div>

{* test
multi-line
comment
*}

{$bar[42]}
{$bar.$foo}

0 comments on commit 5dc3bea

Please sign in to comment.