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