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