<?xml version="1.0"?>
<syntax name="language-root.apache">
	<zones>
		<!--Comments-->
		<zone>
			<expression>(^\s*(#{2,})\s*\S.*?(#*)\s*$[\n\r]*)|(^\s*(#).*$[\n\r]*)|(\\$)</expression>
			<!-- Bookmark comments -->
			<capture number="1" name="comment.line.bookmark"/>
			<capture number="2" name="punctuation.definition.begin"/>
			<capture number="3" name="punctuation.definition.end"/>
			<!-- Normal comments -->
			<capture number="4" name="comment.line"/>
			<capture number="5" name="punctuation.definition.begin"/>
			<!-- Line continuation -->
			<capture number="6" name="punctuation.continuation.backslash"/>
		</zone>
		
		<include collection="strings" />
		
		<!--Flow control-->
		
		<zone name="tag.open">
			<starts-with>
				<expression>(&lt;)([a-zA-Z]*)\b</expression>
				<capture number="1" name="punctuation.definition.begin"/>
				<capture number="2" name="keyword.directive.name"/>
			</starts-with>
			<ends-with>
				<expression>(>)</expression>
				<capture number="1" name="punctuation.definition.end"/>
			</ends-with>
			<subzones name="condition">
				<include collection="strings" />
				<zone name="operator.logical">
					<expression>!</expression>
				</zone>
				<zone name="operator.regex-toggle">
					<expression>(?&lt;=\s)~(?=\s)</expression>
				</zone>
			</subzones>
		</zone>
		
		<zone name="tag.close">
			<starts-with>
				<expression>(&lt;/)([a-zA-Z]+)</expression>
				<capture number="1" name="punctuation.definition.begin"/>
				<capture number="2" name="keyword.directive.name"/>
			</starts-with>
			<ends-with>
				<expression>(>)</expression>
				<capture number="1" name="punctuation.definition.end"/>
			</ends-with>
		</zone>
		
		<!--Keywords-->
		<!-- Specific keyword support -->
		<zone name="rewriterule">
			<starts-with>
				<expression>^[\t ]*(RewriteRule)</expression>
				<capture number="1" name="keyword.directive"/>
			</starts-with>
			<ends-with>
				<expression>$</expression>
			</ends-with>
			<subzones>
				<include collection="line-continue" />
				<zone name="pattern">
					<starts-with>
						<expression>[ \t]+(!)?</expression>
						<capture number="1" name="regex.operator.not"/>
					</starts-with>
					<ends-with>
						<expression>[ \t]+(?!\[|$)</expression>
					</ends-with>
					<subzones>
						<include collection="variables" />
						<include syntax="language-root.regex" />
					</subzones>
				</zone>
				<zone name="substitution">
					<starts-with>
						<expression>(?=[^\[\s])</expression>
					</starts-with>
					<ends-with>
						<expression>([ \t]+(?=\[|$))|[ \t]*$</expression>
					</ends-with>
					<subzones>
						<include collection="variables" />
						<include syntax="regex.replace" />
					</subzones>
				</zone>
				<zone name="flags">
					<expression>\[[a-zA-Z0-9, =]+\]</expression>
				</zone>
			</subzones>
		</zone>
		
		<zone name="rewritecond">
			<starts-with>
				<expression>^[\t ]*(RewriteCond)</expression>
				<capture number="1" name="keyword.directive"/>
			</starts-with>
			<ends-with>
				<expression>$</expression>
			</ends-with>
			<subzones>
				<include collection="line-continue" />
				<zone name="teststring">
					<starts-with>
						<expression>[ \t]+</expression>
					</starts-with>
					<ends-with>
						<expression>[ \t]+(?!\[|$)</expression>
					</ends-with>
					<subzones>
						<include collection="variables" />
						<include syntax="regex.replace" />
					</subzones>
				</zone>
				<zone name="pattern">
					<starts-with>
						<expression>(!)|(?=[^\[\s])</expression>
						<capture number="1" name="regex.operator.not"/>
					</starts-with>
					<ends-with>
						<expression>([ \t]+(?=\[|$))|[ \t]*$</expression>
					</ends-with>
					<subzones>
						<include collection="variables" />
						<include syntax="language-root.regex" />
					</subzones>
				</zone>
				<zone name="flags">
					<expression>\[[a-zA-Z0-9, =]+\]</expression>
				</zone>
			</subzones>
		</zone>
		
		<zone name="mod_alias">
			<starts-with>
				<expression>^[\t ]*((?:(?:Script)?Alias|Redirect)Match)</expression>
				<capture number="1" name="keyword.directive"/>
			</starts-with>
			<ends-with>
				<expression>$</expression>
			</ends-with>
			<subzones>
				<include collection="line-continue" />
				<zone name="status">
					<expression>[ \t]+(?:(?:permanent|temp|seeother|gone)|(3[0-9]{2}))\b</expression>
					<capture number="1" name="constant.numeric.integer"/>
				</zone>
				<zone name="pattern">
					<starts-with>
						<expression>[ \t]+</expression>
					</starts-with>
					<ends-with>
						<expression>[ \t]+(?!$)</expression>
					</ends-with>
					<subzones>
						<include collection="variables" />
						<include syntax="language-root.regex" />
					</subzones>
				</zone>
				<zone name="substitution">
					<starts-with>
						<expression>(?!\s)</expression>
					</starts-with>
					<ends-with>
						<expression>[ \t]*$</expression>
					</ends-with>
					<subzones>
						<include collection="variables" />
						<include syntax="regex.replace" />
					</subzones>
				</zone>
			</subzones>
		</zone>
		
		<!-- Generic keyword and number support -->
		<zone>
			<expression>^[\t ]*([A-Z]\w*)|((?&lt;=\s)(?:0(?:x|X)[0-9a-fA-F]+|(?:(?:(?:[0-9]+)?\.[0-9]+(?:[eE]-?[0-9]+)?)|(?:[0-9]+[eE]-?[0-9]+))|[0-9]+)(?=\s|$))</expression>
			<capture number="1" name="keyword.directive"/>
			<capture number="2" name="constant.numeric"/>
		</zone>
		
		<include collection="variables" />
	</zones>
	
	<library>
		<collection name="line-continue">
			<!-- This results in a worthless anonymous zone (and duplicates effort for backslash line continuation zones) but is necessary in order to harvest the $ that does not end the main zone -->
			<zone>
				<starts-with>
					<expression>(\\)$</expression>
					<capture number="1" name="punctuation.continuation.backslash"/>
				</starts-with>
				<ends-with>
					<expression>^\s*</expression>
				</ends-with>
			</zone>
		</collection>
		
		<!--Strings-->
		<collection name="strings">
			<zone name="string.quoted.single">
				<starts-with>
					<expression>'</expression>
					<capture number="0" name="punctuation.definition.begin"/>
				</starts-with>
				<ends-with>
					<expression>'</expression>
					<capture number="0" name="punctuation.definition.end"/>
				</ends-with>
				<subzones>
					<zone name="constant.character.escape">
						<expression>(\\)('|\\)</expression>
						<capture number="1" name="punctuation.escape.backslash"/>
					</zone>
				</subzones>
			</zone>
			<zone name="string.quoted.double">
				<starts-with>
					<expression>"</expression>
					<capture number="0" name="punctuation.definition.begin"/>
				</starts-with>
				<ends-with>
					<expression>"</expression>
					<capture number="0" name="punctuation.definition.end"/>
				</ends-with>
				<subzones>
					<zone name="constant.character.escape">
						<expression>(\\)("|\\)</expression>
						<capture number="1" name="punctuation.escape.backslash"/>
					</zone>
				</subzones>
			</zone>
		</collection>
		
		<!--Variables-->
		<collection name="variables">
			<zone name="variable.environment">
				<expression>(\$\{)(\w+)(\})</expression>
				<capture number="1" name="punctuation.definition.begin"/>
				<capture number="2" name="name"/>
				<capture number="3" name="punctuation.definition.end"/>
			</zone>
			<zone name="variable.server">
				<expression>(%\{)(\w+)(\})</expression>
				<capture number="1" name="punctuation.definition.begin"/>
				<capture number="2" name="name"/>
				<capture number="3" name="punctuation.definition.end"/>
			</zone>
		</collection>
	</library>
</syntax>