vis: implement :set cursorline
[vis.git] / lexers / vcard.lua
blob20574514d490c75f9a17ab6106f780b28ae5ddad
1 -- Copyright (c) 2015 Piotr Orzechowski [drzewo.org]. See LICENSE.
2 -- vCard 2.1, 3.0 and 4.0 LPeg lexer.
4 local l = require('lexer')
5 local token, word_match = l.token, l.word_match
6 local P, R, S = lpeg.P, lpeg.R, lpeg.S
8 local M = {_NAME = 'vcard'}
10 -- Whitespace.
11 local ws = token(l.WHITESPACE, l.space^1)
13 -- Required properties.
14 local required_property = token(l.KEYWORD, word_match({
15 'BEGIN', 'END', 'FN', 'N' --[[ Not required in v4.0. ]], 'VERSION'
16 }, nil, true)) * #P(':')
18 -- Supported properties.
19 local supported_property = token(l.TYPE, word_match({
20 'ADR', 'AGENT' --[[ Not supported in v4.0. ]],
21 'ANNIVERSARY' --[[ Supported in v4.0 only. ]], 'BDAY',
22 'CALADRURI' --[[ Supported in v4.0 only. ]],
23 'CALURI' --[[ Supported in v4.0 only. ]], 'CATEGORIES',
24 'CLASS' --[[ Supported in v3.0 only. ]],
25 'CLIENTPIDMAP' --[[ Supported in v4.0 only. ]], 'EMAIL', 'END',
26 'FBURL' --[[ Supported in v4.0 only. ]],
27 'GENDER' --[[ Supported in v4.0 only. ]], 'GEO',
28 'IMPP' --[[ Not supported in v2.1. ]], 'KEY',
29 'KIND' --[[ Supported in v4.0 only. ]],
30 'LABEL' --[[ Not supported in v4.0. ]],
31 'LANG' --[[ Supported in v4.0 only. ]], 'LOGO',
32 'MAILER' --[[ Not supported in v4.0. ]],
33 'MEMBER' --[[ Supported in v4.0 only. ]],
34 'NAME' --[[ Supported in v3.0 only. ]],
35 'NICKNAME' --[[ Not supported in v2.1. ]], 'NOTE', 'ORG', 'PHOTO',
36 'PRODID' --[[ Not supported in v2.1. ]],
37 'PROFILE' --[[ Not supported in v4.0. ]],
38 'RELATED' --[[ Supported in v4.0 only. ]], 'REV', 'ROLE',
39 'SORT-STRING' --[[ Not supported in v4.0. ]], 'SOUND', 'SOURCE', 'TEL',
40 'TITLE', 'TZ', 'UID', 'URL', 'XML' --[[ Supported in v4.0 only. ]]
41 }, nil, true)) * #S(':;')
43 local identifier = l.alpha^1 * l.digit^0 * (P('-') * l.alnum^1)^0
45 -- Extension.
46 local extension = token(l.TYPE,
47 l.starts_line(S('xX') * P('-') * identifier * #S(':;')))
49 -- Parameter.
50 local parameter = token(l.IDENTIFIER, l.starts_line(identifier * #S(':='))) +
51 token(l.STRING, identifier) * #S(':=')
53 -- Operators.
54 local operator = token(l.OPERATOR, S('.:;='))
56 -- Group and property.
57 local group_sequence = token(l.CONSTANT, l.starts_line(identifier)) *
58 token(l.OPERATOR, P('.')) *
59 (required_property + supported_property +
60 l.token(l.TYPE, S('xX') * P('-') * identifier) *
61 #S(':;'))
62 -- Begin vCard, end vCard.
63 local begin_sequence = token(l.KEYWORD, P('BEGIN')) *
64 token(l.OPERATOR, P(':')) * token(l.COMMENT, P('VCARD'))
65 local end_sequence = token(l.KEYWORD, P('END')) * token(l.OPERATOR, P(':')) *
66 token(l.COMMENT, P('VCARD'))
68 -- vCard version (in v3.0 and v4.0 must appear immediately after BEGIN:VCARD).
69 local version_sequence = token(l.KEYWORD, P('VERSION')) *
70 token(l.OPERATOR, P(':')) *
71 token(l.CONSTANT, l.digit^1 * (P('.') * l.digit^1)^-1)
73 -- Data.
74 local data = token(l.IDENTIFIER, l.any)
76 -- Rules.
77 M._rules = {
78 {'whitespace', ws},
79 {'begin_sequence', begin_sequence},
80 {'end_sequence', end_sequence},
81 {'version_sequence', version_sequence},
82 {'group_sequence', group_sequence},
83 {'required_property', required_property},
84 {'supported_property', supported_property},
85 {'extension', extension},
86 {'parameter', parameter},
87 {'operator', operator},
88 {'data', data},
91 -- Folding.
92 M._foldsymbols = {
93 _patterns = {'BEGIN', 'END'},
94 [l.KEYWORD] = {['BEGIN'] = 1, ['END'] = -1}
97 return M