1 -- Copyright 2006-2015 Mitchell mitchell.att.foicica.com. See LICENSE.
2 -- WSF LPeg lexer (based on XML).
3 -- Contributed by Jeff Stone.
5 local l
= require('lexer')
6 local token
, word_match
= l
.token
, l
.word_match
7 local P
, R
, S
, V
= lpeg
.P
, lpeg
.R
, lpeg
.S
, lpeg
.V
9 local M
= {_NAME
= 'wsf'}
12 local ws
= token(l
.WHITESPACE
, l
.space^
1)
15 local comment
= token(l
.COMMENT
, '<!--' * (l
.any
- '-->')^
0 * P('-->')^
-1)
18 local sq_str
= l
.delimited_range("'", false, true)
19 local dq_str
= l
.delimited_range('"', false, true)
20 local string = #S('\'"') * l
.last_char_includes('=') *
21 token(l
.STRING
, sq_str
+ dq_str
)
23 local in_tag
= P(function(input
, index
)
24 local before
= input
:sub(1, index
- 1)
25 local s
, e
= before
:find('<[^>]-$'), before
:find('>[^<]-$')
26 if s
and e
then return s
> e
and index
or nil end
27 if s
then return index
end
28 return input
:find('^[^<]->', index
) and index
or nil
32 local number = #l
.digit
* l
.last_char_includes('=') *
33 token(l
.NUMBER
, l
.digit^
1 * P('%')^
-1) * in_tag
35 local alpha
= R('az', 'AZ', '\127\255')
36 local word_char
= l
.alnum
+ S('_-:.??')
37 local identifier
= (l
.alpha
+ S('_-:.??')) * word_char^
0
40 local element
= token('element', '<' * P('/')^
-1 * identifier
)
43 local attribute
= token('attribute', identifier
) * #(l
.space^
0 * '=')
46 local tag_close
= token('element', P('/')^
-1 * '>')
49 local equals
= token(l
.OPERATOR
, '=') * in_tag
52 local entity
= token('entity', '&' * word_match
{
53 'lt', 'gt', 'amp', 'apos', 'quot'
60 {'tag_close', tag_close
},
61 {'attribute', attribute
},
69 element
= l
.STYLE_KEYWORD
,
70 attribute
= l
.STYLE_TYPE
,
71 entity
= l
.STYLE_OPERATOR
75 _patterns
= {'</?', '/>', '<!%-%-', '%-%->'},
76 element
= {['<'] = 1, ['/>'] = -1, ['</'] = -1},
77 [l
.COMMENT
] = {['<!--'] = 1, ['-->'] = -1},
80 -- Finally, add JavaScript and VBScript as embedded languages
82 -- Tags that start embedded languages.
83 M
.embed_start_tag
= element
*
84 (ws^
1 * attribute
* ws^
0 * equals
* ws^
0 * string)^
0 *
86 M
.embed_end_tag
= element
* tag_close
88 -- Embedded JavaScript.
89 local js
= l
.load('javascript')
90 local js_start_rule
= #(P('<script') * (P(function(input
, index
)
91 if input
:find('^%s+language%s*=%s*(["\'])[jJ][ava]*[sS]cript%1', index
) then
94 end) + '>')) * M
.embed_start_tag
-- <script language="javascript">
95 local js_end_rule
= #('</script' * ws^
0 * '>') * M
.embed_end_tag
-- </script>
96 l
.embed_lexer(M
, js
, js_start_rule
, js_end_rule
)
99 local vbs
= l
.load('vbscript')
100 local vbs_start_rule
= #(P('<script') * (P(function(input
, index
)
101 if input
:find('^%s+language%s*=%s*(["\'])[vV][bB][sS]cript%1', index
) then
104 end) + '>')) * M
.embed_start_tag
-- <script language="vbscript">
105 local vbs_end_rule
= #('</script' * ws^
0 * '>') * M
.embed_end_tag
-- </script>
106 l
.embed_lexer(M
, vbs
, vbs_start_rule
, vbs_end_rule
)