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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
|
" Vim syntax file
" Language: CNM 0.3
" Maintainer: <clsr@clsr.net>
" Last Change: 2017-08-18
" Version: 0.1.0
" Filenames: *.cnm
" Bugs: Nested syntaxes in raw blocks include block indentation
if !exists('g:main_syntax')
if exists('b:current_syntax')
finish
endif
let g:main_syntax = 'cnm'
" sync from the current top-level element
syn sync match cnmSync grouphere NONE "^[^\t]"
"syn sync fromstart
endif
function! s:generateRawSyntaxes()
if !exists('g:cnm_raw_syntaxes')
"let g:cnm_raw_syntaxes = {
" \ 'text/json': 'json',
" \ 'application/json': 'json',
" \ 'json': 'json',
let g:cnm_raw_syntaxes = {
\ 'text/cnm': 'cnm',
\ 'cnm': 'cnm',
\ 'message/cnp': 'cnp',
\ 'application/cnp': 'cnp',
\ 'cnp': 'cnp',
\ 'text/cnm-fmt': 'cnmfmt',
\ 'cnm-fmt': 'cnmfmt',
\ 'cnmfmt': 'cnmfmt',
\ }
endif
if exists('g:cnm_raw_syntaxes_extra')
for [l:k, l:v] in items(g:cnm_raw_syntaxes_extra)
let g:cnm_raw_syntaxes[l:k] = l:v
endfor
endif
" CNM and CNMfmt syntaxes are already defined below as clusters
let l:syntaxes = {'Cnm': 1, 'Cnmfmt': 1}
for [l:lang, l:syntax] in items(g:cnm_raw_syntaxes)
let l:slang = substitute(l:syntax, '\(\w\+\)\W\?', '\u\1', 'g')
"try
if !has_key(l:syntaxes, l:slang)
exe 'syn include @cnmLang' . l:slang . ' syntax/' . l:syntax . '.vim'
unlet! b:current_syntax
let l:syntaxes[l:slang] = 1
endif
call s:generateBlock('raw ' . l:lang, 'cnmRaws', 'contained contains=@cnmLang' . l:slang)
"catch
"endtry
endfor
endfunction
function! s:generateBlock(name, cluster, options)
let l:region = 'cnm' . substitute(substitute(a:name, '\(\w\+\) \?', '\u\1', 'g'), '\W', '', 'g')
let l:name = substitute(a:name, ' ', '\\s\\+', 'g')
exe 'syn region ' . l:region . ' matchgroup=cnmBlock start="^\z(\t*\)\<' . l:name . '\(\s\|$\)\@=.*$" end="^\(\t*[^\t]\)\@=" skip="^\z1\t\+\([^\t]\)\@=" keepend ' . a:options
exe 'syn cluster ' . a:cluster . ' add=' . l:region
endfunction
syn include @cnmFmt syntax/cnmfmt.vim
" XXX: make `raw text/cnm` work
syn cluster cnmLangCnm contains=@cnmToplevelBLocks,@cnmContentBlocks,cnmError
" `raw text/cnm-fmt`
syn cluster cnmLangCnmfmt contains=@cnmFmt
" all blocks that contain other blocks
syn cluster cnmToplevelBlocks contains=cnmUnknown
syn cluster cnmContainerBlocks contains=cnmUnknown
syn cluster cnmContentBlocks contains=cnmUnknown,@cnmContainerBlocks,@cnmTexts,@cnmRaws,cnmEmbed
syn cluster cnmTableBlocks contains=cnmUnknown
" misc.
syn match cnmError ".*"
syn match cnmEscape "\\[nt\\ ]" contained
syn match cnmEscape "\\x\x\{2\}" contained
syn match cnmEscape "\\u\x\{4\}" contained
syn match cnmEscape "\\U\x\{8\}" contained
" top-level blocks
syn region cnmUnknown matchgroup=cnmError start="^\z(\t*\)[^\t].*$" end="^\(\t*[^\t]\)\@=" skip="^\z1\t\+\([^\t]\)\@=" keepend contains=cnmError
call s:generateBlock('content', 'cnmToplevelBlocks', 'contains=@cnmContentBlocks')
call s:generateBlock('site', 'cnmToplevelBlocks', 'contains=cnmSiteLines,cnmError')
call s:generateBlock('title', 'cnmToplevelBlocks', 'contains=cnmEscape,@Spell')
call s:generateBlock('links', 'cnmToplevelBlocks', 'contains=cnmLinkLines')
" content/
call s:generateBlock('section', 'cnmContainerBlocks', 'contained contains=@cnmContentBlocks')
call s:generateBlock('table', 'cnmContainerBlocks', 'contained contains=@cnmTableBlocks')
call s:generateBlock('list', 'cnmContainerBlocks', 'contained contains=@cnmContentBlocks')
" content/table/
call s:generateBlock('header', 'cnmTableBlocks', 'contained contains=@cnmContentBlocks')
call s:generateBlock('row', 'cnmTableBlocks', 'contained contains=@cnmContentBlocks')
" content/raw
call s:generateBlock('raw', 'cnmRaws', 'contained')
call s:generateRawSyntaxes()
" content/text
call s:generateBlock('text', 'cnmTexts', 'contained contains=cnmEscape,@Spell')
call s:generateBlock('text plain', 'cnmTexts', 'contained contains=cnmEscape,@Spell')
call s:generateBlock('text fmt', 'cnmTexts', 'contained contains=@cnmFmt,@Spell')
" content/embed
call s:generateBlock('embed', 'cnmEmbed', 'contained contains=cnmEscape,@Spell')
" links/
syn match cnmLinkLines "^.*$" keepend contained contains=cnmLinkUrl,cnmLinkText
syn match cnmLinkText "^\t\t.*" contained contains=cnmEscape
syn match cnmLinkUrl "\S\+" contained
" site/
syn match cnmSiteLines "^\t*[^\t ]\+\(\s.*\)\?$" keepend contained contains=cnmSitePath,cnmSiteText
syn match cnmSitePath "\S\+" contained contains=cnmSiteSlash
syn match cnmSiteText "\([^ \t]\)\@<=\s\+.*" contained contains=cnmEscape
syn match cnmSiteSlash "/\S\@=" contained
hi def link cnmBlock Keyword
hi def link cnmError Error
hi def link cnmLinkUrl Underlined
hi def link cnmLinkText String
hi def link cnmSitePath Underlined
hi def link cnmSiteSlash Keyword
hi def link cnmSiteText String
"hi def link cnmText String
hi def link cnmRaw String
hi def link cnmEmbed String
hi def link cnmTitle String
hi def link cnmEscape Special
syn match TODO "TODO" contained containedin=cnmText,@cnmFmt
hi def link TODO TODO
let b:current_syntax = 'cnm'
if g:main_syntax ==# 'cnm'
unlet g:main_syntax
endif
" vim: set noet:
|