<?xml version="1.0" encoding="UTF-8"?>
<!--
Unsupported:
- Arbitrarily nested elements
  * Any block element (other than lists) in nested lists
  * Any block element (other than blockquotes) in a nested blockquote
- HTML axing for block-level tags that are not alone on a line
- Hard wrap formatting in various areas (lists, mainly)
- Probably lots of outlying scenarios that parse fine but do not use good form
-->
<syntax name="language-root.markdown">
	<zones>
		<include collection="comments"/>
		
		<!-- Multi-line HTML block -->
		<!--
		This is hacktastic, but I can't figure out any other way to discourage the Markdown syntax within HTML blocks.
		
		Main downsides:
		* Duplicated syntax zones, so have to update this if we ever change HTML tag zones
		* Dies when nesting the same tag multiple times (like if you have nested divs, and the inner one isn't indented)
		-->
		<zone name="embedded.language-root.html">
			<starts-with>
				<expression>^(&lt;)(?!(?:(?:https?|ftp|dict|mailto):|[-.\w\u80-\uFF]+@)|base|basefont|img|br|link|meta|hr|input|command|col|wbr|source|track)([a-zA-Z0-9:]+)([^>]*?)(>)$</expression>
				<capture number="0" name="tag.open.other.html"/>
				<capture number="1" name="punctuation.definition.begin"/>
				<capture number="2" name="entity.name"/>
				<capture number="3">
					<subzones>
						<include syntax="language-root.html" collection="tag-attributes"/>
					</subzones>
				</capture>
				<capture number="4" name="punctuation.definition.end"/>
			</starts-with>
			<ends-with>
				<expression>^(&lt;/)(\2)(>)$</expression>
				<capture number="0" name="tag.close.other.html"/>
				<capture number="1" name="punctuation.definition.begin"/>
				<capture number="2" name="entity.name"/>
				<capture number="3" name="punctuation.definition.end"/>
			</ends-with>
			<subzones>
				<include syntax="language-root.html" collection="tags"/>
				<include syntax="language-root.html" collection="entities"/>
			</subzones>
		</zone>
		
		<!-- Headers -->
		<zone name="punctuation.definition.setext">
			<expression>^(?:={4,})[ \t]*$</expression>
			<rewind-and-replace line-starts="-1">
				<zone name="header.setext.name.h1">
					<expression>^\S.*$</expression>
					<subzones>
						<include collection="inline-styles"/>
					</subzones>
				</zone>
			</rewind-and-replace>
		</zone>
		<zone name="punctuation.definition.setext">
			<expression>^(?:-{4,})[ \t]*$</expression>
			<rewind-and-replace line-starts="-1">
				<zone name="header.setext.name.h2">
					<expression>^\S.*$</expression>
					<subzones>
						<include collection="inline-styles"/>
					</subzones>
				</zone>
			</rewind-and-replace>
		</zone>
		<zone>
			<expression>^((#{1,6})[ \t]*(.+?)[ \t]*(#*))$|^([ \t]{0,2}(?:(?:[ ]?\*[ ]?){3,}|(?:[ ]?\-[ ]?){3,}|(?:[ ]?\_[ ]?){3,})[ \t]*$[\n\r]*)</expression>
			<capture number="1" name="header.atx"/>
			<capture number="2" name="punctuation.definition.begin" behavior="text-to-parent-name" behavior-match="(#{6})|(#{5})|(#{4})|(#{3})|(#{2})|(#)" behavior-transform="(?1:h6:)(?2:h5:)(?3:h4:)(?4:h3:)(?5:h2:)(?6:h1:)" />
			<capture number="3" name="name">
				<subzones>
					<include collection="inline-styles"/>
				</subzones>
			</capture>
			<capture number="4" name="punctuation.definition.end"/>
			<!-- HR separator -->
			<capture number="5" name="separator"/>
		</zone>
		
		<!-- Block-level items -->
		<include collection="references"/>
		<include collection="lists"/>
		<include collection="code-blocks"/>
		<include collection="blockquotes"/>
		
		<include collection="inline-styles"/>
	</zones>
	
	<library>
		<!-- HTML Comments -->
		<collection name="comments">
			<zone name="comment.block">
				<starts-with>
					<expression>&lt;!--</expression>
					<capture number="0" name="punctuation.definition.begin"/>
				</starts-with>
				<ends-with>
					<expression>--></expression>
					<capture number="0" name="punctuation.definition.end"/>
				</ends-with>
			</zone>
		</collection>
		
		<collection name="character-escapes">
			<zone name="constant.character.escape">
				<expression>\\(\\|`|\*|_|\{|}|\[|]|\(|\)|>|#|\+|-|\.|!)</expression>
			</zone>
		</collection>
		
		<!-- Inline style collections -->
		<collection name="inline-styles">
			<include collection="comments"/>
			<include collection="code-inline"/>
			<include collection="character-escapes"/>
			
			<include collection="images"/>
			<include collection="links"/>
			
			<include collection="bold"/>
			<include collection="italic"/>
			
			<include collection="hardbreaks"/>
			
			<include syntax="language-root.html" collection="tags"/>
		</collection>
		
		<!-- Inline code -->
		<collection name="code-inline">
			<zone name="code.inline">
				<starts-with>
					<expression>(`+)</expression>
					<capture number="0" name="punctuation.definition.begin"/>
				</starts-with>
				<ends-with>
					<expression>\1</expression>
					<capture number="0" name="punctuation.definition.end"/>
				</ends-with>
			</zone>
		</collection>
		
		<!-- Images -->
		<collection name="images">
			<zone>
				<expression>((!\[).*?(\])(\()(.+?)(?:\s+((")(?:\\"|.)+?(")|(')(?:\\'|.)+?(')))?(\)))|((!\[).*?(\])(\[)(.+?)(\]))</expression>
				<capture number="1" name="image.inline"/>
				<capture number="2" name="punctuation.brace.square.open"/>
				<capture number="3" name="punctuation.brace.square.close"/>
				<capture number="4" name="punctuation.brace.round.open"/>
				<capture number="5" name="constant.url"/>
				<capture number="6" name="string.quoted"/>
				<capture number="7" name="punctuation.definition.begin"/>
				<capture number="8" name="punctuation.definition.end"/>
				<!-- Single quoted string -->
				<capture number="9" name="punctuation.definition.begin"/>
				<capture number="10" name="punctuation.definition.end"/>
				<capture number="11" name="punctuation.brace.round.close"/>
				<!-- Image by reference -->
				<capture number="12" name="image"/>
				<capture number="13" name="punctuation.brace.square.open"/>
				<capture number="14" name="punctuation.brace.square.close"/>
				<capture number="15" name="punctuation.brace.square.open"/>
				<capture number="16" name="keyword.reference"/>
				<capture number="17" name="punctuation.brace.square.close"/>
			</zone>
		</collection>
		
		<!-- Links -->
		<collection name="links">
			<!-- FIXME: this is not ideal logic, because it excludes links that have square braces in them. However, without this stipulation having two links in a row (first reference, second inline) will cause the first to greedily gobble through to the second. Swapping the order doesn't fix things, because then the opposite ordering behaves greedily -->
			<zone>
				<expression>((\[)([^\]]+?)(\]) ?(\()([^\s]+?|&lt;!--.*?-->\S*?)(?:\s+((")(?:\\"|.)+?(")|(')(?:\\'|.)+?(')))?(\)))|((\[)([^\]]+?)(\]) ?(\[)(.*?)(\]))|((&lt;)(?:(?:https?|ftp|dict):[^">\s]+)(>))|((&lt;)(?:mailto:)?(?:[-.\w\u80-\uFF]+@[-a-z0-9\u80-\uFF]+(?:\.[-a-z0-9\u80-\uFF]+)*\.[a-z]+)(>))</expression>
				<!-- [Linked](http://somewhere.com "My title") -->
				<capture number="1" name="link.inline"/>
				<capture number="2" name="punctuation.brace.square.open"/>
				<capture number="3" name="text">
					<subzones>
						<include collection="bold"/>
						<include collection="italic"/>
					</subzones>
				</capture>
				<capture number="4" name="punctuation.brace.square.close"/>
				<capture number="5" name="punctuation.brace.round.open"/>
				<capture number="6" name="constant.url">
					<subzones>
						<include collection="comments"/>
					</subzones>
				</capture>
				<capture number="7" name="string.quoted"/>
				<capture number="8" name="punctuation.definition.begin"/>
				<capture number="9" name="punctuation.definition.end"/>
				<!-- Single-quoted titles -->
				<capture number="10" name="punctuation.definition.begin"/>
				<capture number="11" name="punctuation.definition.end"/>
				<capture number="12" name="punctuation.brace.round.close"/>
				<!-- [Linked][reference] -->
				<capture number="13" name="link"/>
				<capture number="14" name="punctuation.brace.square.open"/>
				<capture number="15" name="text">
					<subzones>
						<include collection="bold"/>
						<include collection="italic"/>
					</subzones>
				</capture>
				<capture number="16" name="punctuation.brace.square.close"/>
				<capture number="17" name="punctuation.brace.square.open"/>
				<capture number="18" name="keyword.reference"/>
				<capture number="19" name="punctuation.brace.square.close"/>
				<!-- Autolinks -->
				<capture number="20" name="constant.url.autolink"/>
				<capture number="21" name="punctuation.definition.begin"/>
				<capture number="22" name="punctuation.definition.end"/>
				<!-- Email autolink -->
				<capture number="23" name="constant.url.autolink.email"/>
				<capture number="24" name="punctuation.definition.begin"/>
				<capture number="25" name="punctuation.definition.end"/>
			</zone>
		</collection>
		
		<!-- Formatting styles -->
		<collection name="bold">
			<zone name="bold">
				<starts-with>
					<!-- Actual regex for Markdown just uses \S, but this fails for us because Markdown checks for balanced delimiters and we can't. Instead, this regex looks for something other than sentence-terminating punctuation or spaces (otherwise using asterisks as footnote markers or similar could fail badly) -->
					<expression>(\*\*|__)(?=[^\s.,!:;?])</expression>
					<capture number="1" name="punctuation.definition.begin"/>
				</starts-with>
				<ends-with>
					<expression>\1</expression>
					<capture number="0" name="punctuation.definition.end"/>
				</ends-with>
				<subzones>
					<include collection="comments"/>
					<include collection="code-inline"/>
					<include collection="character-escapes"/>
					<include collection="italic"/>
					<include collection="links"/>
				</subzones>
			</zone>
		</collection>
		
		<collection name="italic">
			<zone name="italic">
				<starts-with>
					<expression>(\*|_)(?=[^\s.,!:;?])</expression>
					<capture number="1" name="punctuation.definition.begin"/>
				</starts-with>
				<ends-with>
					<expression>\1</expression>
					<capture number="0" name="punctuation.definition.end"/>
				</ends-with>
				<subzones>
					<include collection="comments"/>
					<include collection="code-inline"/>
					<include collection="character-escapes"/>
					<include collection="bold"/>
					<include collection="links"/>
				</subzones>
			</zone>
		</collection>
		
		<collection name="hardbreaks">
			<zone>
				<expression>(?&lt;=\S)( {2,})$[\r\n]+</expression>
				<capture number="1" name="hard-break.whitespace"/>
			</zone>
		</collection>
		
		<!-- Link and image references -->
		<collection name="references">
			<zone name="link.definition">
				<starts-with>
					<expression>^ {0,3}(\[)(.+?)(\]) ?(:)</expression>
					<capture number="1" name="punctuation.brace.square.open"/>
					<capture number="2" name="keyword.reference"/>
					<capture number="3" name="punctuation.brace.square.close"/>
					<capture number="4" name="punctuation.colon"/>
				</starts-with>
				<ends-with>
					<expression>(?=^\s*$)|(?=^\s*\[)</expression>
				</ends-with>
				<subzones>
					<zone>
						<expression>((")(?:\\"|.)+?(")|(')(?:\\'|.)+?(')|(\()(?:\\\)|.)+?(\)))\s*$|(\S+)</expression>
						<capture number="1" name="string.quoted"/>
						<capture number="2" name="punctuation.definition.begin"/>
						<capture number="3" name="punctuation.definition.end"/>
						<!-- Single quoted -->
						<capture number="4" name="punctuation.definition.begin"/>
						<capture number="5" name="punctuation.definition.end"/>
						<!-- In parentheses -->
						<capture number="6" name="punctuation.definition.begin"/>
						<capture number="7" name="punctuation.definition.end"/>
						<!-- Arbitrary URL -->
						<capture number="8" name="constant.url"/>
					</zone>
				</subzones>
			</zone>
		</collection>
		
		<!-- Lists -->
		<collection name="lists">
			<!--
			This method of list detection has the following downsides:
			
			* List elements that continue flush with the next line are cut off after the first line: `- My continuing\nparagraph` dies after the first line. Hard breaks are almost impossible for us to detect accurately without eating up way too much text in some situations, and usually break the list item after the paragraph anyway, so this seems like a decent trade-off.
			* Support for nested blockquotes and code in lists is ignored after the first level of lists. We have no way to track what level of indent we are on without providing unique zones for every level of nested list, and this is an edge case anyway.
			-->
			<zone name="list.element.unordered">
				<starts-with>
					<expression>^[ ]{0,3}([*+-])[ \t]</expression>
					<capture number="1" name="punctuation.definition.begin"/>
				</starts-with>
				<ends-with>
					<expression>^$|^(?=[ ]{0,3}(?:[*+-]|\d+\.)[ \t])|^(?=\S)</expression>
				</ends-with>
				<subzones>
					<include collection="list-children"/>
				</subzones>
			</zone>
			
			<zone name="list.element.ordered">
				<starts-with>
					<expression>^[ ]{0,3}(\d+\.)[ \t]</expression>
					<capture number="1" name="punctuation.definition.begin"/>
				</starts-with>
				<ends-with>
					<expression>^$|^(?=[ ]{0,3}(?:[*+-]|\d+\.)[ \t])|^(?=\S)</expression>
				</ends-with>
				<subzones>
					<include collection="list-children"/>
				</subzones>
			</zone>
		</collection>
		
		<collection name="list-children">
			<include collection="inline-styles"/>
			<include collection="nested-lists"/>
			<include collection="nested-code"/>
			<include collection="nested-blockquotes"/>
		</collection>
		
		<collection name="nested-lists">
			<zone name="list.element.unordered">
				<starts-with>
					<expression>^(\t+|(?:[ ]{4})+)[ ]{0,3}([*+-])[ \t]</expression>
					<capture number="2" name="punctuation.definition.begin"/>
				</starts-with>
				<ends-with>
					<expression>^(?!\1)|^(?=\s*(?:[*+-]|\d+\.)[ \t])</expression>
				</ends-with>
				<subzones>
					<include collection="inline-styles"/>
				</subzones>
			</zone>
			
			<zone name="list.element.ordered">
				<starts-with>
					<expression>^(\t+|(?:[ ]{4})+)[ ]{0,3}(\d+\.)[ \t]</expression>
					<capture number="2" name="punctuation.definition.begin"/>
				</starts-with>
				<ends-with>
					<expression>^(?!\1)|^(?=\s*(?:[*+-]|\d+\.)[ \t])</expression>
				</ends-with>
				<subzones>
					<include collection="inline-styles"/>
				</subzones>
			</zone>
		</collection>
		
		<!-- Code blocks -->
		<collection name="code-blocks">
			<zone name="code.block">
				<starts-with>
					<expression>^(\t+|(?: {4})+)\S</expression>
				</starts-with>
				<ends-with>
					<expression>^(?!\1)</expression>
				</ends-with>
			</zone>
		</collection>
		
		<collection name="nested-code">
			<zone name="code.block">
				<starts-with>
					<expression>^(\t{2,}|(?: {4}){2,})\S</expression>
				</starts-with>
				<ends-with>
					<expression>^(?!\1)</expression>
				</ends-with>
			</zone>
		</collection>
		
		<!-- Block quotes -->
		<collection name="blockquotes">
			<zone name="blockquote.element">
				<starts-with>
					<expression>^(?=>)</expression>
				</starts-with>
				<ends-with>
					<expression>^\s*$</expression>
				</ends-with>
				<subzones>
					<zone>
						<expression>^((?:> ?)*>) ?</expression>
						<capture number="1" name="punctuation.definition"/>
					</zone>
					<include collection="quoted-elements"/>
					<include collection="inline-styles"/>
				</subzones>
			</zone>
		</collection>
		
		<collection name="nested-blockquotes">
			<zone name="blockquote.element">
				<starts-with>
					<expression>^(\t| {4})((?:> ?)*>)</expression>
					<capture number="2" name="punctuation.definition"/>
				</starts-with>
				<ends-with>
					<expression>^(?!\1)</expression>
				</ends-with>
				<subzones>
					<zone>
						<expression>^(?:\t| {4})((?:> ?)*>)</expression>
						<capture number="1" name="punctuation.definition"/>
					</zone>
					<include collection="inline-styles"/>
				</subzones>
			</zone>
		</collection>
		
		<collection name="quoted-elements">
			<!-- Quoted headers -->
			<zone name="punctuation.definition.setext">
				<expression>(?&lt;=> )(?:={4,}|-{4,})[ \t]*$</expression>
				<rewind-and-replace line-starts="-1">
					<zone name="header.setext.name">
						<expression>(?&lt;=> )\S.*$</expression>
					</zone>
				</rewind-and-replace>
			</zone>
			<zone name="header.atx">
				<expression>(?&lt;=> )(?:((\#{1,6})[ \t]*(.+?)[ \t]*(\#*))$|([ \t]{0,2}(?:(?:[ ]?\*[ ]?){3,}|(?:[ ]?\-[ ]?){3,}|(?:[ ]?\_[ ]?){3,})[ \t]*$[\n\r]*))</expression>
				<!-- ATX headers -->
				<capture number="1" name="header.atx"/>
				<capture number="2" name="punctuation.definition.begin"/>
				<capture number="3" name="name"/>
				<capture number="4" name="punctuation.definition.end"/>
				<!-- HR separators -->
				<capture number="5" name="separator"/>
			</zone>
			
			<!-- Quoted Lists -->
			<zone name="list.element.unordered">
				<starts-with>
					<expression>(?&lt;=> )[ ]{0,3}([*+-])[ \t]</expression>
					<capture number="1" name="punctuation.definition.begin"/>
				</starts-with>
				<ends-with>
					<expression>^(?!>)|^(?=(?:(?:> ?)*> )$)|^(?=(?:(?:> ?)*> )[ ]{0,3}(?:[*+-]|\d+\.)[ \t])</expression>
				</ends-with>
				<subzones>
					<include collection="inline-styles"/>
				</subzones>
			</zone>
			<zone name="list.element.ordered">
				<starts-with>
					<expression>(?&lt;=> )[ ]{0,3}(\d+\.)[ \t]</expression>
					<capture number="1" name="punctuation.definition.begin"/>
				</starts-with>
				<ends-with>
					<expression>^(?!>)|^(?=(?:(?:> ?)*> )$)|^(?=(?:(?:> ?)*> )[ ]{0,3}(?:[*+-]|\d+\.)[ \t])</expression>
				</ends-with>
				<subzones>
					<include collection="inline-styles"/>
				</subzones>
			</zone>
			
			<!-- Quoted Code Blocks -->
			<zone name="code.block">
				<starts-with>
					<expression>(?&lt;=> )(\t+|(?: {4})+)\S</expression>
				</starts-with>
				<ends-with>
					<expression>^(?!(?:(?:> ?)*> )\1)</expression>
				</ends-with>
				<subzones>
					<zone>
						<expression>^((?:> ?)*>) ?</expression>
						<capture number="1" name="punctuation.definition"/>
					</zone>
				</subzones>
			</zone>
		</collection>
	</library>
</syntax>