forked from rouge-ruby/rouge
-
Notifications
You must be signed in to change notification settings - Fork 0
/
mason.rb
110 lines (87 loc) · 3.2 KB
/
mason.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# -*- coding: utf-8 -*- #
# frozen_string_literal: true
module Rouge
module Lexers
class Mason < TemplateLexer
title 'Mason'
desc 'The HTML::Mason framework (https://metacpan.org/pod/HTML::Mason)'
tag 'mason'
filenames '*.mi', '*.mc', '*.mas', '*.m', '*.mhtml', '*.mcomp', 'autohandler', 'dhandler'
mimetypes 'text/x-mason', 'application/x-mason'
def initialize(*)
super
@perl = Perl.new
end
# Note: If you add a tag in the lines below, you also need to modify "disambiguate '*.m'" in file disambiguation.rb
TEXT_BLOCKS = %w(text doc)
PERL_BLOCKS = %w(args flags attr init once shared perl cleanup filter)
COMPONENTS = %w(def method)
state :root do
mixin :mason_tags
end
state :mason_tags do
rule %r/\s+/, Text::Whitespace
rule %r/<%(#{TEXT_BLOCKS.join('|')})>/oi, Comment::Preproc, :text_block
rule %r/<%(#{PERL_BLOCKS.join('|')})>/oi, Comment::Preproc, :perl_block
rule %r/(<%(#{COMPONENTS.join('|')}))([^>]*)(>)/oi do |m|
token Comment::Preproc, m[1]
token Name, m[3]
token Comment::Preproc, m[4]
push :component_block
end
# perl line
rule %r/^(%)(.*)$/ do |m|
token Comment::Preproc, m[1]
delegate @perl, m[2]
end
# start of component call
rule %r/<%/, Comment::Preproc, :component_call
# start of component with content
rule %r/<&\|/ do
token Comment::Preproc
push :component_with_content
push :component_sub
end
# start of component substitution
rule %r/<&/, Comment::Preproc, :component_sub
# fallback to HTML until a mason tag is encountered
rule(/(.+?)(?=(<\/?&|<\/?%|^%|^#))/m) { delegate parent }
# if we get here, there's no more mason tags, so we parse the rest of the doc as HTML
rule(/.+/m) { delegate parent }
end
state :perl_block do
rule %r/<\/%(#{PERL_BLOCKS.join('|')})>/oi, Comment::Preproc, :pop!
rule %r/\s+/, Text::Whitespace
rule %r/^(#.*)$/, Comment
rule(/(.*?[^"])(?=<\/%)/m) { delegate @perl }
end
state :text_block do
rule %r/<\/%(#{TEXT_BLOCKS.join('|')})>/oi, Comment::Preproc, :pop!
rule %r/\s+/, Text::Whitespace
rule %r/^(#.*)$/, Comment
rule %r/(.*?[^"])(?=<\/%)/m, Comment
end
state :component_block do
rule %r/<\/%(#{COMPONENTS.join('|')})>/oi, Comment::Preproc, :pop!
rule %r/\s+/, Text::Whitespace
rule %r/^(#.*)$/, Comment
mixin :mason_tags
end
state :component_with_content do
rule %r/<\/&>/ do
token Comment::Preproc
pop!
end
mixin :mason_tags
end
state :component_sub do
rule %r/&>/, Comment::Preproc, :pop!
rule(/(.*?)(?=&>)/m) { delegate @perl }
end
state :component_call do
rule %r/%>/, Comment::Preproc, :pop!
rule(/(.*?)(?=%>)/m) { delegate @perl }
end
end
end
end