xref: /vim-8.2.3635/runtime/syntax/xml.vim (revision 96f45c0b)
1" Vim syntax file
2" Language: XML
3" Maintainer: Christian Brabandt <[email protected]>
4" Repository: https://github.com/chrisbra/vim-xml-ftplugin
5" Previous Maintainer: Johannes Zellner <[email protected]>
6" Author: Paul Siegmann <[email protected]>
7" Last Changed:	Sept 24, 2019
8" Filenames:	*.xml
9" Last Change:
10" 20190923 - Fix xmlEndTag to match xmlTag (vim/vim#884)
11" 20190924 - Fix xmlAttribute property (amadeus/vim-xml@d8ce1c946)
12
13" CONFIGURATION:
14"   syntax folding can be turned on by
15"
16"      let g:xml_syntax_folding = 1
17"
18"   before the syntax file gets loaded (e.g. in ~/.vimrc).
19"   This might slow down syntax highlighting significantly,
20"   especially for large files.
21"
22" CREDITS:
23"   The original version was derived by Paul Siegmann from
24"   Claudio Fleiner's html.vim.
25"
26" REFERENCES:
27"   [1] http://www.w3.org/TR/2000/REC-xml-20001006
28"   [2] http://www.w3.org/XML/1998/06/xmlspec-report-19980910.htm
29"
30"   as <[email protected]> pointed out according to reference [1]
31"
32"   2.3 Common Syntactic Constructs
33"   [4]    NameChar    ::=    Letter | Digit | '.' | '-' | '_' | ':' | CombiningChar | Extender
34"   [5]    Name        ::=    (Letter | '_' | ':') (NameChar)*
35"
36" NOTE:
37"   1) empty tag delimiters "/>" inside attribute values (strings)
38"      confuse syntax highlighting.
39"   2) for large files, folding can be pretty slow, especially when
40"      loading a file the first time and viewoptions contains 'folds'
41"      so that folds of previous sessions are applied.
42"      Don't use 'foldmethod=syntax' in this case.
43
44
45" Quit when a syntax file was already loaded
46if exists("b:current_syntax")
47    finish
48endif
49
50let s:xml_cpo_save = &cpo
51set cpo&vim
52
53syn case match
54
55" mark illegal characters
56syn match xmlError "[<&]"
57
58" strings (inside tags) aka VALUES
59"
60" EXAMPLE:
61"
62" <tag foo.attribute = "value">
63"                      ^^^^^^^
64syn region  xmlString contained start=+"+ end=+"+ contains=xmlEntity,@Spell display
65syn region  xmlString contained start=+'+ end=+'+ contains=xmlEntity,@Spell display
66
67
68" punctuation (within attributes) e.g. <tag xml:foo.attribute ...>
69"                                              ^   ^
70" syn match   xmlAttribPunct +[-:._]+ contained display
71syn match   xmlAttribPunct +[:.]+ contained display
72
73" no highlighting for xmlEqual (xmlEqual has no highlighting group)
74syn match   xmlEqual +=+ display
75
76
77" attribute, everything before the '='
78"
79" PROVIDES: @xmlAttribHook
80"
81" EXAMPLE:
82"
83" <tag foo.attribute = "value">
84"      ^^^^^^^^^^^^^
85"
86syn match   xmlAttrib
87    \ +[-'"<]\@1<!\<[a-zA-Z:_][-.0-9a-zA-Z:_]*\>\%(['"]\@!\|$\)+
88    \ contained
89    \ contains=xmlAttribPunct,@xmlAttribHook
90    \ display
91
92
93" namespace spec
94"
95" PROVIDES: @xmlNamespaceHook
96"
97" EXAMPLE:
98"
99" <xsl:for-each select = "lola">
100"  ^^^
101"
102if exists("g:xml_namespace_transparent")
103syn match   xmlNamespace
104    \ +\(<\|</\)\@2<=[^ /!?<>"':]\+[:]\@=+
105    \ contained
106    \ contains=@xmlNamespaceHook
107    \ transparent
108    \ display
109else
110syn match   xmlNamespace
111    \ +\(<\|</\)\@2<=[^ /!?<>"':]\+[:]\@=+
112    \ contained
113    \ contains=@xmlNamespaceHook
114    \ display
115endif
116
117
118" tag name
119"
120" PROVIDES: @xmlTagHook
121"
122" EXAMPLE:
123"
124" <tag foo.attribute = "value">
125"  ^^^
126"
127syn match   xmlTagName
128    \ +\%(<\|</\)\@2<=[^ /!?<>"']\++
129    \ contained
130    \ contains=xmlNamespace,xmlAttribPunct,@xmlTagHook
131    \ display
132
133
134if exists('g:xml_syntax_folding')
135
136    " start tag
137    " use matchgroup=xmlTag to skip over the leading '<'
138    "
139    " PROVIDES: @xmlStartTagHook
140    "
141    " EXAMPLE:
142    "
143    " <tag id="whoops">
144    " s^^^^^^^^^^^^^^^e
145    "
146    syn region   xmlTag
147	\ matchgroup=xmlTag start=+<[^ /!?<>"']\@=+
148	\ matchgroup=xmlTag end=+>+
149	\ contained
150	\ contains=xmlError,xmlTagName,xmlAttrib,xmlEqual,xmlString,@xmlStartTagHook
151
152
153    " highlight the end tag
154    "
155    " PROVIDES: @xmlTagHook
156    " (should we provide a separate @xmlEndTagHook ?)
157    "
158    " EXAMPLE:
159    "
160    " </tag>
161    " ^^^^^^
162    "
163    syn region   xmlEndTag
164	\ matchgroup=xmlTag start=+</[^ /!?<>"']\@=+
165	\ matchgroup=xmlTag end=+>+
166	\ contained
167	\ contains=xmlTagName,xmlNamespace,xmlAttribPunct,@xmlTagHook
168
169    " tag elements with syntax-folding.
170    " NOTE: NO HIGHLIGHTING -- highlighting is done by contained elements
171    "
172    " PROVIDES: @xmlRegionHook
173    "
174    " EXAMPLE:
175    "
176    " <tag id="whoops">
177    "   <!-- comment -->
178    "   <another.tag></another.tag>
179    "   <empty.tag/>
180    "   some data
181    " </tag>
182    "
183    syn region   xmlRegion
184	\ start=+<\z([^ /!?<>"']\+\)+
185	\ skip=+<!--\_.\{-}-->+
186	\ end=+</\z1\_\s\{-}>+
187	\ end=+/>+
188	\ fold
189	\ contains=xmlTag,xmlEndTag,xmlCdata,xmlRegion,xmlComment,xmlEntity,xmlProcessing,@xmlRegionHook,@Spell
190	\ keepend
191	\ extend
192
193else
194
195    " no syntax folding:
196    " - contained attribute removed
197    " - xmlRegion not defined
198    "
199    syn region   xmlTag
200	\ matchgroup=xmlTag start=+<[^ /!?<>"']\@=+
201	\ matchgroup=xmlTag end=+>+
202	\ contains=xmlError,xmlTagName,xmlAttrib,xmlEqual,xmlString,@xmlStartTagHook
203
204    syn region   xmlEndTag
205	\ matchgroup=xmlTag start=+</[^ /!?<>"']\@=+
206	\ matchgroup=xmlTag end=+>+
207	\ contains=xmlTagName,xmlNamespace,xmlAttribPunct,@xmlTagHook
208
209endif
210
211
212" &entities; compare with dtd
213syn match   xmlEntity                 "&[^; \t]*;" contains=xmlEntityPunct
214syn match   xmlEntityPunct  contained "[&.;]"
215
216if exists('g:xml_syntax_folding')
217
218    " The real comments (this implements the comments as defined by xml,
219    " but not all xml pages actually conform to it. Errors are flagged.
220    syn region  xmlComment
221	\ start=+<!+
222	\ end=+>+
223	\ contains=xmlCommentStart,xmlCommentError
224	\ extend
225	\ fold
226
227else
228
229    " no syntax folding:
230    " - fold attribute removed
231    "
232    syn region  xmlComment
233	\ start=+<!+
234	\ end=+>+
235	\ contains=xmlCommentStart,xmlCommentError
236	\ extend
237
238endif
239
240syn match xmlCommentStart   contained "<!" nextgroup=xmlCommentPart
241syn keyword xmlTodo         contained TODO FIXME XXX
242syn match   xmlCommentError contained "[^><!]"
243syn region  xmlCommentPart
244    \ start=+--+
245    \ end=+--+
246    \ contained
247    \ contains=xmlTodo,@xmlCommentHook,@Spell
248
249
250" CData sections
251"
252" PROVIDES: @xmlCdataHook
253"
254syn region    xmlCdata
255    \ start=+<!\[CDATA\[+
256    \ end=+]]>+
257    \ contains=xmlCdataStart,xmlCdataEnd,@xmlCdataHook,@Spell
258    \ keepend
259    \ extend
260
261" using the following line instead leads to corrupt folding at CDATA regions
262" syn match    xmlCdata      +<!\[CDATA\[\_.\{-}]]>+  contains=xmlCdataStart,xmlCdataEnd,@xmlCdataHook
263syn match    xmlCdataStart +<!\[CDATA\[+  contained contains=xmlCdataCdata
264syn keyword  xmlCdataCdata CDATA          contained
265syn match    xmlCdataEnd   +]]>+          contained
266
267
268" Processing instructions
269" This allows "?>" inside strings -- good idea?
270syn region  xmlProcessing matchgroup=xmlProcessingDelim start="<?" end="?>" contains=xmlAttrib,xmlEqual,xmlString
271
272
273if exists('g:xml_syntax_folding')
274
275    " DTD -- we use dtd.vim here
276    syn region  xmlDocType matchgroup=xmlDocTypeDecl
277	\ start="<!DOCTYPE"he=s+2,rs=s+2 end=">"
278	\ fold
279	\ contains=xmlDocTypeKeyword,xmlInlineDTD,xmlString
280else
281
282    " no syntax folding:
283    " - fold attribute removed
284    "
285    syn region  xmlDocType matchgroup=xmlDocTypeDecl
286	\ start="<!DOCTYPE"he=s+2,rs=s+2 end=">"
287	\ contains=xmlDocTypeKeyword,xmlInlineDTD,xmlString
288
289endif
290
291syn keyword xmlDocTypeKeyword contained DOCTYPE PUBLIC SYSTEM
292syn region  xmlInlineDTD contained matchgroup=xmlDocTypeDecl start="\[" end="]" contains=@xmlDTD
293syn include @xmlDTD <sfile>:p:h/dtd.vim
294unlet b:current_syntax
295
296
297" synchronizing
298" TODO !!! to be improved !!!
299
300syn sync match xmlSyncDT grouphere  xmlDocType +\_.\(<!DOCTYPE\)\@=+
301" syn sync match xmlSyncDT groupthere  NONE       +]>+
302
303if exists('g:xml_syntax_folding')
304    syn sync match xmlSync grouphere   xmlRegion  +\_.\(<[^ /!?<>"']\+\)\@=+
305    " syn sync match xmlSync grouphere  xmlRegion "<[^ /!?<>"']*>"
306    syn sync match xmlSync groupthere  xmlRegion  +</[^ /!?<>"']\+>+
307endif
308
309syn sync minlines=100
310
311
312" The default highlighting.
313hi def link xmlTodo		Todo
314hi def link xmlTag		Function
315hi def link xmlTagName		Function
316hi def link xmlEndTag		Identifier
317if !exists("g:xml_namespace_transparent")
318    hi def link xmlNamespace	Tag
319endif
320hi def link xmlEntity		Statement
321hi def link xmlEntityPunct	Type
322
323hi def link xmlAttribPunct	Comment
324hi def link xmlAttrib		Type
325
326hi def link xmlString		String
327hi def link xmlComment		Comment
328hi def link xmlCommentStart	xmlComment
329hi def link xmlCommentPart	Comment
330hi def link xmlCommentError	Error
331hi def link xmlError		Error
332
333hi def link xmlProcessingDelim	Comment
334hi def link xmlProcessing	Type
335
336hi def link xmlCdata		String
337hi def link xmlCdataCdata	Statement
338hi def link xmlCdataStart	Type
339hi def link xmlCdataEnd		Type
340
341hi def link xmlDocTypeDecl	Function
342hi def link xmlDocTypeKeyword	Statement
343hi def link xmlInlineDTD	Function
344
345let b:current_syntax = "xml"
346
347let &cpo = s:xml_cpo_save
348unlet s:xml_cpo_save
349
350" vim: ts=8
351