name: "Roff"
scopeName: "text.roff"
fileTypes: [
	"1", "1b", "1c", "1has", "1in", "1m", "1s", "1t", "1x", "1.in"
	"2"
	"3", "3avl", "3bsm", "3c", "3in", "3m", "3pm", "3qt", "3x"
	"4"
	"5"
	"6"
	"7", "7d", "7fs", "7i", "7ipp", "7m", "7p", "7.in"
	"8"
	"9", "9e", "9f", "9p", "9s"
	"eqnrc"
	"groff"
	"man", "man.template"
	"mandoc"
	"mdoc", "mdoc.template"
	"me"
	"mmn", "mmt"
	"ms"
	"mom"
	"n", "nr"
	"nroff"
	"roff", "rof"
	"tmac", "tmac-u", "tmac.in"
	"toc.entries"
	"tr"
	"troff"
	"troffrc", "troffrc-end"
]
firstLineMatch: """(?x)

	# .\" Non-empty comment
	(?:^|\\R)\\.\\\\"[ \\t]\\S
	|

	# Manual page with .TH, .Dd or .Dt macro on first line
	^\\.(?:TH|Dd|Dt)[ \\t]+\\S
	|
	
	# $Mdocdate$ keyword in comment or .Dd macro
	(?:^|\\s)"?\\$Mdocdate(?::.*?)?\\$
	|
	
	# Preprocessor line
	# See: https://www.gnu.org/software/groff/manual/html_node/Preprocessors-in-man-pages.html
	^'\\\\\"\\x20[tre]+(?=\\s|$)
	|
	
	# “Aliased” manual page
	^\\.so[ \\t]+man(\\w+)/.+\\.\\1(?=\\s|$)
	|
	
	# DWB copyright banner
	(?:^|\\R)(?:'+\\t?|\\.\\t)\\\\"\\s
	|
	
	# Modeline
	(?i:
		# Emacs
		-\\*-(?:\\s*(?=[^:;\\s]+\\s*-\\*-)|(?:.*?[;\\s]|(?<=-\\*-))mode\\s*:\\s*)
			[gnt]?roff
		(?=[\\s;]|(?<![-*])-\\*-).*?-\\*-
		
		|
		
		# Vim
		(?:(?:\\s|^)vi(?:m[<=>]?\\d+|m)?|\\sex)(?=:(?=\\s*set?\\s[^\\r\\n:]+:)|:(?!\\s* set?\\s))(?:(?:\\s|\\s*:\\s*)\\w*(?:\\s*=(?:[^\\r\\n\\\\\\s]|\\\\.)*)?)*[\\s:](?:filetype|ft|syntax)\\s*=
			[gnt]?roff
		(?=\\s|:|$)
	)
"""
limitLineLength: no
patterns: [include: "#main"]
injections:
	"L:text.roff":
		patterns: [include: "#c0"]
	
	"L:meta.device-control.roff,
	 L:meta.function.request.transparent-output & source.embedded.ditroff":
		patterns: [
			{match: "[.']"}
			{include: "#escapes-copymode"}
		]


repository:
	
	# Common patterns
	main:
		patterns: [
			{include: "#preprocessors"}
			{include: "#escapes"}
			{include: "#requests"}
			{include: "#macros"}
		]
	
	
	# Legal ASCII control characters
	c0:
		patterns: [
			{match: "\\x02", name: "punctuation.c0.ctrl-char.start-of-text.roff"}
			{match: "\\x03", name: "punctuation.c0.ctrl-char.end-of-text.roff"}
			{match: "\\x04", name: "punctuation.c0.ctrl-char.end-of-transmission.roff"}
			{match: "\\x05", name: "punctuation.c0.ctrl-char.enquiry.roff"}
			{match: "\\x06", name: "punctuation.c0.ctrl-char.acknowledge.roff"}
			{match: "\\a",   name: "punctuation.c0.ctrl-char.alarm.bell.roff"}
			{match: "\\f",   name: "punctuation.whitespace.form-feed.roff"}
			{match: "\\x7F", name: "punctuation.c0.ctrl-char.delete.roff"}
		]
	
	
	# Control line parameters
	params:
		patterns: [
			{include: "#escapes"}
			{include: "#string"}
			{include: "#number"}
			{include: "#generic-parameter"}
		]
	
	
	# Numeric literal
	number:
		name: "constant.numeric.roff"
		match: "(?!\\d+(?:/|[cfimnPpsuvz]\\w))(\\|)?(?:(?<!\\w)[-+])?(?:\\d+(?:\\.\\d*)?|\\.\\d+|(?<=[-+])\\.)([cfimnPpsuvz])?"
		captures:
			1: name: "keyword.operator.absolute.roff"
			2: name: "keyword.other.unit.roff"
	
	
	# "Double-quoted string"
	string:
		patterns: [{
			name: "string.quoted.double.empty.roff"
			match: '(?<=(?<=[^\\\\]|^)\\s|^)(")(")(?=\\s|$)'
			captures:
				1: name: "punctuation.definition.string.begin.roff"
				2: name: "punctuation.definition.string.end.roff"
		},{
			name: "string.quoted.double.roff"
			begin: '(?<=(?<=[^\\\\]|^)\\s|^)"(?!")'
			end:   '(?<!")"(?!")|(?<!\\\\)$|(?=\\\\E?")'
			beginCaptures: 0: name: "punctuation.definition.string.begin.roff"
			endCaptures:   0: name: "punctuation.definition.string.end.roff"
			patterns: [include: "#string-escapes"]
		}, include: "#c0"]
	
	
	# Escape sequences to match inside double-quoted strings
	"string-escapes":
		patterns: [
			{match: '""', name: "constant.character.escape.quote.double.roff"}
			{include: "#escapes"}
		]
	
	
	# Highlighting for macro arguments that don't match anything else
	"generic-parameter":
		name: "variable.parameter.roff"
		match: "[^\\s\\\\]+"
		captures:
			0: patterns: [include: "#c0"]
	
	
	# List of arguments passed to a request or macro
	"param-group":
		name: "function-call.arguments.roff"
		begin: "\\G|^"
		end:   "\\Z|$"
		patterns: [include: "#params"]
	
	
	# Bracket-delimited long-name (GNU)
	"long-name":
		patterns: [{
			name: "variable.parameter.other.roff"
			begin: "\\G\\s*"
			end:   "(?=\\]|\\s)"
			patterns: [include: "#escapes"]
		}
		{include: "#escapes"}
		{include: "#string"}
		{include: "#number"}]
	
	
	# Variant of “#param-group” used inside \[long-names]
	"long-params":
		patterns: [
			{include: "#escapes"}
			{include: "#string"}
			{include: "#number"}
			{include: "#arithmetic"}
			
			name: "variable.parameter.roff"
			match: "[^\\\\\\s\\]]+"
			captures:
				0: patterns: [include: "#c0"]
		]
	
	
	# Group of strings delimited with an arbitrary character
	"3-part-title":
		name: "string.3-part.other.roff"
		match: '\\G[ \\t]*(.)((?:(?!\\1).)*)(\\1)((?:(?!\\1).)*)(\\1)((?:(?!\\1).)*)(\\1)'
		captures:
			1: name: "punctuation.definition.string.begin.roff", patterns: [include: "#c0"]
			2: name: "entity.string.left.roff",                  patterns: [include: "#escapes"]
			3: name: "punctuation.definition.string.begin.roff", patterns: [include: "#c0"]
			4: name: "entity.string.centre.roff",                patterns: [include: "#escapes"]
			5: name: "punctuation.definition.string.end.roff",   patterns: [include: "#c0"]
			6: name: "entity.string.right.roff",                 patterns: [include: "#escapes"]
			7: name: "punctuation.definition.string.end.roff",   patterns: [include: "#c0"]
	
	
	
	# Requests
	requests:
		patterns:[{
			
			# GNU extensions
			name: "meta.function.request.$2.gnu.roff"
			begin: """(?x) ^([.'])[ \\t]*
				(aln|als|asciify|backtrace|blm|boxa|box|brp|cflags|chop|close|composite|color
				|cp|devicem|device|do|ecs|ecr|evc|fam|fchar|fcolor|fschar|fspecial|ftr|fzoom
				|gcolor|hcode|hla|hlm|hpfa|hpfcode|hpf|hym|hys|itc|kern|length|linetabs|lsm
				|mso|nop|nroff|opena|open|pev|pnr|psbb|pso|ptr|pvs|rchar|rfschar|rj
				|rnn|schar|shc|shift|sizes|special|spreadwarn|stringdown|stringup|sty
				|substring|tkf|tm1|tmc|trf|trin|trnt|troff|unformat|vpt|warnscale|warn
				|writec|writem|write)
				(?=\\s|\\\\E?["#])"""
			end: "(?<!\\\\)(?=\\R|$)|(?=\\\\E?\")"
			beginCaptures:
				1: name: "punctuation.definition.request.roff"
				2: name: "entity.function.name.roff"
			patterns: [include: "#param-group"]
		},{
			
			# .class: Assign a name to a range of characters (GNU)
			name: "meta.function.request.assign-class.gnu.roff"
			begin: "^([.'])[ \\t]*(class)[ \\t]+(\\S+)"
			end:   "(?<!\\\\)(?=$)|(?=\\\\E?\")"
			beginCaptures:
				1: name: "punctuation.definition.request.roff"
				2: name: "entity.function.name.roff"
				3: name: "variable.parameter.roff", patterns: [include: "#escapes"]
			patterns: [{
				name: "string.unquoted.character-range.roff"
				match: "([^\\s\\\\]+)(-)([^\\s\\\\]+)"
				captures:
					2: name: "punctuation.separator.dash.roff"
					1: patterns: [include: "#c0"]
					3: patterns: [include: "#c0"]
			}, include: "#params"]
		},{
			
			# .char: Define character or glyph (GNU)
			name: "meta.function.request.$2.gnu.roff"
			begin: "^([.'])[ \\t]*(char)[ \\t]*(\\S+)?[ \\t]*(.*)(?=$|\\\\E?[\"#])"
			end:   "(?<!\\\\)(?=$)|(?=\\\\E?[\"#])"
			patterns: [include: "$self"]
			beginCaptures:
				1: name: "punctuation.definition.request.roff"
				2: name: "storage.type.var.roff"
				3: name: "variable.parameter.roff", patterns: [include: "#escapes"]
				4: patterns: [include: "#param-group"]
		},{
			
			# .defcolor: Define colour (GNU)
			name: "meta.function.request.define-colour.gnu.roff"
			begin: "^([.'])[ \\t]*(defcolor)(?=\\s)[ \\t]*((?:[^\\s\\\\]|\\\\(?!E?[\"#]).)*)[ \\t]*(rgb|cmyk?|gr[ae]y)?"
			end:   "(?<!\\\\)(?=$)|(?=\\\\E?[\"#])"
			beginCaptures:
				1: name: "punctuation.definition.request.roff"
				2: name: "storage.type.var.roff"
				3: name: "string.other.colour-name.roff", patterns: [include: "#escapes"]
				4: name: "constant.language.colour-scheme.roff"
			patterns: [{
				
				# Hexadecimal colour
				name: "constant.other.colour.hex.roff"
				match: "(\#{1,2})[A-Fa-f0-9]+"
				captures: 1: name: "punctuation.definition.colour.roff"
				
			}, include: "#params"]
		},{
			
			# .output: Write directly to intermediate output (GNU)
			name: "meta.function.request.transparent-output.gnu.roff"
			begin: "^([.'])[ \\t]*(output)(?=\\s|\\\\E?[\"#])"
			end:   '(.*)(?<!\\\\)(?=$)|(?=\\\\E?")|(?=^(?!\\G))'
			beginCaptures:
				1: name: "punctuation.definition.request.roff"
				2: name: "entity.function.name.roff"
			endCaptures:
				0: name: "source.embedded.ditroff"
				1: patterns: [include: "source.ditroff"]
			contentName: "source.embedded.ditroff"
			patterns: [
				{include: "#continuous-newline"}
				{include: "source.ditroff"}
			]
		},{
			
			# Requests for controlling program flow (GNU)
			begin: "^([.'])[ \\t]*(break|continue|return)(?=\\s)"
			end:   "(?<!\\\\)(?=$)|(?=\\\\E?\")"
			patterns: [include: "#param-group"]
			beginCaptures:
				0: name: "meta.function.request.control.gnu.roff"
				1: name: "punctuation.definition.request.roff"
				2: name: "keyword.control.roff"
		},{
			
			# .tm/.ab: Print remainder of line to STDERR
			name: "meta.function.request.$2.roff"
			begin: "^([.'])[ \\t]*(ab|tm)(?=\\s|\\\\E?[\"#])"
			end:   "(?<!\\\\)(?=\\R|$)|(?=\\\\E?\")"
			beginCaptures:
				1: name: "punctuation.definition.request.roff"
				2: name: "entity.function.name.roff"
			patterns: [include: "#escapes-copymode"]
			contentName: "string.unquoted.roff"
			
		},{
			# Generic requests without formatting
			name: "meta.function.request.$2.roff"
			begin: """(?x) ^([.'])[ \\t]*
				(ab|ad|af|bd|bp|br|c2|cc|ce|cf|ch|cs|da|di|dt|ec|em|eo|ev
				|ex|fc|fi|fl|fp|ft|hc|hw|hy|in|it|lc|lg|lf|ll|ls|lt|mc|mk
				|na|ne|nf|nh|nm|nn|ns|nx|os|pc|pi|pl|pm|pn|po|ps|rd|rm|rn
				|rr|rs|rt|so|sp|ss|sv|sy|ta|tc|ti|tm|tr|uf|vs|wh)
				(?=\\s|\\d+\\s*$|\\\\E?["#])"""
			end: "(?<!\\\\)(?=\\R|$)|(?=\\\\E?\")"
			beginCaptures:
				1: name: "punctuation.definition.request.roff"
				2: name: "entity.function.name.roff"
			patterns: [include: "#param-group"]
			
		}
		{ include: "#conditionals" }
		{ include: "#definition"   }
		{ include: "#ignore"       }
		{ include: "#underlines"   }
		{
			# Register assignment
			name: "meta.function.request.$2.roff"
			begin: "^([.'])[ \\t]*(nr)[ \\t]*(?:(%|ct|dl|dn|dw|dy|ln|mo|nl|sb|st|yr)|(c\\.)|(\\${2}|\\.[$aAbcdfFhHijklLnopRTstuvVwxyz])|(\\.[CgmMOPUxyY])|(\\S+))?[ \\t]*(.*)$"
			end: "(?<!\\\\)$"
			beginCaptures:
				1: name: "punctuation.definition.request.roff"
				2: name: "storage.type.var.roff"
				3: name: "constant.language.predefined.register.roff"
				4: name: "constant.language.predefined.register.gnu.roff"
				5: name: "invalid.illegal.readonly.register.roff"
				6: name: "invalid.illegal.readonly.register.gnu.roff"
				7: name: "variable.parameter.roff", patterns: [include: "#escapes"]
				8: patterns: [{include: "#arithmetic"}, {include: "#param-group"}]
		},{
			
			# String definition
			name: "meta.function.request.$2.roff"
			begin: "^([.'])[ \\t]*([ad]s1?)[ \\t]+(((?:[^\\s\\\\]|\\\\(?!E?\").)+))?"
			end:   "(?<!\\\\)$"
			beginCaptures:
				1: name: "punctuation.definition.request.roff"
				2: name: "storage.type.var.roff"
				3: name: "variable.parameter.roff", patterns: [include: "#c0"]
				4: name: "entity.name.roff",        patterns: [include: "#escapes"]
			contentName: "string.unquoted.roff"
			patterns: [
				{include: "#escapes-clipped"}
				{include: "#escapes"}
			]
		},{
			
			# Three-part title
			name: "meta.function.request.$2.roff"
			begin: "^([.'])[ \\t]*(tl)(?=\\s)"
			end:   "(?<!\\\\)$|(?=\\\\E?\")"
			beginCaptures:
				1: name: "punctuation.definition.request.roff"
				2: name: "entity.function.name.roff"
			contentName: "function-call.arguments.roff"
			patterns: [
				{include: "#3-part-title"}
				{include: "#params"}
			]
		}]
	
	
	
	# Conditional input
	conditionals:
		patterns: [{
			
			# Conditional: If
			begin: """(?x)^
				([.'])         [ \\t]*  # 1: punctuation.definition.request.roff
				(ie|if|while)  [ \\t]*  # 2: keyword.control.roff
				(!)?                    # 3: keyword.operator.logical
				
				(?:
					# One-character built-in comparison name
					([notevh])       # 4: constant.language.builtin-comparison.$4.roff
					
					|
					
					# GNU extensions
					([cdFmrS])       # 5: constant.language.builtin-comparison.$5.gnu.roff
					
					# Name being validated
					[ \\t]*
					((?:[^ \\t\\\\]|\\\\(?!E?["#]).)+) # 6: Include “#escapes”
					
					|
					
					# Arithmetic
					(                # 7: meta.equation.roff
						
						# Starts with a bracket
						(\\()        # 8:  punctuation.definition.begin.roff
						(.*?)        # 9:  Include “#arithmetic”
						(\\))        # 10: punctuation.definition.end.roff
						
						# Anything else affixed to it
						(            # 11: Include “#arithmetic”
							(?:
								[^\\s\\(] | # Operators/numbers
								\\(.*?\\)   # More brackets
							)*
						)
						
						|
						
						# Doesn’t start with a bracket
						(?:
							# Starts with a long-form string/register
							(\\|?\\\\+E?[n*]\\(\\S{2}) # 12: Include “#escapes”
							|
							# Starts with a digit or backslash
							(?=\\d|\\\\)
						)
						([^\\s\\(]*) # 13: Sandwiched mathematical junk
						
						(?: # Possible embedded brackets
							(\\()    # 14: punctuation.definition.begin.roff
							(.*?)    # 15: Include “#arithmetic”
							(\\))    # 16: punctuation.definition.end.roff
						)?
						(?: # Possible trailing digits/operators
							[^\\s\\(]*?
							\\d+
						)?
						
						# Ends with a...
						(?<=
							# Digit
							\\d |
							
							# Unit suffix
							(?<=[\\d.])
							[A-Za-z] |
							
							# Closing bracket
							[\\)\\]] |
							
							# String/register: Long-form
							\\\\  [n*] \\( \\S{2} |
							\\\\E [n*] \\( \\S{2} |
							
							# String/register: Short-form
							\\\\  [n*] \\S |
							\\\\E [n*] \\S
						)
					)
					
					|
					
					# String/variable comparison
					([^\\d\\s\\\\])  # 17: punctuation.definition.string.begin.roff
					(                # 18: variable.parameter.operand.left.roff
						(.*?)        # 19: Include “#escapes”
					)
					(\\17)           # 20: punctuation.definition.string.roff
					(                # 21: variable.parameter.operand.right.roff
						(.*?)        # 22: Include “#escapes”
					)
					(\\17)           # 23: punctuation.definition.string.end.roff
					
					|
					
					# Anything not recognised
					(\\S)            # 24: meta.operand.single.roff
				)?
				
				(.*)                 # 25: Include “#conditional-innards”
			"""
			end: "$"
			beginCaptures:
				0:  name: "meta.function.request.$2.roff"
				1:  name: "punctuation.definition.request.roff"
				2:  name: "keyword.control.roff"
				3:  name: "keyword.operator.logical"
				4:  name: "constant.language.builtin-comparison.$4.roff"
				5:  name: "constant.language.builtin-comparison.$5.gnu.roff"
				6:  patterns: [include: "#escapes"]
				7:  name: "meta.equation.roff"
				8:  name: "punctuation.definition.begin.roff"
				9:  patterns: [include: "#arithmetic"]
				10: name: "punctuation.definition.end.roff"
				11: patterns: [include: "#arithmetic"]
				12: patterns: [include: "#escapes"]
				13: patterns: [include: "#arithmetic"]
				14: name: "punctuation.definition.begin.roff"
				15: patterns: [include: "#arithmetic"]
				16: name: "punctuation.definition.end.roff"
				17: name: "punctuation.definition.string.begin.roff", patterns: [include: "#escapes"]
				18: name: "variable.parameter.operand.left.roff"
				19: patterns: [include: "#escapes"]
				20: name: "punctuation.definition.string.roff"
				21: name: "variable.parameter.operand.right.roff"
				22: patterns: [include: "#escapes"]
				23: name: "punctuation.definition.string.end.roff", patterns: [include: "#escapes"]
				24: name: "meta.operand.single.roff"
				25: patterns: [include: "#conditional-innards"]
		},{
			
			# Conditional: Else
			begin: "^([.'])[ \\t]*(el)\\s*(.*)"
			end:   "$"
			beginCaptures:
				0: name: "meta.function.request.$2.roff"
				1: name: "punctuation.definition.request.roff"
				2: name: "keyword.control.roff"
				3: patterns: [include: "#conditional-innards"]
		}]
	
	"conditional-innards":
		patterns: [{
			begin: "^\\s*(\\\\E?\\{(?:\\\\E?(?=\\R|$))?)?\\s*(.*)"
			end:   "$"
			beginCaptures:
				1: name: "punctuation.section.conditional.begin.roff"
				2: patterns: [include: "$self"]
		}]
	
	
	
	# Basic arithmetic sequences
	arithmetic:
		patterns: [
			{include: "#escapes"}
			{
				name: "meta.brackets.roff"
				match: "(\\()(.*?)(\\))"
				captures:
					1: name: "punctuation.arithmetic.begin.roff"
					2: patterns: [include: "#arithmetic"]
					3: name: "punctuation.arithmetic.end.roff"
			}
			{include: "#number"}
			{match: "<\\?",        name: "keyword.operator.minimum.gnu.roff"}
			{match: ">\\?",        name: "keyword.operator.maximum.gnu.roff"}
			{match: "[-/+*%]",     name: "keyword.operator.arithmetic.roff"}
			{match: ":|&|[<=>]=?", name: "keyword.operator.logical.roff"}
			{match: "\\|",         name: "keyword.operator.absolute.roff"}
			{
				# Change default scaling indicator (GNU)
				name: "meta.scaling-indicator.gnu.roff"
				match: "(?<=^|\\()([cfimnPpsuvz])(;)"
				captures:
					1: name: "keyword.other.unit.roff"
					2: name: "punctuation.separator.semicolon.roff"
			}
		]
	
	

	# Macro definitions
	definition:
		patterns: [{
			
			# No terminator specified
			name: "meta.macro.definition.$2.roff"
			begin: "^([.'])[ \\t]*((dei?1?)|(ami?1?))\\s+(\\S+?)?\\s*(\\\\E?[\"#].*)?$"
			end:   "^(?:[ \\t]*\\x5C{2})?\\.[ \\t]*\\."
			beginCaptures:
				1: name: "punctuation.definition.request.roff"
				3: name: "storage.type.function.roff"
				4: name: "entity.name.function.roff"
				5: name: "variable.parameter.roff", patterns: [include: "#escapes"]
				6: patterns: [include: "#escapes"]
				7: patterns: [include: "#param-group"]
			endCaptures:
				0: name: "punctuation.definition.request.roff"
			patterns: [include: "$self"]
		},{
			
			# Terminator included
			name: "meta.macro.definition.with-terminator.$2.roff"
			begin: "^([.'])[ \\t]*((dei?1?)|(ami?1?))\\s+(\\S+)\\s*(\"[^\"]+\"?|\\S+?(?=\\s|\\\\E?[\"#]))?(.*)$"
			end:   "^(\\.)[ \\t]*((\\6)(?=$|\\s|\\\\(?:$|\")))"
			beginCaptures:
				1: name: "punctuation.definition.request.roff"
				3: name: "storage.type.function.roff"
				4: name: "entity.name.function.roff"
				5: name: "variable.parameter.roff",         patterns: [include: "#escapes"]
				6: name: "keyword.control.terminator.roff", patterns: [include: "#string"]
				7: patterns: [include: "#param-group"]
			endCaptures:
				1: name: "punctuation.definition.request.roff"
				2: name: "keyword.control.terminator.roff"
				3: patterns: [include: "#string"]
			patterns: [include: "$self"]
		}]
	
	
	# Ignored content
	ignore:
		patterns: [{
			
			# Terminator specified
			contentName: "comment.block.ignored-input.with-terminator.roff"
			begin: '^(?!.*?\\\\*})([.\'])[ \\t]*(ig)[ \\t]+(?!\\\\E?["#]|\\\\+\\$\\d+)(("[^"]+")|\\S+?(?=\\s|\\\\E?["#]))(.*)$'
			end:   "^([.'])[ \\t]*(\\3)(?=\\s|$|\\\\)|^(?=[.']?[ \\t]*\\\\*})"
			patterns: [include: "#register-expansion"]
			beginCaptures:
				1: name: "punctuation.definition.request.roff"
				2: name: "entity.function.name.roff"
				3: name: "keyword.control.terminator.roff", patterns: [include: "#escapes"]
				4: patterns: [include: "#string"]
				5: patterns: [include: "#params"]
			endCaptures:
				1: name: "punctuation.definition.request.roff"
				2: name: "keyword.control.terminator.roff", patterns: [include: "#string"]
		},{
			
			# No terminator given
			contentName: "comment.block.ignored-input.roff"
			begin: "^(?!.*?\\\\*})([.'])[ \\t]*(ig)(?=\\s|\\\\E?[\"#])(.*)$"
			end:   "^([.'])[ \\t]*\\.(?=\\s|\\\\E?[\"#])|^(?=[.']?[ \\t]*\\\\*})"
			patterns: [include: "#register-expansion"]
			beginCaptures:
				1: name: "punctuation.definition.request.roff"
				2: name: "entity.function.name.roff"
				3: patterns: [include: "#params"]
			endCaptures:
				0: name: "punctuation.definition.request.roff"
		}]
	

	# Underlined passages
	underlines:
		patterns: [{
			
			# .ul/.cu 0: Empty request/noop
			name: "meta.request.$2.roff"
			match: "^([.'])[ \\t]*(ul|cu)\\s*(0+)(?:(?!\\\\E?\")\\D)*(?=\\s|$)(.*)$"
			captures:
				1: name: "punctuation.definition.function.request.roff"
				2: name: "entity.function.name.roff"
				3: name: "constant.numeric.roff"
				4: patterns: [include: "#params"]
			
		}, {
			
			# Underline following line
			name: "meta.request.$2.roff"
			begin: "^([.'])[ \\t]*(ul|cu)(?=\\s|$|\\\\)(.*?)$\\R?"
			end:   "(?!\\G)(?<!\\\\)$"
			beginCaptures:
				1: name: "punctuation.definition.function.request.roff"
				2: name: "entity.function.name.roff"
				3: patterns: [include: "#params"]
			patterns: [{
				
				# Ignore control-lines
				begin: "(?:^|\\G)(?=[.']|\\\\E?!)(.*)$\\R?"
				end:   "(?!\\G)^"
				beginCaptures:
					1: patterns: [include: "$self"]
			}, {
				name: "string.other.link.roff"
				contentName: "markup.underline.roff"
				begin: "(?:^|\\G)(?![.'])"
				end:   "(?!\\G)(?<!\\\\)$"
			}]
		}]
	
	
	
	
	
	# Escape sequences
	escapes:
		patterns: [
			{include: "#escapes-copymode"}
			{include: "#escapes-full"}
		]
	
	
	# Register interpolation
	"register-expansion":
		patterns: [{
			
			# \n[xx] - Contents of number register "XX" (GNU)
			name: "constant.character.escape.function.expand-register.gnu.roff"
			begin: "(\\|)?((?:((\\\\)E)|((?:(?<=\\|)\\\\*?)?\\\\))n([-+])?(\\[))"
			end: "(\\])|(?<!\\\\)(?=$)"
			patterns: [include: "#long-name"]
			beginCaptures:
				1: name: "keyword.operator.absolute.roff"
				2: name: "entity.name.roff"
				3: name: "constant.character.escape.current-escape-char.gnu.roff"
				4: name: "punctuation.definition.escape.roff"
				5: name: "punctuation.definition.escape.roff"
				6: name: "keyword.operator.arithmetic.roff"
				7: name: "punctuation.section.begin.bracket.square.roff"
			endCaptures:
				1: name: "punctuation.section.end.bracket.square.roff"
		},{
			
			# \nX, \n(XX - Contents of number register "X" or "XX"
			name: "constant.character.escape.function.expand-register.roff"
			match: """(?x)
				
				# 1: keyword.operator.absolute.roff
				(\\|)?
				
				# 2: entity.name.roff
				(
					(?:
						# 3: constant.character.escape.current-escape-char.gnu.roff
						(
							# 4: punctuation.definition.escape.roff
							(\\\\)E
						)
						|
						# 5: punctuation.definition.escape.roff
						(
							(?:(?<=\\|)\\\\*?)?
							\\\\
						)
					)
					n
					([-+])?   # 6: keyword.operator.arithmetic.roff
					(\\()     # 7: punctuation.definition.brace.roff
				)
				
				# Name of register
				(?:
					# 8: constant.language.predefined.register.roff
					(ct|dl|dn|dw|dy|ln|mo|nl|sb|st|yr)
					|
					# 9: constant.language.predefined.register.gnu.roff
					(c\\.)
					|
					# 10: constant.language.predefined.register.readonly.roff
					(\\${2}  |  \\.[$aAbcdfFhHijklLnopRTstuvVwxyz])
					|
					# 11: constant.language.predefined.register.readonly.gnu.roff
					(\\.[CgmMOPUxyY])
					|
					# 12: variable.parameter.roff
					(\\S{2})
				)
				
				|
				
				# 13: keyword.operator.absolute.roff
				(\\|)?
				
				# 14: entity.name.roff
				(
					(?:
						# 15: constant.character.escape.current-escape-char.gnu.roff
						(
							# 16: punctuation.definition.escape.roff
							(\\\\)E
						)
						|
						# 17: punctuation.definition.escape.roff
						(
							(?:(?<=\\|)\\\\*?)?
							\\\\
						)
					)
					n
				)
				
				# 18: keyword.operator.arithmetic.roff
				([-+])?
				
				# Name of register
				(?:
					(%) |  # 19: constant.language.predefined.register.roff
					(\\S)  # 20: variable.parameter.roff
				)
			"""
			captures:
				1:  name: "keyword.operator.absolute.roff"
				2:  name: "entity.name.roff"
				3:  name: "constant.character.escape.current-escape-char.gnu.roff"
				4:  name: "punctuation.definition.escape.roff"
				5:  name: "punctuation.definition.escape.roff"
				6:  name: "keyword.operator.arithmetic.roff"
				7:  name: "punctuation.definition.brace.roff"
				8:  name: "constant.language.predefined.register.roff"
				9:  name: "constant.language.predefined.register.gnu.roff"
				10: name: "constant.language.predefined.register.readonly.roff"
				11: name: "constant.language.predefined.register.readonly.gnu.roff"
				12: name: "variable.parameter.roff", patterns: [include: "#c0"]
				13: name: "keyword.operator.absolute.roff"
				14: name: "entity.name.roff"
				15: name: "constant.character.escape.current-escape-char.gnu.roff"
				16: name: "punctuation.definition.escape.roff"
				17: name: "punctuation.definition.escape.roff"
				18: name: "keyword.operator.arithmetic.roff"
				19: name: "constant.language.predefined.register.roff"
				20: name: "variable.parameter.roff", patterns: [include: "#c0"]
		}]
	
	
	# Limited range of escape sequences permitted in copy-mode
	"escapes-copymode":
		patterns: [{
			
			# Backslashed escape sequences: \t -> \\t
			match: "(\\\\+?)(?=\\1\\S)"
			name: "punctuation.definition.concealed.escape.backslash.roff"
		},{
			
			# Comments
			name: "comment.line.roff"
			begin: "(?:^(\\.|'+)\\s*)?(\\\\E?\")"
			end: "$"
			beginCaptures:
				1: name: "punctuation.definition.comment.roff"
				2: name: "punctuation.definition.comment.roff"
		},{
			
			# Newline-devouring comment (GNU)
			name: "comment.line.number-sign.gnu.roff"
			begin: "(?:^(\\.|'+)\\s*)?(\\\\E?\#).*$\\R?"
			end: "^"
			beginCaptures:
				1: name: "punctuation.definition.comment.roff"
				2: name: "punctuation.definition.comment.roff"
		},{
			# Empty control lines
			name: "comment.empty.roff"
			match: "^(\\.|'+)[ \\t]*$"
			captures:
				1: name: "punctuation.definition.comment.roff"
		}
		
		{include: "#continuous-newline"}
		{include: "#register-expansion"}
		{
			# \\ - Escaped backslash
			name: "constant.character.escape.backslash.roff"
			match: "(?:((\\\\)E)|(\\\\))\\\\"
			captures:
				1: name: "constant.character.escape.current-escape-char.gnu.roff"
				2: name: "punctuation.definition.escape.roff"
				3: name: "punctuation.definition.escape.roff"
		},{
			# \t - Non-interpreted horizontal tab
			name: "constant.character.escape.tab.roff"
			match: "(?:((\\\\)E)|(\\\\))t"
			captures:
				1: name: "constant.character.escape.current-escape-char.gnu.roff"
				2: name: "punctuation.definition.escape.roff"
				3: name: "punctuation.definition.escape.roff"
		},{
			# \a - Leader character
			name: "constant.character.escape.leader-char.roff"
			match: "(?:((\\\\)E)|(\\\\))a"
			captures:
				1: name: "constant.character.escape.current-escape-char.gnu.roff"
				2: name: "punctuation.definition.escape.roff"
				3: name: "punctuation.definition.escape.roff"
		},{
			# \. - Literal full-stop
			name: "constant.character.escape.dot.roff"
			match: "(?:((\\\\)E)|(\\\\))\\."
			captures:
				1: name: "constant.character.escape.current-escape-char.gnu.roff"
				2: name: "punctuation.definition.escape.roff"
				3: name: "punctuation.definition.escape.roff"
		},{
			
			# \*[name].macro - Adhoc matching to improve tbl's "\*[3trans]" hack (GNU)
			begin: "^(\\\\\\*\\[[^\\]]+\\])\\s*(\\.\\w+.*)"
			end: "$"
			beginCaptures:
				1: patterns: [include: "#escapes"]
				2: patterns: [include: "#conditional-innards"]
		},{
			
			# \*[xx args…] - Interpolate string "xx" with optional arguments (GNU)
			name: "constant.character.escape.function.interpolate-string.gnu.roff"
			begin: "((?:((\\\\)E)|(\\\\))\\*(\\[))"
			end: "(\\])|(?<!\\\\)(?=$)"
			contentName: "function-call.arguments.roff"
			patterns: [include: "#long-name"]
			beginCaptures:
				1: name: "entity.name.roff"
				2: name: "constant.character.escape.current-escape-char.gnu.roff"
				3: name: "punctuation.definition.escape.roff"
				4: name: "punctuation.definition.escape.roff"
				5: name: "punctuation.section.begin.bracket.square.roff"
			endCaptures:
				1: name: "punctuation.section.end.bracket.square.roff"
		},{
			
			# \*x, \*(xx - Interpolate string "x" or "xx"
			name: "constant.character.escape.function.interpolate-string.roff"
			match: "((?:((\\\\)E)|(\\\\))\\*(\\())(\\S{2})|((?:((\\\\)E)|(\\\\))\\*)(\\S)"
			captures:
				1:  name: "entity.name.roff"
				2:  name: "constant.character.escape.current-escape-char.gnu.roff"
				3:  name: "punctuation.definition.escape.roff"
				4:  name: "punctuation.definition.escape.roff"
				5:  name: "punctuation.definition.brace.roff"
				6:  name: "variable.parameter.roff", patterns: [include: "#c0"]
				7:  name: "entity.name.roff"
				8:  name: "constant.character.escape.current-escape-char.gnu.roff"
				9:  name: "punctuation.definition.escape.roff"
				10: name: "punctuation.definition.escape.roff"
				11: name: "variable.parameter.roff", patterns: [include: "#c0"]
		},{
			
			# \$N - Interpolate argument number N (valid range: 1-9)
			name: "constant.character.escape.function.interpolate-argument.roff"
			match: "((?:((\\\\)E)|(\\\\))\\$\\d)"
			captures:
				1: name: "entity.name.roff"
				2: name: "constant.character.escape.current-escape-char.gnu.roff"
				3: name: "punctuation.definition.escape.roff"
				4: name: "punctuation.definition.escape.roff"
		},{

			# \m[X] - Alternate syntax for setting drawing/background colour (GNU)
			name: "constant.character.escape.function.set-colour.gnu.roff"
			begin: "((?:((\\\\)E)|(\\\\))[Mm](\\[))"
			end: "(\\])|(?<!\\\\)(?=$)"
			contentName: "variable.parameter.roff"
			patterns: [include: "#long-params"]
			beginCaptures:
				1: name: "entity.name.roff"
				2: name: "constant.character.escape.current-escape-char.gnu.roff"
				3: name: "punctuation.definition.escape.roff"
				4: name: "punctuation.definition.escape.roff"
				5: name: "punctuation.section.begin.bracket.square.roff"
			endCaptures:
				1: name: "punctuation.section.end.bracket.square.roff"
		},{
			
			# \mX, \m(XX - Set drawing or background colour to "X" (GNU)
			name: "constant.character.escape.function.set-colour.gnu.roff"
			match: "((?:((\\\\)E)|(\\\\))[Mm](\\())(\\S{2})|((?:((\\\\)E)|(\\\\))[Mm])(\\S)"
			captures:
				1:  name: "entity.name.roff"
				2:  name: "constant.character.escape.current-escape-char.gnu.roff"
				3:  name: "punctuation.definition.escape.roff"
				4:  name: "punctuation.definition.escape.roff"
				5:  name: "punctuation.definition.brace.roff"
				6:  name: "variable.parameter.roff", patterns: [include: "#c0"]
				7:  name: "entity.name.roff"
				8:  name: "constant.character.escape.current-escape-char.gnu.roff"
				9:  name: "punctuation.definition.escape.roff"
				10: name: "punctuation.definition.escape.roff"
				11: name: "variable.parameter.roff", patterns: [include: "#c0"]
		},{
			
			# \s[±n], \s±[n] - Set/adjust point-size (GNU)
			name: "constant.character.escape.function.point-size.gnu.roff"
			begin: "((?:((\\\\)E)|(\\\\))s([-+])?(\\[))"
			end: "(\\])|(?<!\\\\)(?=$)"
			contentName: "variable.parameter.roff"
			patterns: [include: "#long-params"]
			beginCaptures:
				1: name: "entity.name.roff"
				2: name: "constant.character.escape.current-escape-char.gnu.roff"
				3: name: "punctuation.definition.escape.roff"
				4: name: "punctuation.definition.escape.roff"
				5: name: "keyword.operator.arithmetic.roff"
				6: name: "punctuation.section.begin.bracket.square.roff"
			endCaptures:
				1: name: "punctuation.section.end.bracket.square.roff"
		},{
			
			# "Parametric" escape sequences supported in Groff (GNU)
			name: "constant.character.escape.function.check-identifier.gnu.roff"
			begin: "((?:((\\\\)E)|(\\\\))(?!s[-+]?\\(?\\d)[ABRsZ])((.))"
			end:   "(\\6)|(?<!\\\\)(?=$)"
			contentName: "string.other.roff"
			patterns: [include: "#escapes"]
			beginCaptures:
				1: name: "entity.name.function.roff"
				2: name: "constant.character.escape.current-escape-char.gnu.roff"
				3: name: "punctuation.definition.escape.roff"
				4: name: "punctuation.definition.escape.roff"
				5: name: "string.other.roff"
				6: name: "punctuation.definition.begin.roff"
			endCaptures:
				0: name: "string.other.roff"
				1: name: "punctuation.definition.end.roff"
		},{
			
			# \ON - Suppress troff output with signal "N" (GNU)
			name: "constant.character.escape.internal.gnu.roff"
			match: "((?:((\\\\)E)|(\\\\))O([0-4]))"
			captures:
				1: name: "entity.name.roff"
				2: name: "constant.character.escape.current-escape-char.gnu.roff"
				3: name: "punctuation.definition.escape.roff"
				4: name: "punctuation.definition.escape.roff"
				5: name: "constant.numeric.roff"
		},{
			
			# \O5[xyz] - Write file "xyz" to STDERR; grohtml-specific (GNU)
			name: "constant.character.escape.internal.stderr-write-file.gnu.roff"
			begin: "((?:((\\\\)E)|(\\\\))O(5)(\\[))"
			end: "(\\])|(?<!\\\\)(?=$)"
			contentName: "string.unquoted.filename.roff"
			patterns: [include: "#escapes"]
			beginCaptures:
				1: name: "entity.name.roff"
				2: name: "constant.character.escape.current-escape-char.gnu.roff"
				3: name: "punctuation.definition.escape.roff"
				4: name: "punctuation.definition.escape.roff"
				5: name: "constant.numeric.roff"
				6: name: "punctuation.section.begin.bracket.square.roff"
			endCaptures:
				1: name: "punctuation.section.end.bracket.square.roff"
		},{
			
			# \V[x] - Alternate syntax for interpolating environment variable (GNU)
			name: "constant.character.escape.function.interpolate-variable.gnu.roff"
			begin: "((?:((\\\\)E)|(\\\\))[VY](\\[))"
			end: "(\\])|(?<!\\\\)(?=$)"
			patterns: [include: "#long-name"]
			beginCaptures:
				1: name: "entity.name.roff"
				2: name: "constant.character.escape.current-escape-char.gnu.roff"
				3: name: "punctuation.definition.escape.roff"
				4: name: "punctuation.definition.escape.roff"
				5: name: "punctuation.section.begin.bracket.square.roff"
			endCaptures:
				1: name: "punctuation.section.end.bracket.square.roff"
		},{
			
			# \Vx, \V(xx - Interpolate contents of environment variable (GNU)
			name: "constant.character.escape.function.interpolate-variable.gnu.roff"
			match: "((?:((\\\\)E)|(\\\\))[VY](\\())(\\S{2})|((?:((\\\\)E)|(\\\\))[VY])(\\S)"
			captures:
				1:  name: "entity.name.roff"
				2:  name: "constant.character.escape.current-escape-char.gnu.roff"
				3:  name: "punctuation.definition.escape.roff"
				4:  name: "punctuation.definition.escape.roff"
				5:  name: "punctuation.definition.brace.roff"
				6:  name: "variable.parameter.roff", patterns: [include: "#c0"]
				7:  name: "entity.name.roff"
				8:  name: "constant.character.escape.current-escape-char.gnu.roff"
				9:  name: "punctuation.definition.escape.roff"
				10: name: "punctuation.definition.escape.roff"
				11: name: "variable.parameter.roff", patterns: [include: "#c0"]
		},{
			
			# \?code\? - Embed a chunk of code in diversion (GNU)
			match: "((?:((\\\\)E)|(\\\\))(\\?))(.*?)((\\\\)(\\?))"
			captures:
				1: name: "constant.character.escape.embed-diversion.start.gnu.roff"
				2: name: "constant.character.escape.current-escape-char.gnu.roff"
				3: name: "punctuation.definition.escape.roff"
				4: name: "punctuation.definition.escape.roff"
				5: name: "punctuation.definition.script.roff"
				6: name: "string.interpolated.roff", patterns: [include: "$self"]
				7: name: "constant.character.escape.embed-diversion.start.gnu.roff"
				8: name: "punctuation.definition.escape.roff"
				9: name: "punctuation.definition.script.roff"
		},{
			
			# \$*, \$@, \$^ - Argument concatenation for macros/strings (GNU)
			name: "constant.character.escape.function.concatenated-arguments.gnu.roff"
			match: "((?:((\\\\)E)|(\\\\))\\$[*@^])"
			captures:
				1: name: "variable.language.roff"
				2: name: "constant.character.escape.current-escape-char.gnu.roff"
				3: name: "punctuation.definition.escape.roff"
				4: name: "punctuation.definition.escape.roff"
		},{
			
			# \$(nn - Expand n-th argument passed to macro or string (GNU)
			name: "constant.character.escape.function.interpolate-argument.gnu.roff"
			match: "((?:((\\\\)E)|(\\\\))\\$(\\())(\\S{2})"
			captures:
				1: name: "entity.name.roff"
				2: name: "constant.character.escape.current-escape-char.gnu.roff"
				3: name: "punctuation.definition.escape.roff"
				4: name: "punctuation.definition.escape.roff"
				5: name: "punctuation.definition.brace.roff"
				6: name: "variable.parameter.roff"
		},{
			
			# \$[nnn] - Alternate syntax for expanding n-th macro/string argument (GNU)
			name: "constant.character.escape.function.interpolate-argument.gnu.roff"
			begin: "((?:((\\\\)E)|(\\\\))\\$(\\[))"
			end: "(\\])|(?<!\\\\)(?=$)"
			contentName: "variable.parameter.roff"
			patterns: [include: "#long-name"]
			beginCaptures:
				1: name: "entity.name.roff"
				2: name: "constant.character.escape.current-escape-char.gnu.roff"
				3: name: "punctuation.definition.escape.roff"
				4: name: "punctuation.definition.escape.roff"
				5: name: "punctuation.section.begin.bracket.square.roff"
			endCaptures:
				1: name: "punctuation.section.end.bracket.square.roff"
		}, include: "#c0"]
	
	
	# Escaped line-break
	"continuous-newline":
		begin: "(\\\\)?(\\\\)$\\R?"
		end:   "^(?:[.'])?"
		beginCaptures:
			0: name: "constant.character.escape.newline.roff"
			1: name: "punctuation.definition.concealed.escape.backslash.roff"
			2: name: "punctuation.definition.escape.roff"
	
	
	# Font escapes which terminate at EOL
	"escapes-clipped":
		patterns: [{
			# Italic
			begin: "\\\\E?f(?:[I2]|\\(CI|\\[\\s*(?:[I2]|CI)\\s*\\])"
			end: "$|(?=\\\\E?f[\\[A-Za-z0-9])"
			beginCaptures:
				0: patterns: [include: "#escapes"]
			patterns: [
				{include: "#escaped-newline"}
				{include: "$self"}
				{include: "#italic-word"}
			]
		},{
			# Bold
			begin: "\\\\E?f(?:[B3]|\\(CB|\\[\\s*(?:[B3]|CB)\\s*\\])"
			end: "$|(?=\\\\E?f[\\[A-Za-z0-9])"
			beginCaptures:
				0: patterns: [include: "#escapes"]
			patterns: [
				{include: "#escaped-newline"}
				{include: "$self"}
				{include: "#bold-word"}
			]
		},{
			# Bold and italic
			begin: "\\\\E?f(?:4|\\(BI|\\[\\s*BI\\s*\\])"
			end: "$|(?=\\\\E?f[\\[A-Za-z0-9])"
			beginCaptures:
				0: patterns: [include: "#escapes"]
			patterns: [
				{include: "#escaped-newline"}
				{include: "$self"}
				{include: "#bold-italic-word"}
			]
		},{
			# Constant-width/monospaced
			begin: "\\\\E?f(?:\\(C[WR]|\\[\\s*C[WR]\\s*\\])"
			end: "$|(?=\\\\E?f[\\[A-Za-z0-9])"
			beginCaptures:
				0: patterns: [include: "#escapes"]
			patterns: [
				{include: "#escaped-newline"}
				{include: "$self"}
				{include: "#monospace-word"}
			]
		}]
	
	
	# Every other escape sequence
	"escapes-full":
		patterns: [{
			
			# \e - Current escape character 
			name: "constant.character.escape.current-escape-char.roff"
			match: "(\\\\)E?e"
			captures:
				1: name: "punctuation.definition.escape.roff"
		},{
			
			# \´ - Acute accent (U+00B4)
			name: "constant.character.escape.acute-accent.roff"
			match: "(?:((\\\\)E)|(\\\\))´"
			captures:
				1: name: "constant.character.escape.current-escape-char.gnu.roff"
				2: name: "punctuation.definition.escape.roff"
				3: name: "punctuation.definition.escape.roff"
		},{
			
			# \` - Grave accent/backtick (U+0060)
			name: "constant.character.escape.grave-accent.roff"
			match: "(?:((\\\\)E)|(\\\\))`"
			captures:
				1: name: "constant.character.escape.current-escape-char.gnu.roff"
				2: name: "punctuation.definition.escape.roff"
				3: name: "punctuation.definition.escape.roff"
		},{
			
			# \- Mathematical minus (U+2212)
			name: "constant.character.escape.minus.roff"
			match: "(?:((\\\\)E)|(\\\\))-"
			captures:
				1: name: "constant.character.escape.current-escape-char.gnu.roff"
				2: name: "punctuation.definition.escape.roff"
				3: name: "punctuation.definition.escape.roff"
		},{
			
			# \ - Escaped space
			name: "constant.character.escape.space.roff"
			match: "(?:((\\\\)E)|(\\\\)) "
			captures:
				1: name: "constant.character.escape.current-escape-char.gnu.roff"
				2: name: "punctuation.definition.escape.roff"
				3: name: "punctuation.definition.escape.roff"
		},{
			
			# \0 - Digit-width space
			name: "constant.character.escape.space.digit-width.roff"
			match: "(?:((\\\\)E)|(\\\\))0"
			captures:
				1: name: "constant.character.escape.current-escape-char.gnu.roff"
				2: name: "punctuation.definition.escape.roff"
				3: name: "punctuation.definition.escape.roff"
		},{
			
			# \| - 1-sixth EM space
			name: "constant.character.escape.space.one-sixth-em.roff"
			match: "(?:((\\\\)E)|(\\\\))\\|"
			captures:
				1: name: "constant.character.escape.current-escape-char.gnu.roff"
				2: name: "punctuation.definition.escape.roff"
				3: name: "punctuation.definition.escape.roff"
		},{
			
			# \^ - One-twelfth EM space
			name: "constant.character.escape.space.one-twelfth-em.roff"
			match: "(?:((\\\\)E)|(\\\\))\\^"
			captures:
				1: name: "constant.character.escape.current-escape-char.gnu.roff"
				2: name: "punctuation.definition.escape.roff"
				3: name: "punctuation.definition.escape.roff"
		},{
			
			# \& - Zero-width marker/empty character
			name: "constant.character.escape.zero-width-marker.roff"
			match: "(?:((\\\\)E)|(\\\\))&"
			captures:
				1: name: "constant.character.escape.current-escape-char.gnu.roff"
				2: name: "punctuation.definition.escape.roff"
				3: name: "punctuation.definition.escape.roff"
		},{
			
			# \% - Hyphenation character
			name: "constant.character.escape.hyphenation-char.roff"
			match: "(?:((\\\\)E)|(\\\\))%"
			captures:
				1: name: "constant.character.escape.current-escape-char.gnu.roff"
				2: name: "punctuation.definition.escape.roff"
				3: name: "punctuation.definition.escape.roff"
		},{
			
			# \c - Connect to next input
			name: "constant.character.escape.connect.roff"
			match: "(?:((\\\\)E)|(\\\\))c"
			captures:
				1: name: "constant.character.escape.current-escape-char.gnu.roff"
				2: name: "punctuation.definition.escape.roff"
				3: name: "punctuation.definition.escape.roff"
		},{
			
			# \d - Move downward ½em
			match: "(?:((\\\\)E)|(\\\\))d"
			name: "constant.character.escape.downwards.roff"
			captures:
				1: name: "constant.character.escape.current-escape-char.gnu.roff"
				2: name: "punctuation.definition.escape.roff"
				3: name: "punctuation.definition.escape.roff"
		},{
			
			# \p - Break and spread line
			name: "constant.character.escape.spread-line.roff"
			match: "(?:((\\\\)E)|(\\\\))p"
			captures:
				1: name: "constant.character.escape.current-escape-char.gnu.roff"
				2: name: "punctuation.definition.escape.roff"
				3: name: "punctuation.definition.escape.roff"
		},{
			
			# \r - Upwards 1em
			name: "constant.character.escape.reverse.roff"
			match: "(?:((\\\\)E)|(\\\\))r"
			captures:
				1: name: "constant.character.escape.current-escape-char.gnu.roff"
				2: name: "punctuation.definition.escape.roff"
				3: name: "punctuation.definition.escape.roff"
		},{
			
			# \u - Upwards ½em
			match: "(?:((\\\\)E)|(\\\\))u"
			name: "constant.character.escape.upwards.roff"
			captures:
				1: name: "constant.character.escape.current-escape-char.gnu.roff"
				2: name: "punctuation.definition.escape.roff"
				3: name: "punctuation.definition.escape.roff"
		},{
			
			# \(aa - Character named "aa"
			name: "constant.character.escape.function.named-char.roff"
			match: "(?:((\\\\)E)|(\\\\))(\\()(\\S{2})"
			captures:
				1: name: "constant.character.escape.current-escape-char.gnu.roff"
				2: name: "punctuation.definition.escape.roff"
				3: name: "punctuation.definition.brace.roff"
				4: name: "punctuation.definition.escape.roff"
				5: name: "variable.parameter.roff", patterns: [include: "#c0"]
		},{
			
			# \[aa] - Character named "aa" (GNU)
			name: "constant.character.escape.function.named-char.gnu.roff"
			begin: "(?:((\\\\)E)|(\\\\))(\\[)"
			end: "(\\S*?)(\\])|(?<!\\\\)(?=$)"
			patterns: [
				{include: "#long-params"}
				{match: '(?:[^\\s\\]\\\\]|\\\\(?!E?["#]).)+', name: "variable.parameter.roff"}
			]
			beginCaptures:
				1: name: "constant.character.escape.current-escape-char.gnu.roff"
				2: name: "punctuation.definition.escape.roff"
				3: name: "punctuation.definition.escape.roff"
				4: name: "punctuation.section.begin.bracket.square.roff"
			endCaptures:
				1: patterns: [include: "#long-params"]
				2: name: "punctuation.section.end.bracket.square.roff"
		},{
			
			# Conditional input: Begin
			name: "meta.function.begin.roff"
			match: "(?:^(\\.|'+)[ \\t]*)?(\\\\\\{(?:\\\\(?=\\R|$))?)"
			captures:
				1: name: "punctuation.definition.request.roff"
				2: name: "punctuation.section.conditional.begin.roff"
		},{
			
			# Conditional input: End
			name: "meta.function.end.roff"
			match: "(?:^(\\.|'+)[ \\t]*)?(\\\\\\}(?:\\\\(?=\\R|$))?)"
			captures:
				1: name: "punctuation.definition.request.roff"
				2: name: "punctuation.section.conditional.end.roff"
		},{
			
			# Device control function
			name: "meta.device-control.roff"
			begin: "((?:((\\\\)E)|(\\\\))X)(.)"
			end:   "(.*?)(?:(\\5)|(?<!\\\\)(?=$))"
			beginCaptures:
				1: name: "entity.name.function.roff"
				2: name: "constant.character.escape.current-escape-char.gnu.roff"
				3: name: "punctuation.definition.escape.roff"
				4: name: "punctuation.definition.escape.roff"
				5: name: "punctuation.section.embedded.begin.roff", patterns: [include: "#c0"]
			endCaptures:
				1: name: "source.embedded.ditroff", patterns: [include: "source.ditroff#xCommands"]
				2: name: "punctuation.section.embedded.end.roff", patterns: [include: "#c0"]
			patterns: [{
				name: "source.embedded.ditroff"
				match: ".+"
				captures:
					0: patterns: [include: "source.ditroff#xCommands"]
			}, include: "#escapes"]
		},{
				
			# Parametric/function-like escape sequences
			name: "constant.character.escape.function.roff"
			begin: "((?:((\\\\)E)|(\\\\))[bCDhHSlLovwxXN])((.))"
			end:   "(\\6)|(?<!\\\\)(?=$)"
			contentName: "string.other.roff"
			patterns: [include: "#escapes"]
			beginCaptures:
				1: name: "entity.name.function.roff"
				2: name: "constant.character.escape.current-escape-char.gnu.roff"
				3: name: "punctuation.definition.escape.roff"
				4: name: "punctuation.definition.escape.roff"
				5: name: "string.other.roff"
				6: name: "punctuation.definition.begin.roff", patterns: [include: "#c0"]
			endCaptures:
				0: name: "string.other.roff"
				1: name: "punctuation.definition.end.roff", patterns: [include: "#c0"]
		},{
			
			# Transparent throughput
			name: "meta.throughput.roff"
			begin: "(?:((\\\\)E)|(\\\\))!"
			end: "(?<!\\\\)$"
			beginCaptures:
				0: name: "constant.character.escape.transparent-line.roff"
				1: name: "constant.character.escape.current-escape-char.gnu.roff"
				2: name: "punctuation.definition.escape.roff"
				3: name: "punctuation.definition.escape.roff"
			patterns: [include: "#escapes-copymode"]
		},{
			
			# Font: Roman/regular
			name: "constant.character.escape.font.roff"
			match: "(?:((\\\\)E)|(\\\\))f[RP1]"
			captures:
				0: name: "entity.name.roff"
				1: name: "constant.character.escape.current-escape-char.gnu.roff"
				2: name: "punctuation.definition.escape.roff"
				3: name: "punctuation.definition.escape.roff"
		},{
				
			# Font: Italics (typically rendered by nroff as underlined text)
			begin: "((?:((\\\\)E)|(\\\\))f(?:[I2]|(\\()CI|(\\[)\\s*(?:[I2]|CI)\\s*(\\])))"
			end: "(?=\\\\E?f[\\[A-Za-z0-9])|^(?=[.']\\s*(?:(?:SH|SS|P|[HILPT]P|di)\\b)|\\.)"
			beginCaptures:
				0: name: "constant.character.escape.font.roff"
				1: name: "entity.name.roff"
				2: name: "constant.character.escape.current-escape-char.gnu.roff"
				3: name: "punctuation.definition.escape.roff"
				4: name: "punctuation.definition.escape.roff"
				5: name: "punctuation.section.begin.bracket.square.roff"
				6: name: "punctuation.section.end.bracket.square.roff"
			patterns: [
				{include: "$self"}
				{include: "#italic-word"}
			]
		},{
			
			# Font: Bold
			begin: "((?:((\\\\)E)|(\\\\))f(?:[B3]|(\\()CB|(\\[)\\s*(?:[B3]|CB)\\s*(\\])))"
			end: "(?=\\\\E?f[\\[A-Za-z0-9])|^(?=[.']\\s*(?:(?:SH|SS|P|[HILPT]P|di)\\b)|\\.)"
			beginCaptures:
				0: name: "constant.character.escape.font.roff"
				1: name: "entity.name.roff"
				2: name: "constant.character.escape.current-escape-char.gnu.roff"
				3: name: "punctuation.definition.escape.roff"
				4: name: "punctuation.definition.escape.roff"
				5: name: "punctuation.definition.brace.roff"
				6: name: "punctuation.section.begin.bracket.square.roff"
				7: name: "punctuation.section.end.bracket.square.roff"
			patterns: [
				{include: "$self"}
				{include: "#bold-word"}
			]
		},{
			
			# Font: Bold and italic
			begin: "((?:((\\\\)E)|(\\\\))f(?:4|(\\()BI|(\\[)\\s*BI\\s*(\\])))"
			end: "(?=\\\\E?f[\\[A-Za-z0-9])|^(?=[.']\\s*(?:(?:SH|SS|P|[HILPT]P|di)\\b)|\\.)"
			beginCaptures:
				0: name: "constant.character.escape.font.roff"
				1: name: "entity.name.roff"
				2: name: "constant.character.escape.current-escape-char.gnu.roff"
				3: name: "punctuation.definition.escape.roff"
				4: name: "punctuation.definition.escape.roff"
				5: name: "punctuation.definition.brace.roff"
				6: name: "punctuation.section.begin.bracket.square.roff"
				7: name: "punctuation.section.end.bracket.square.roff"
			patterns: [
				{include: "$self"}
				{include: "#bold-italic-word"}
			]
		},{
			
			# Font: Constant-width/monospaced
			begin: "((?:((\\\\)E)|(\\\\))f(?:(\\()C[WR]|(\\[)\\s*C[WR]\\s*(\\])))"
			end: "(?=\\\\E?f[\\[A-Za-z0-9])|^(?=[.']\\s*(?:(?:SH|SS|P|[HILPT]P|di)\\b)|\\.)"
			beginCaptures:
				0: name: "constant.character.escape.font.roff"
				1: name: "entity.name.roff"
				2: name: "constant.character.escape.current-escape-char.gnu.roff"
				3: name: "punctuation.definition.escape.roff"
				4: name: "punctuation.definition.escape.roff"
				5: name: "punctuation.definition.brace.roff"
				6: name: "punctuation.section.begin.bracket.square.roff"
				7: name: "punctuation.section.end.bracket.square.roff"
			patterns: [
				{include: "$self"}
				{include: "#monospace-word"}
			]
		},{
			
			# \f[XX] - Change to font named "XX" (GNU)
			name: "constant.character.escape.function.font.gnu.roff"
			begin: "((?:((\\\\)E)|(\\\\))[Ff](\\[))"
			end: "(\\])|(?<!\\\\)(?=$)"
			contentName: "variable.parameter.roff"
			patterns: [include: "#escapes"]
			beginCaptures:
				1: name: "entity.name.roff"
				2: name: "constant.character.escape.current-escape-char.gnu.roff"
				3: name: "punctuation.definition.escape.roff"
				4: name: "punctuation.definition.escape.roff"
				5: name: "punctuation.section.begin.bracket.square.roff"
			endCaptures:
				1: name: "punctuation.section.end.bracket.square.roff"
		},{
			
			# \fX, \f(XX, \fN - Change to font named "X" or "XX", or position N
			name: "constant.character.escape.function.font.roff"
			match: "((?:((\\\\)E)|(\\\\))[Ff](\\())(\\S{2})|((?:((\\\\)E)|(\\\\))[Ff])(\\S)"
			captures:
				1:  name: "entity.name.roff"
				2:  name: "constant.character.escape.current-escape-char.gnu.roff"
				3:  name: "punctuation.definition.escape.roff"
				4:  name: "punctuation.definition.escape.roff"
				5:  name: "punctuation.definition.brace.roff"
				6:  name: "variable.parameter.roff", patterns: [include: "#c0"]
				7:  name: "entity.name.roff"
				8:  name: "constant.character.escape.current-escape-char.gnu.roff"
				9:  name: "punctuation.definition.escape.roff"
				10: name: "punctuation.definition.escape.roff"
				11: name: "variable.parameter.roff", patterns: [include: "#c0"]
		},{
			
			# \gx, \g(xx - Format of number register "x" or "xx"
			name: "constant.character.escape.function.format-register.roff"
			match: "((?:((\\\\)E)|(\\\\))g(\\())(\\S{2})|((?:((\\\\)E)|(\\\\))g)(\\S)"
			captures:
				1:  name: "entity.name.roff"
				2:  name: "constant.character.escape.current-escape-char.gnu.roff"
				3:  name: "punctuation.definition.escape.roff"
				4:  name: "punctuation.definition.escape.roff"
				5:  name: "punctuation.definition.brace.roff"
				6:  name: "variable.parameter.roff", patterns: [include: "#c0"]
				7:  name: "entity.name.roff"
				8:  name: "constant.character.escape.current-escape-char.gnu.roff"
				9:  name: "punctuation.definition.escape.roff"
				10: name: "punctuation.definition.escape.roff"
				11: name: "variable.parameter.roff", patterns: [include: "#c0"]
		},{
			
			# \kX - Mark horizontal input place in register "X"
			name: "constant.character.escape.function.mark-input.roff"
			match: "((?:((\\\\)E)|(\\\\))k)(\\S)"
			captures:
				1: name: "entity.name.roff"
				2: name: "constant.character.escape.current-escape-char.gnu.roff"
				3: name: "punctuation.definition.escape.roff"
				4: name: "punctuation.definition.escape.roff"
				5: name: "variable.parameter.roff", patterns: [include: "#c0"]
		},{
			
			# \sN, \s±N - Point-size change function; also \s(NN, \s±(NN
			name: "constant.character.escape.function.point-size.roff"
			match: "((?:((\\\\)E)|(\\\\))s[-+]?(\\()?)(\\d+)"
			captures:
				1: name: "entity.name.roff"
				2: name: "constant.character.escape.current-escape-char.gnu.roff"
				3: name: "punctuation.definition.escape.roff"
				4: name: "punctuation.definition.escape.roff"
				5: name: "punctuation.definition.brace.roff"
				6: name: "variable.parameter.roff"
		},{
			
			# \zC - Print "C" with zero width (without spacing)
			name: "constant.character.escape.function.zero-width-print.roff"
			match: "((?:((\\\\)E)|(\\\\))z)([^\\s\\\\])"
			captures:
				1: name: "entity.name.roff"
				2: name: "constant.character.escape.current-escape-char.gnu.roff"
				3: name: "punctuation.definition.escape.roff"
				4: name: "punctuation.definition.escape.roff"
				5: name: "variable.parameter.roff", patterns: [include: "#c0"]
		},{
			
			# \U'XX' - Print character with Unicode codepoint "XX" (Heirloom)
			name: "constant.character.escape.function.unicode-codepoint.heirloom.roff"
			match: "(?:((\\\\)E)|(\\\\))U([^0-9A-Fa-f ])([0-9A-Fa-f]+)(\\4)"
			captures:
				1: name: "constant.character.escape.current-escape-char.gnu.roff"
				2: name: "punctuation.definition.escape.roff"
				3: name: "punctuation.definition.escape.roff"
				4: name: "punctuation.definition.string.begin.roff", patterns: [include: "#c0"]
				5: name: "constant.numeric.integer.int.hexadecimal.roff"
				6: name: "punctuation.definition.string.end.roff", patterns: [include: "#c0"]
		},{
			
			# \T'anchor'text\T, \W'url'text'\W - Anchor/web link (Heirloom)
			name: "markup.link.inline.escape.heirloom.roff"
			match: "((?:((\\\\)E)|(\\\\))(T|W))((.)((?:(?!\\7).)++)(\\7))(.+?)((?:((\\\\)E)|(\\\\))\\5)"
			captures:
				1:  name: "constant.character.escape.function.roff"
				2:  name: "constant.character.escape.current-escape-char.gnu.roff"
				3:  name: "punctuation.definition.escape.roff"
				4:  name: "punctuation.definition.escape.roff"
				6:  name: "meta.link-destination.anchor.roff"
				7:  name: "punctuation.definition.string.begin.roff", patterns: [include: "#c0"]
				8:  name: "string.other.link.destination.roff",       patterns: [include: "#escapes"]
				9:  name: "punctuation.definition.string.end.roff",   patterns: [include: "#c0"]
				10: name: "entity.name.link-text.unquoted.roff",      patterns: [include: "#escapes"]
				11: name: "constant.character.escape.function.roff"
				12: name: "constant.character.escape.current-escape-char.gnu.roff"
				13: name: "punctuation.definition.escape.roff"
				14: name: "punctuation.definition.escape.roff"
		},{
			
			# \Z - Any character not listed above
			name: "constant.character.escape.misc.roff"
			match: "(?:((\\\\)E)|(\\\\))\\S"
			captures:
				1: name: "constant.character.escape.current-escape-char.gnu.roff"
				2: name: "punctuation.definition.escape.roff"
				3: name: "punctuation.definition.escape.roff"
		}]
	
	
	
	
	# Macros
	macros:
		patterns: [
			{include: "#man"}
			{include: "#mdoc"}
			{include: "#mono"}
			{include: "#ms"}
			{include: "#mm"}
			{include: "#me"}
			{include: "#www"}
			
			# Generic macro highlighting
			name: "meta.function.macro.roff"
			begin: "^([.'])[ \\t]*((?:[^\\s\\\\]|\\\\(?!E?[#\"]).)+)"
			end:   "(?<!\\\\)(?=$)|(?=\\\\E?\")"
			beginCaptures:
				1: name: "punctuation.definition.macro.roff"
				2: name: "entity.function.name.roff", patterns: [include: "#escapes"]
			patterns: [include: "#param-group"]
		]
	
	
	# Document macros
	mdoc:
		patterns: [{
			
			# .Bf [ -emphasis | Em ]: Begin emphasised text
			name: "meta.function.begin-emphasis.unparsed.macro.mdoc.roff"
			begin: "^([.'])\\s*(Bf)[ \\t]+(-emphasis|Em)(?=\\s)(.*)"
			end:   "^(?=[.']\\s*[BE]f\\s)"
			beginCaptures:
				1: name: "punctuation.definition.macro.roff"
				2: name: "entity.function.name.roff"
				3: name: "constant.language.option.mdoc.macro.roff"
				4: patterns: [include: "#escapes"]
			patterns: [
				{include: "$self"}
				{include: "#italic-word"}
			]
		},{

			# .Bf [ -literal | Li ]: Begin literal text
			name: "meta.function.begin-literal.unparsed.macro.mdoc.roff"
			begin: "^([.'])\\s*(Bf)[ \\t]+(-literal|Li)(?=\\s)(.*)"
			end:   "^(?=[.']\\s*[BE]f\\s)"
			beginCaptures:
				1: name: "punctuation.definition.macro.roff"
				2: name: "entity.function.name.roff"
				3: name: "constant.language.option.mdoc.macro.roff"
				4: patterns: [include: "#escapes"]
			patterns: [
				{include: "$self"}
				{include: "#monospace-word"}
			]
		},{
			
			# .Bf [ -symbolic | Sy ]: Begin symbolic text
			name: "meta.function.begin-symbolic.unparsed.macro.mdoc.roff"
			begin: "^([.'])\\s*(Bf)[ \\t]+(-symbolic|Sy)(?=\\s)(.*)"
			end:   "^(?=[.']\\s*[BE]f\\s)"
			beginCaptures:
				1: name: "punctuation.definition.macro.roff"
				2: name: "entity.function.name.roff"
				3: name: "constant.language.option.mdoc.macro.roff"
				4: patterns: [include: "#escapes"]
			patterns: [
				{include: "$self"}
				{include: "#bold-word"}
			]
		},{
			
			# .Rs/.Re: Bibliographic block
			begin: "^([.'])\\s*(Rs)(?=\\s)(.*)$"
			end:   "^([.'])\\s*(Re)(?=\\s)"
			patterns: [include: "#refer"]
			contentName: "meta.citation.mdoc.roff"
			beginCaptures:
				0: name: "meta.function.unparsed.macro.mdoc.roff"
				1: name: "punctuation.definition.macro.mdoc.roff"
				2: name: "entity.function.name.mdoc.roff"
				3: patterns: [include: "#escapes"]
			endCaptures:
				0: name: "meta.function.unparsed.macro.mdoc.roff"
				1: name: "punctuation.definition.mdoc.macro.roff"
				2: name: "entity.function.name.mdoc.roff"
		},{
			
			# .Bd/.Ed: Ad-hoc rules to highlight embedded source code
			begin: "^([.'])\\s*(Bd)\\s+(-literal)(?=\\s|$)(.*)"
			end:   "^([.'])\\s*(Ed)(?=\\s|$)"
			beginCaptures:
				0: name: "meta.function.$2.unparsed.macro.mdoc.roff"
				1: name: "punctuation.definition.macro.roff"
				2: name: "entity.function.name.roff"
				3: patterns: [include: "#mdoc-args"]
				4: patterns: [include: "#mdoc-unparsed"]
			endCaptures:
				0: name: "meta.function.$2.unparsed.macro.mdoc.roff"
				1: name: "punctuation.definition.macro.roff"
				2: name: "entity.function.name.roff"
			patterns: [{
				
				# HTML
				name: "meta.html-snippet.mdoc.roff"
				begin: "^(?:\\S*.*?\\s+)?HTML:\\s*$\\R?"
				end:   "^(?!\\t|\\s*$)"
				beginCaptures:
					0: patterns: [include: "#main"]
				patterns: [{
					name: "text.embedded.html.basic"
					match: ".+"
					captures:
						0: patterns: [include: "text.html.basic"]
				}]
			},{
				
				# JavaScript
				name: "meta.js-snippet.mdoc.roff"
				begin: "^(?:\\S*.*?\\s+)?JavaScript:\\s*$\\R?"
				end:   "^(?!\\t|\\s*$)"
				beginCaptures:
					0: patterns: [include: "#main"]
				patterns: [{
					match: ".+"
					captures:
						0: patterns: [include: "source.js"]
				}]
			},{
				
				# CSS
				name: "meta.css-snippet.mdoc.roff"
				begin: "^(?:\\S*.*?\\s+)?CSS:\\s*$\\R?"
				end:   "^(?!\\t|\\s*$)"
				beginCaptures:
					0: patterns: [include: "#main"]
				patterns: [include: "source.css"]
			
			},{
				
				# Shell
				name: "meta.shell-snippet.mdoc.roff"
				begin: "^(?:\\S*.*?\\s+)?(?i:Bash|(?:Bourne[\\s-]?)?Shell(?:[\\s-]?Script)?):\\s*$\\R?"
				end:   "^(?!\\t|\\s*$)"
				beginCaptures:
					0: patterns: [include: "#main"]
				patterns: [{
					match: ".+"
					captures:
						0: patterns: [include: "source.shell"]
				}]
			}, include: "#main"]
		},{
			
			# Document title
			name: "markup.heading.title.function.mdoc.macro.roff"
			begin: "^([.'])\\s*(Dt)(?=\\s)"
			end:   "(?<!\\\\)$"
			beginCaptures:
				0: name: "meta.function.$2.unparsed.macro.mdoc.roff"
				1: name: "punctuation.definition.macro.roff"
				2: name: "entity.name.function.roff"
			patterns: [
				{include: "#mdoc-delimiters"}
				{include: "#mdoc-args"}
			]
		},{
			
			# Document date
			name: "meta.function.document-date.unparsed.mdoc.macro.roff"
			begin: "^([.'])\\s*(Dd)(?:[ \\t]+|(?=$))"
			end:   "(?<!\\\\)$"
			beginCaptures:
				1: name: "punctuation.definition.macro.roff"
				2: name: "entity.function.name.roff"
			contentName: "string.unquoted.other.roff"
			patterns: [
				{include: "#mdoc-date-auto"}
				{include: "#mdoc-date-manual"}
				{include: "#mdoc-args"}
			]
		},{
			
			# Section heading
			name: "markup.heading.section.function.mdoc.macro.roff"
			begin: "^([.'])\\s*(Sh)(?=\\s)"
			end:   "(?<!\\\\)$"
			beginCaptures:
				0: name: "meta.function.$2.parsed.macro.mdoc.roff"
				1: name: "punctuation.definition.macro.roff"
				2: name: "entity.name.function.roff"
			patterns: [
				{include: "#mdoc-callables"}
				{include: "#mdoc-args"}
			]
		},{
			
			# Unparsed macros: passing callable macros as arguments won't invoke them
			name: "meta.function.$2.unparsed.macro.mdoc.roff"
			begin: "^([.'])\\s*(%[ABCDIJNOPQRTUV]|B[dfklt]|br|D[bdt]|E[dfklx]|F[do]|Hf|In|L[bp]|Nd|Os|Pp|R[esv]|Sm|sp|Ud)(?=\\s)"
			end:   "(?<!\\\\)$"
			beginCaptures:
				1: name: "punctuation.definition.macro.roff"
				2: name: "entity.function.name.roff"
			patterns: [include: "#mdoc-unparsed"]
		},{
			
			# Parsed macros: will execute callable mdoc macros
			name: "meta.function.$2.parsed.macro.mdoc.roff"
			begin: """(?x)^([.'])\\s*
				(Ac|Ad|An|Ao|Ap|Aq|Ar|At|Bc|Bo|Bq|Brc|Bro|Brq|Bsx|Bx|Cd|Cm|D1|Dc
				|Dl|Do|Dq|Dv|Dx|Ec|Em|En|Eo|Eq|Er|Es|Ev|Fa|Fc|Fl|Fn|Fr|Ft|Fx|Ic
				|It|Li|Lk|Me|Ms|Mt|Nm|No|Ns|Nx|Oc|Oo|Op|Ot|Ox|Pa|Pc|Pf|Po|Pq|Qc
				|Ql|Qo|Qq|Rd|Sc|Sh|So|Sq|Ss|St|Sx|Sy|Ta|Tn|Ux|Va|Vt|Xc|Xo|Xr)
				(?=\\s)"""
			end: "(?<!\\\\)$"
			beginCaptures:
				1: name: "punctuation.definition.macro.roff"
				2: name: "entity.function.name.roff"
			patterns: [
				{include: "#mdoc-callables"}
				{include: "#mdoc-args"}
				{include: "#generic-parameter"}
			]
		}]


	# Mdoc macros that're executed as arguments by "parsed" macros
	"mdoc-callables":
		patterns: [{
			
			# .Em: Emphasised text (Italic)
			name: "meta.function.$1.callable.macro.mdoc.roff"
			begin: "(?<=Em|Ar)\\G|(?<=\\s)(Em|Ar)(?=\\s)"
			end:   """(?x)
				(?<!\\\\)$ |
				(?=
					\\s+
					(?:Ac|Ad|An|Ao|Ap|Aq|Ar|At|Bc|Bo|Bq|Brc|Bro|Brq|Bsx|Bx|Cd|Cm|Dc|Do|Dq|Dv|Dx|Ec|Em
					|En|Eo|Er|Es|Ev|Fa|Fc|Fl|Fn|Fr|Ft|Fx|Ic|Li|Lk|Ms|Mt|Nm|No|Ns|Nx|Oc|Oo|Op|Ot|Ox|Pa
					|Pc|Pf|Po|Pq|Qc|Ql|Qo|Qq|Sc|So|Sq|Sx|Sy|Ta|Tn|Ux|Va|Vt|Xc|Xo|Xr)
					\\s | \\\\E? (?:"|f[\\[A-Za-z0-9])
				)"""
			beginCaptures:
				1: name: "entity.function.name.roff"
			patterns: [
				{include: "#mdoc-args"}
				{include: "$self"}
				{include: "#italic-word"}
			]
		},{
			
			# .Sy: Symbolic text (Bold)
			name: "meta.function.$1.callable.macro.mdoc.roff"
			begin: "(?<=Sy|Fl|Cm)\\G|(?<=\\s)(Sy|Fl|Cm)(?=\\s)"
			end:   """(?x)
				(?<!\\\\)$ |
				(?=
					\\s+
					(?:Ac|Ad|An|Ao|Ap|Aq|Ar|At|Bc|Bo|Bq|Brc|Bro|Brq|Bsx|Bx|Cd|Cm|Dc|Do|Dq|Dv|Dx|Ec|Em
					|En|Eo|Er|Es|Ev|Fa|Fc|Fl|Fn|Fr|Ft|Fx|Ic|Li|Lk|Ms|Mt|Nm|No|Ns|Nx|Oc|Oo|Op|Ot|Ox|Pa
					|Pc|Pf|Po|Pq|Qc|Ql|Qo|Qq|Sc|So|Sq|Sx|Sy|Ta|Tn|Ux|Va|Vt|Xc|Xo|Xr)
					\\s | \\\\E? (?:"|f[\\[A-Za-z0-9])
				)"""
			beginCaptures:
				1: name: "entity.function.name.roff"
			patterns: [
				{include: "#mdoc-args"}
				{include: "$self"}
				{include: "#bold-word"}
			]
		},{
			
			# .Li: Literal text (Monospaced)
			name: "meta.function.$1.callable.macro.mdoc.roff"
			begin: "(?<=Li)\\G|(?<=\\s)(Li)(?=\\s)"
			end:   """(?x)
				(?<!\\\\)$ |
				(?=
					\\s+
					(?:Ac|Ad|An|Ao|Ap|Aq|Ar|At|Bc|Bo|Bq|Brc|Bro|Brq|Bsx|Bx|Cd|Cm|Dc|Do|Dq|Dv|Dx|Ec|Em
					|En|Eo|Er|Es|Ev|Fa|Fc|Fl|Fn|Fr|Ft|Fx|Ic|Li|Lk|Ms|Mt|Nm|No|Ns|Nx|Oc|Oo|Op|Ot|Ox|Pa
					|Pc|Pf|Po|Pq|Qc|Ql|Qo|Qq|Sc|So|Sq|Sx|Sy|Ta|Tn|Ux|Va|Vt|Xc|Xo|Xr)
					\\s | \\\\E? (?:"|f[\\[A-Za-z0-9])
				)"""
			beginCaptures:
				1: name: "entity.function.name.roff"
			patterns: [
				{include: "#mdoc-args"}
				{include: "$self"}
				{include: "#monospace-word"}
			]
		},{
			
			# .Lk/.Mt: Hyperlink or mailto
			name: "meta.function.$1.callable.macro.mdoc.roff"
			begin: "(?<=Lk|Mt)\\G|(?<=\\s)(Lk|Mt)(?=\\s|$)\\s*"
			end:   '$|(?=\\\\E?")|(\\S+?)(?=$|\\s|\\\\E?")'
			beginCaptures:
				1: name: "entity.function.name.roff"
			endCaptures:
				0: name: "string.other.link.roff"
				1: name: "markup.underline.link.hyperlink.mdoc.roff", patterns: [include: "#escapes"]
		},{
			# Embedded macro name inside argument list
			name: "meta.function.$1.callable.macro.mdoc.roff"
			match: """(?x) (?<=[ \\t])
				(Ac|Ad|An|Ao|Ap|Aq|Ar|At|Bc|Bo|Bq|Brc|Bro|Brq|Bsx|Bx|Cd|Cm|Dc|Do|Dq|Dv|Dx|Ec|En
				|Eo|Er|Es|Ev|Fa|Fc|Fl|Fn|Fr|Ft|Fx|Ic|Li|Lk|Ms|Mt|Nm|No|Ns|Nx|Oc|Oo|Op|Ot|Ox|Pa|Pc
				|Pf|Po|Pq|Qc|Ql|Qo|Qq|Sc|So|Sq|Sx|Ta|Tn|Ux|Va|Vt|Xc|Xo|Xr)(?=\\s)"""
			captures:
				1: name: "entity.function.name.roff"
		}]


	# Arguments passed to mdoc macros
	"mdoc-args":
		patterns: [
			{include: "#escapes"}
			{include: "#string"}
			{
				# "Delimiters" (in mdoc's terms)
				name: "punctuation.delimiter.mdoc.macro.roff"
				match: "(?<=\\s)[(\\[.,:|;)\\]?!](?=\\s|$)"
			},{
				# Option flags used by some macros
				name: "constant.language.option.mdoc.macro.roff"
				match: """(?x)
					(?<=\\s) (-)
					(alpha|beta|bullet|centered|column|compact|dash|devel|diag|emphasis|enum|file|filled|hang
					|hyphen|inset|item|literal|nested|nosplit|ohang|ragged|split|std|symbolic|tag|type|unfilled
					|width|words|offset(?:\\s+(?:left|center|indent|indent-two|right))?)(?=\\s)"""
				captures: 1: name: "punctuation.definition.dash.roff"
			}]


	# Automatic revision date: $Mdocdate$ $Mdocdate:…$
	"mdoc-date-auto":
		name:  "meta.document-date.automatic.roff"
		begin: "(?:\\G|^)((\\$)Mdocdate)(?=[:$]|$)"
		end:   "\\s*((\\$))|(?=$)"
		beginCaptures:
			1: name: "keyword.rcs-like.section.begin.roff"
			2: name: "punctuation.section.begin.roff"
		endCaptures:
			1: name: "keyword.rcs-like.section.end.roff"
			2: name: "punctuation.section.end.roff"
		patterns: [{
			contentName: "constant.other.date.roff"
			begin: "\\G(:)\\s*"
			end:   "\\s*(?=\\$|(?<!\\\\)$)"
			beginCaptures:
				1: name: "punctuation.separator.key-value.roff"
			patterns: [
				{include: "#mdoc-date-manual"}
				{include: "#mdoc-args"}
			]
		}]


	# Hardcoded document date: Month DD, YYYY
	"mdoc-date-manual":
		name: "meta.document-date.hardcoded.roff"
		match: "(?:\\G|^)([A-Za-z]+\\s+\\d{1,2}(,)?\\s+\\d{4})\\b"
		captures:
			1: name: "constant.other.date.roff"
			2: name: "punctuation.separator.comma.roff"



	# Arguments passed to "unparsed" mdoc macros
	"mdoc-unparsed":
		patterns: [
			{include: "#mdoc-delimiters"}
			{include: "#mdoc-args"}
			{include: "#generic-parameter"}
		]


	# Macros I wrote while sleep-deprived
	mono:
		patterns: [{
			# Hyperlink
			name: "markup.link.inline.function.mono.macro.roff"
			begin: """(?x) ^([.'])[ \\t]*
				# Displayed text
				(
					# .[ Text ]( … )
					(\\[) \\s+
					(?: ((")((?:[^\\\\"]|\\\\[^"\\#]|"")*+)(")) | ((?:[^\\\\\\s]|\\\\.)++))
					\\s+ (\\])
					(?! \\(\\) | <>)
					|
					# .[ Destination ][]
					(\\[) \\s+
					(?: (")((?:[^\\\\"]|\\\\[^"\\#]|"")*+)(") | ((?:[^\\\\\\s]|\\\\.)++))
					\\s+ (\\])
					(?= \\(\\) | <>)
				)
				(?=
					(?: \\( \\)
					|   \\[ \\]
					|     < >
					|   \\( \\s .*? \\s \\)
					|   \\[ \\s .*? \\s \\]
					|     < \\s .*? \\s >
					)? (?:\\s|$|\\\\E?[\"\\#])
				)
			"""
			end: "(?<!\\\\)(?=\\R|$)|(?=\\\\E?\")"
			beginCaptures:
				1:  name: "punctuation.definition.macro.roff"
				2:  name: "meta.link-destination.displayed.roff"
				3:  name: "punctuation.definition.square.bracket.begin.roff"
				4:  name: "entity.name.link-text.quoted.roff"
				5:  name: "punctuation.definition.string.begin.roff"
				6:  patterns: [include: "#string-escapes"]
				7:  name: "punctuation.definition.string.end.roff"
				8:  name: "entity.name.link-text.unquoted.roff", patterns: [include: "#escapes"]
				9:  name: "punctuation.definition.square.bracket.end.roff"
				10: name: "punctuation.definition.square.bracket.begin.roff"
				11: name: "punctuation.definition.string.begin.roff"
				12: patterns: [include: "#mono-link-destination"]
				13: name: "punctuation.definition.string.end.roff"
				14: patterns: [include: "#mono-link-destination"]
				15: name: "punctuation.definition.square.bracket.end.roff"
			patterns: [{
				match: """(?x) \\G
					# Destination
					(
						# .[ Text ] is another way to write .[ Text ][]
						(?=\\s)
						|
						# Shorthand for links with identical text/URL parameters
						(?:(\\(\\)) | (\\[\\]) | (<>))
						(?=\\s|$)
						|
						# 6-argument form to customise rendering of non-interactive links
						(?:
							# .[ Details ]( “ (visit ” http://url “ for more information” )
							(\\() \\s+
							(?:("  (?:[^\\\\"]|\\\\[^"\\#]|"")*+  ")|((?:[^\\\\\\s]|\\\\.)++)) \\s+
							(?:(")((?:[^\\\\"]|\\\\[^"\\#]|"")*+)(")|((?:[^\\\\\\s]|\\\\.)++)) \\s+
							(?:("  (?:[^\\\\"]|\\\\[^"\\#]|"")*+  ")|((?:[^\\\\\\s]|\\\\.)++)) \\s+
							(\\))
							|
							# …[ Term ][ “ (q.v. ” term-id “, section 3.2)” ]
							(\\[) \\s+
							(?:("  (?:[^\\\\"]|\\\\[^"\\#]|"")*+  ")|((?:[^\\\\\\s]|\\\\.)++)) \\s+
							(?:(")((?:[^\\\\"]|\\\\[^"\\#]|"")*+)(")|((?:[^\\\\\\s]|\\\\.)++)) \\s+
							(?:("  (?:[^\\\\"]|\\\\[^"\\#]|"")*+  ")|((?:[^\\\\\\s]|\\\\.)++)) \\s+
							(\\])
							|
							# …[ “send an e-mail” ]< “ to ” email@address.com “” >
							(<) \\s+
							(?:("  (?:[^\\\\"]|\\\\[^"\\#]|"")*+  ")|((?:[^\\\\\\s]|\\\\.)++)) \\s+
							(?:(")((?:[^\\\\"]|\\\\[^"\\#]|"")*+)(")|((?:[^\\\\\\s]|\\\\.)++)) \\s+
							(?:("  (?:[^\\\\"]|\\\\[^"\\#]|"")*+  ")|((?:[^\\\\\\s]|\\\\.)++)) \\s+
							(>)
						)
						|
						# Normal form
						(?: (\\() \\s+ (?: (")((?:[^\\\\"]|\\\\[^"\\#]|"")*+)(") | ((?:[^\\\\\\s]|\\\\.)++)) \\s+ (\\)) # .[ Text ]( http://url.com )
						|   (\\[) \\s+ (?: (")((?:[^\\\\"]|\\\\[^"\\#]|"")*+)(") | ((?:[^\\\\\\s]|\\\\.)++)) \\s+ (\\]) # .[ Text ][ anchor-id ]
						|     (<) \\s+ (?: (")((?:[^\\\\"]|\\\\[^"\\#]|"")*+)(") | ((?:[^\\\\\\s]|\\\\.)++)) \\s+ (>)   # .[ Text ]< email@address >
						)
					)
					(?:\\s+([(\\[`"'.,:<|>;)\\]?!]))?
					(?=\\s*(?:$|\\\\[^\\#]))
				"""
				captures:
					1:  name: "meta.link-destination.roff"
					2:  name: "punctuation.definition.round.bracket.empty.roff"
					3:  name: "punctuation.definition.square.bracket.empty.roff"
					4:  name: "punctuation.definition.angle.bracket.empty.roff"
					5:  name: "punctuation.definition.round.bracket.begin.roff"
					6:  name: "string.quoted.double.link-prefix.roff", patterns: [include: "#string"]
					7:  name: "string.unquoted.link-prefix.roff",      patterns: [include: "#string"]
					8:  name: "punctuation.definition.string.begin.roff"
					9:  patterns: [include: "#mono-link-destination"]
					10: name: "punctuation.definition.string.end.roff"
					11: patterns: [include: "#mono-link-destination"]
					12: name: "string.quoted.double.link-affix.roff", patterns: [include: "#string"]
					13: name: "string.unquoted.link-affix.roff",      patterns: [include: "#string"]
					14: name: "punctuation.definition.round.bracket.end.roff"
					15: name: "punctuation.definition.square.bracket.begin.roff"
					16: name: "string.quoted.double.link-prefix.roff", patterns: [include: "#string"]
					17: name: "string.unquoted.link-prefix.roff",      patterns: [include: "#string"]
					18: name: "punctuation.definition.string.begin.roff"
					19: patterns: [include: "#mono-link-destination"]
					20: name: "punctuation.definition.string.end.roff"
					21: patterns: [include: "#mono-link-destination"]
					22: name: "string.quoted.double.link-affix.roff", patterns: [include: "#string"]
					23: name: "string.unquoted.link-affix.roff",      patterns: [include: "#string"]
					24: name: "punctuation.definition.square.bracket.end.roff"
					25: name: "punctuation.definition.angle.bracket.begin.roff"
					26: name: "string.quoted.double.link-prefix.roff", patterns: [include: "#string"]
					27: name: "string.unquoted.link-prefix.roff",      patterns: [include: "#string"]
					28: name: "punctuation.definition.string.begin.roff"
					29: patterns: [include: "#mono-link-destination"]
					30: name: "punctuation.definition.string.end.roff"
					31: patterns: [include: "#mono-link-destination"]
					32: name: "string.quoted.double.link-affix.roff", patterns: [include: "#string"]
					33: name: "string.unquoted.link-affix.roff",      patterns: [include: "#string"]
					34: name: "punctuation.definition.square.bracket.end.roff"
					35: name: "punctuation.definition.round.bracket.begin.roff"
					36: name: "punctuation.definition.string.begin.roff"
					37: patterns: [include: "#mono-link-destination"]
					38: name: "punctuation.definition.string.end.roff"
					39: patterns: [include: "#mono-link-destination"]
					40: name: "punctuation.definition.round.bracket.end.roff"
					41: name: "punctuation.definition.square.bracket.begin.roff"
					42: name: "punctuation.definition.string.begin.roff"
					43: patterns: [include: "#mono-link-destination"]
					44: name: "punctuation.definition.string.end.roff"
					45: patterns: [include: "#mono-link-destination"]
					46: name: "punctuation.definition.square.bracket.end.roff"
					47: name: "punctuation.definition.angle.bracket.begin.roff"
					48: name: "punctuation.definition.string.begin.roff"
					49: patterns: [include: "#mono-link-destination"]
					50: name: "punctuation.definition.string.end.roff"
					51: patterns: [include: "#mono-link-destination"]
					52: name: "punctuation.definition.angle.bracket.end.roff"
					53: name: "punctuation.terminator.mono.macro.roff"
			}, include: "#params"]
		}]


	# Stuff matched inside an underlined hyperlink
	"mono-link-destination":
		name: "string.other.link.destination.roff"
		match: "(.+)"
		captures:
			0: name: "markup.underline.link.hyperlink.roff"
			1: patterns: [include: "#string-escapes"]


	# Manuscript macros
	ms:
		patterns: [{
			name: "meta.function.${2:/downcase}.ms.macro.roff"
			begin: """(?x) ^([.'])[ \\t]*
				(1C|2C|AB|AE|AI|AU|B1|B2|BT|BX|DA|DE|DS|EN|EQ|FE|FS|IP|KE|KF|KS|LG
				|LP|MC|ND|NH|NL|P1|PE|PP|PS|PT|PX|QP|RP|SH|SM|TA|TC|TE|TL|TS|XA|XE
				|XP|XS)(?=\\s)"""
			end: "(?<!\\\\)(?=\\R|$)|(?=\\\\E?\")"
			beginCaptures:
				1: name: "punctuation.definition.macro.roff"
				2: name: "entity.function.name.roff"
			patterns: [include: "#params"]
		},{
			
			# Headers and footers
			name: "meta.function.${2:/downcase}.ms.macro.roff"
			contentName: "function-call.arguments.roff"
			begin: "^([.'])[ \\t]*([EO][FH])(?=\\s)"
			end:   "(?<!\\\\)(?=\\R|$)|(?=\\\\E?\")"
			beginCaptures:
				1: name: "punctuation.definition.macro.roff"
				2: name: "entity.function.name.roff"
			patterns: [
				{include: "#3-part-title"}
				{include: "#escapes"}
				{include: "#string"}
			]
		},{
			
			# Deprecated macros
			name: "meta.deprecated.function.${2:/downcase}.ms.macro.roff"
			contentName: "function-call.arguments.roff"
			begin: "^([.'])[ \\t]*((De|Ds))(?=\\s)"
			end: "(?<!\\\\)$|(?=\\s*\\\\E?\")"
			beginCaptures:
				1: name: "punctuation.definition.macro.roff"
				2: name: "entity.function.name.roff"
				3: name: "invalid.deprecated.roff"
			patterns: [
				{include: "#escapes"}
				{include: "#string"}
			]
		},{
		
			# Monospaced/constant-width text
			name: "meta.function.cw.ms.macro.roff"
			begin: "^([.'])[ \\t]*(CW)(?=\\s)"
			end: "(?<!\\\\)$|(?=\\\\E?\")"
			beginCaptures:
				1: name: "punctuation.definition.macro.roff"
				2: name: "entity.function.name.roff"
			patterns: [{
				
				# Unquoted string
				name: "markup.raw.roff"
				begin: "\\G[ \\t]*(?!\")(?=(?:[^\\s\\\\]|\\\\(?!E?\").)+)"
				end:   "(?<![^\\\\]\\\\|^\\\\)(?=\\s|$)|(?=\\\\E?\")"
				patterns: [include: "#escapes"]
			},{
			
				# Null argument
				name: "markup.raw.roff"
				match: '(")(")'
				captures:
					0: name: "string.quoted.double.empty.roff"
					1: name: "punctuation.definition.string.begin.roff"
					2: name: "punctuation.definition.string.end.roff"
			},{
				
				# Quoted string
				name: "string.quoted.double.roff"
				contentName: "markup.raw.roff"
				begin: '\\G[ \\t]*(")'
				end:   '((?:"")*)"(?!")|(?<!\\\\)$|(?=\\\\E?\")'
				beginCaptures: 1: name: "punctuation.definition.string.begin.roff"
				endCaptures:
					0: name: "punctuation.definition.string.end.roff"
					1: name: "markup.raw.roff", patterns: [include: "#string-escapes"]
				patterns: [include: "#string-escapes"]
			}
			{include: "#escapes"}
			{include: "#string"}]
		},{
			
			# Underlined text
			name: "meta.function.ul.ms.macro.roff"
			begin: "^([.'])[ \\t]*(UL)(?=\\s|$)\\s*"
			end: "(?<!\\\\)$|(?=\\\\E?\")"
			beginCaptures:
				1: name: "punctuation.definition.macro.roff"
				2: name: "entity.function.name.roff"
			patterns: [include: "#underline-first"]
		}]
	
	
	# Memorandum macros
	mm:
		patterns: [{
			name: "meta.function.${2:/downcase}.mm.macro.roff"
			begin: """(?x) ^([.'])[ \\t]*
				(1C|2C|AE|AF|AL|APP|APPSK|AS|AST|AT|AU|AV|AVL|B1|B2|BE|BL|BS|BVL
				|COVER|COVEND|DE|DF|DL|DS|EC|EF|EH|EN|EOP|EPIC|EQ|EX|FC|FD|FE|FG
				|FS|GETHN|GETPN|GETR|GETST|H|HC|HM|HU|HX|HY|HZ|IA|IE|INITI|INITR
				|IND|INDP|ISODATE|LB|LC|LE|LI|LT|LO|MC|ML|MT|MOVE|MULB|MULN|MULE
				|nP|NCOL|NS|ND|OF|OH|OP|PGFORM|PGNH|PIC|PE|PF|PH|PS|PX?|RD|RF|RL
				|RP|RS|S|SA|SETR|SG|SK|SM|SP|TA?B|TC|TE|TL|TM|TP|TS|TX|TY|VERBON
				|VERBOFF|VL|VM|WA|WE|WC|\\)E)(?=\\s)"""
			end: "(?<!\\\\)$|(?=\\\\E?\")"
			beginCaptures:
				1: name: "punctuation.definition.macro.roff"
				2: name: "entity.function.name.roff"
			patterns: [include: "#params"]
		}]
	
	
	# Paper-formatting macros
	me:
		patterns: [{
			
			# Assorted macros without special highlighting or pattern-matching
			name: "meta.function.${3:/downcase}.me.macro.roff"
			begin: """(?x) ^([.'])[ \\t]*
				((?:[()][cdfqxz]|\\+\\+|\\+c)|
				(1c|2c|EN|EQ|GE|GS|PE|PS|TE|TH|TS|ba|bc|bu|bx|hx
				|hl|ip|lp|np|pd|pp|r|re|sk|sm|sz|tp|uh|xp)(?=\\s))"""
			end: "(?<!\\\\)$|(?=\\\\E?\")"
			beginCaptures:
				1: name: "punctuation.definition.macro.roff"
				3: name: "entity.function.name.roff"
			patterns: [include: "#params"]
		},{
			
			# .(l: List
			begin: "^([.'])[ \\t]*(\\(l)(?=\\s)"
			end:   "^([.'])[ \\t]*(\\)l)(?=\\s)"
			contentName: "markup.list.unnumbered.roff"
			patterns: [include: "$self"]
			beginCaptures:
				0: name: "meta.function.list.begin.me.macro.roff"
				1: name: "punctuation.definition.macro.roff"
				2: name: "entity.function.name.roff"
			endCaptures:
				0: name: "meta.function.list.end.me.macro.roff"
				1: name: "punctuation.definition.macro.roff"
				2: name: "entity.function.name.roff"
		},{
			
			# .b: Bold
			begin: "^([.'])[ \\t]*(b)(?=\\s)"
			end: "(?<![^\\\\]\\\\|^\\\\)(?=$|\\R)|(?=\\\\E?\")"
			contentName: "function-call.arguments.roff"
			beginCaptures:
				0: name: "meta.function.bold-text.me.macro.roff"
				1: name: "punctuation.definition.macro.roff"
				2: name: "entity.function.name.roff"
			patterns: [include: "#bold-first"]
		},{
			
			# .i: Italic
			begin: "^([.'])[ \\t]*(i)(?=\\s)"
			end: "(?<![^\\\\]\\\\|^\\\\)(?=$|\\R)|(?=\\\\E?\")"
			contentName: "function-call.arguments.roff"
			beginCaptures:
				0: name: "meta.function.italic-text.me.macro.roff"
				1: name: "punctuation.definition.macro.roff"
				2: name: "entity.function.name.roff"
			patterns: [include: "#italic-first"]
		},{
			
			# .bi: Bold/Italic
			begin: "^([.'])[ \\t]*(bi)(?=\\s)"
			end: "(?<![^\\\\]\\\\|^\\\\)(?=$|\\R)|(?=\\\\E?\")"
			contentName: "function-call.arguments.roff"
			beginCaptures:
				0: name: "meta.function.bold-italic-text.me.macro.roff"
				1: name: "punctuation.definition.macro.roff"
				2: name: "entity.function.name.roff"
			patterns: [include: "#bold-italic-first"]
		},{
			
			# .u: Underline
			begin: "^([.'])[ \\t]*(u)(?=\\s|$)\\s*"
			end: "(?<![^\\\\]\\\\|^\\\\)(?=$|\\R)|(?=\\\\E?\")"
			contentName: "function-call.arguments.roff"
			beginCaptures:
				0: name: "meta.function.underline-text.me.macro.roff"
				1: name: "punctuation.definition.macro.roff"
				2: name: "entity.function.name.roff"
			patterns: [include: "#underline-first"]
		},{
			
			# .sh: Section heading
			name: "markup.heading.section.function.me.macro.roff"
			begin: "^([.'])[ \\t]*(sh)[ \\t]+((?!\")\\S+)\\b[ \\t]*(?!$|\\R|\\\\E?\")"
			end:   "(?<![^\\\\]\\\\|^\\\\)(?=$|\\R)|(?=\\\\E?\")"
			beginCaptures:
				1: name: "punctuation.definition.macro.roff"
				2: name: "entity.function.name.roff"
				3: name: "variable.parameter.roff", patterns: [include: "#params"]
			patterns: [include: "#bold-first"]
		},{
			
			# Headers and footers
			name: "meta.function.${2:/downcase}.me.macro.roff"
			contentName: "function-call.arguments.roff"
			begin: "^([.'])[ \\t]*(of|oh|he|eh|fo|ef)(?=\\s)"
			end:   "(?<!\\\\)(?=\\R|$)|(?=\\\\E?\")"
			beginCaptures:
				1: name: "punctuation.definition.macro.roff"
				2: name: "entity.function.name.roff"
			patterns: [
				{include: "#3-part-title"}
				{include: "#escapes"}
				{include: "#string"}
			]
		}]
	
	
	# Webpage macros
	www:
		patterns: [{
			
			name: "meta.function.${2:/downcase}.www.macro.roff"
			begin: """(?x) ^([.'])[ \\t]*
				(ALN|BCL|BGIMG|DC|DLE|DLS|HEAD|HR|HTM?L|HX|JOBNAME
				|LI|LINKSTYLE|LK|LNE|LNS|MPIMG|NHR|P?IMG|TAG)(?=\\s)"""
			end: "(?<!\\\\)$|(?=\\\\E?\")"
			beginCaptures:
				1: name: "punctuation.definition.macro.roff"
				2: name: "entity.function.name.roff"
			patterns: [include: "#params"]
		},{
			
			# Macros that take URIs as their first argument
			name: "meta.function.${2:/downcase}.www.macro.roff"
			begin: "^([.'])[ \\t]*(URL|FTP|MTO)(?=\\s)"
			end:   "(?<!\\\\)(?=$)|(?=\\\\E?\")"
			beginCaptures:
				1: name: "punctuation.definition.macro.roff"
				2: name: "entity.function.name.roff"
			patterns: [include: "#underline-first"]
		},{
			
			# Code blocks
			name: "meta.function.${2:/downcase}.www.macro.roff"
			contentName: "markup.raw.roff"
			begin: "^([.'])[ \\t]*(CDS)(?=\\s|\\\\E?[\"#])\\s*(\\\\E?[#\"].*)?$"
			end:   "^([.'])[ \\t]*(CDE)(?=\\s|\\\\E?[\"#])"
			beginCaptures:
				1: name: "punctuation.definition.macro.roff"
				2: name: "entity.function.name.roff"
				3: patterns: [include: "#escapes"]
			endCaptures:
				1: name: "punctuation.definition.macro.roff"
				2: name: "entity.function.name.roff"
			patterns: [include: "$self"]
		},{
			
			# Headings
			name: "markup.heading.$3.www.macro.roff"
			contentName: "string.unquoted.heading.roff"
			begin: "^([.'])[ \\t]*(HnS)(?=\\s)(?:\\s*(\\d+))?(?:\\s*(\\\\E?[#\"].*)$)?"
			end:   "^([.'])[ \\t]*(HnE)(?=\\s)(.*)$"
			beginCaptures:
				0: name: "meta.function.${2:/downcase}.macro.roff"
				1: name: "punctuation.definition.macro.roff"
				2: name: "entity.function.name.roff"
				3: name: "constant.numeric.roff"
				4: patterns: [include: "#escapes"]
			endCaptures:
				1: name: "punctuation.definition.macro.roff"
				2: name: "entity.function.name.roff"
				3: patterns: [include: "#escapes"]
			patterns: [include: "$self"]
		},{
			
			# Ordered lists
			name: "meta.function.${2:/downcase}.www.macro.roff"
			contentName: "markup.list.ordered.roff"
			begin: "^([.'])[ \\t]*(OLS)(?=\\s)\\s*(\\\\E?[#\"].*)?$"
			end:   "^([.'])[ \\t]*(OLE)(?=\\s)"
			beginCaptures:
				1: name: "punctuation.definition.macro.roff"
				2: name: "entity.function.name.roff"
				3: patterns: [include: "#escapes"]
			endCaptures:
				1: name: "punctuation.definition.macro.roff"
				2: name: "entity.function.name.roff"
			patterns: [include: "$self"]
		},{
			
			# Unordered lists
			name: "meta.function.${2:/downcase}.www.macro.roff"
			contentName: "markup.list.ordered.roff"
			begin: "^([.'])[ \\t]*(ULS)(?=\\s)\\s*(\\\\E?[#\"].*)?$"
			end:   "^([.'])[ \\t]*(ULE)(?=\\s)"
			beginCaptures:
				1: name: "punctuation.definition.macro.roff"
				2: name: "entity.function.name.roff"
				3: patterns: [include: "#escapes"]
			endCaptures:
				1: name: "punctuation.definition.macro.roff"
				2: name: "entity.function.name.roff"
			patterns: [include: "$self"]
		}]
	
	
	
	# Manual-page macros
	man:
		patterns: [{
			
			# Various macros that don't need special highlighting
			name: "meta.function.${2:/downcase}.man.macro.roff"
			begin: "^([.'])[ \\t]*(RE|RS|SM|BT|PT)(?=\\s)"
			end:   "(?<!\\\\)(?=$)|(?=\\\\E?\")"
			beginCaptures:
				1: name: "punctuation.definition.macro.roff"
				2: name: "entity.function.name.roff"
			patterns: [include: "#param-group"]
		},{
		
			# Various deprecated macros
			name: "meta.deprecated.function.${2:/downcase}.man.macro.roff"
			begin: "^([.'])[ \\t]*((AT|DT|PD|UC))(?=\\s)"
			end:   "(?<!\\\\)(?=$)|(?=\\\\E?\")"
			beginCaptures:
				1: name: "punctuation.definition.macro.roff"
				2: name: "entity.function.name.roff"
				3: name: "invalid.deprecated.roff"
			patterns: [include: "#param-group"]
		},{
			# .TH: Title
			name: "markup.heading.title.function.man.macro.roff"
			begin: "^([.'])[ \\t]*(TH)(?=\\s)"
			end: "(?<!\\\\)$|(?=\\\\E?\")"
			patterns: [include: "#escapes"]
			beginCaptures:
				0: name: "meta.function.man.macro.roff"
				1: name: "punctuation.definition.macro.roff"
				2: name: "entity.name.function.roff"
		},{
			
			# .SH: Section heading
			name: "markup.heading.section.function.man.macro.roff"
			begin: "^([.'])[ \\t]*(SH)(?=\\s)"
			end: "(?<!\\\\)$|(?=\\\\E?\")"
			patterns: [include: "#escapes"]
			beginCaptures:
				0: name: "meta.function.man.macro.roff"
				1: name: "punctuation.definition.macro.roff"
				2: name: "entity.name.function.roff"
		},{
			
			# .SS: Subsection
			name: "markup.heading.subsection.function.man.macro.roff"
			begin: "^([.'])[ \\t]*(SS)(?=\\s)"
			end: "(?<!\\\\)$|(?=\\\\E?\")"
			patterns: [include: "#escapes"]
			beginCaptures:
				0: name: "meta.function.man.macro.roff"
				1: name: "punctuation.definition.macro.roff"
				2: name: "entity.name.function.roff"
		},{
		
			# .EX: Example code
			contentName: "markup.raw.roff"
			begin: "^([.'])[ \\t]*(EX)\\s*(\\\\E?[#\"].*)?$"
			end:   "^([.'])[ \\t]*(EE)(?=\\s|\\\\E?[#\"])"
			patterns: [include: "$self"]
			beginCaptures:
				0: name: "meta.function.man.macro.roff"
				1: name: "punctuation.definition.function.macro.roff"
				2: name: "entity.name.function.roff"
				3: patterns: [include: "#escapes-copymode"]
			endCaptures:
				0: name: "meta.function.man.macro.roff"
				1: name: "punctuation.definition.function.macro.roff"
				2: name: "entity.name.function.roff"
		},{
			
			# .LP/.PP/.P: Paragraph
			name: "meta.function.paragraph.man.macro.roff"
			begin: "^([.'])[ \\t]*(LP|PP?)(?=\\s|\\\\E?[\"#])"
			end:   "(?<!\\\\)(?=$)|(?=\\\\E?\")"
			beginCaptures:
				1: name: "punctuation.definition.macro.roff"
				2: name: "entity.function.name.roff"
			patterns: [include: "#params"]
		},{
			
			# .IP: Indented paragraph
			name: "meta.function.indented-paragraph.man.macro.roff"
			begin: "^([.'])[ \\t]*(IP)(?=\\s|\\\\E?[\"#])"
			end:   "(?<!\\\\)(?=$)|(?=\\\\E?\")"
			beginCaptures:
				1: name: "punctuation.definition.macro.roff"
				2: name: "entity.function.name.roff"
			patterns: [include: "#param-group"]
		},{
			
			# .TP/.TQ: Titled paragraph
			begin: "^([.'])[ \\t]*(TP|TQ)(?=\\s|\\\\E?[\"#])(.*)?$\\R?"
			end:   "^(.*)(?<!\\\\)$"
			patterns: [
				match: ".+"
				captures: 0: patterns: [include: "$self"]
			]
			beginCaptures:
				0: name: "meta.function.titled-paragraph.man.macro.roff"
				1: name: "punctuation.definition.macro.roff"
				2: name: "entity.function.name.roff"
				3: patterns: [include: "#param-group"]
			endCaptures:
				0: name: "markup.heading.paragraph.roff"
				1: patterns: [include: "$self"]
		},{
			
			# .HP: Hanging paragraph (deprecated)
			name: "meta.deprecated.function.hanging-paragraph.man.macro.roff"
			begin: "^([.'])[ \\t]*((HP))(?=\\s|\\\\E?[\"#])"
			end:   "(?<!\\\\)(?=$)|(?=\\\\E?\")"
			beginCaptures:
				1: name: "punctuation.definition.macro.roff"
				2: name: "entity.function.name.roff"
				3: name: "invalid.deprecated.roff"
			patterns: [include: "#param-group"]
		},{
			
			# .MT/.ME: Hyperlink (GNU extension)
			name: "meta.function.mailto.hyperlink.man.macro.gnu.roff"
			begin: "^([.'])[ \\t]*(MT)(?=\\s|\\\\E?[\"#])\\s*"
			end:   "^([.'])[ \\t]*(ME)(?=\\s|\\\\E?[\"#])(.*)\\s*(\\\\E?[\"#].*)?$"
			beginCaptures:
				1: name: "punctuation.definition.macro.gnu.roff"
				2: name: "entity.function.name.gnu.roff"
			endCaptures:
				1: name: "punctuation.definition.macro.gnu.roff"
				2: name: "entity.function.name.gnu.roff"
				3: patterns: [include: "#param-group"]
				4: patterns: [include: "#escapes"]
			patterns: [include: "#underline-first"]
		},{
			
			# .UR/.UE: URL (GNU extension)
			name: "meta.function.hyperlink.man.macro.gnu.roff"
			begin: "^([.'])[ \\t]*(UR)(?=\\s|\\\\E?[\"#])\\s*"
			end:   "^([.'])[ \\t]*(UE)(?=\\s|\\\\E?[\"#])(.*)\\s*(\\\\E?[\"#].*)?$"
			beginCaptures:
				1: name: "punctuation.definition.macro.gnu.roff"
				2: name: "entity.function.name.gnu.roff"
			endCaptures:
				1: name: "punctuation.definition.macro.gnu.roff"
				2: name: "entity.function.name.gnu.roff"
				3: patterns: [include: "#param-group"]
				4: patterns: [include: "#escapes"]
			patterns: [include: "#underline-first"]
		},{
			
			# .SY: Command synopsis (GNU extension)
			name: "meta.command-synopsis.roff"
			begin: "^([.'])[ \\t]*(SY)(?=\\s|\\\\E?[\"#])"
			end:   "^([.'])[ \\t]*(YS)(?=\\s|\\\\E?[\"#])"
			beginCaptures:
				0: name: "meta.function.begin.synopsis.man.macro.gnu.roff"
				1: name: "punctuation.definition.macro.gnu.roff"
				2: name: "entity.function.name.gnu.roff"
			endCaptures:
				0: name: "meta.function.end.synopsis.man.macro.gnu.roff"
				1: name: "punctuation.definition.macro.gnu.roff"
				2: name: "entity.function.name.gnu.roff"
			patterns: [include: "#bold-first", {
				
				# .OP: Option description (GNU extension)
				name: "meta.function.option-description.man.macro.gnu.roff"
				begin: "^([.'])[ \\t]*(OP)(?=\\s)"
				end:   "(?<!\\\\)(?=\\R|$)|(?=\\\\E?\")"
				beginCaptures:
					1: name: "punctuation.definition.macro.gnu.roff"
					2: name: "entity.function.name.gnu.roff"
				patterns: [{
					name: "function-call.arguments.roff"
					begin: "\\G"
					end: '(?<![^\\\\]\\\\|^\\\\)(?=\\R|$)|(?=\\\\E?")'
					patterns: [
						{include: "#odd-bold"}
						{include: "#even-italic-after-bold"}
						{include: "#even-italic"}
						{include: "#bridge-escapes"}
					]
				}, include: "#escapes"]
			
			}, include: "$self"]
		},{

			# .B/.SB: Bold
			begin: "^([.'])[ \\t]*(S?B)(\\s*\\\\E?[#\"].*$)?(?=$|[ \\t]+|\\\\)"
			end:   "^(?=[.'])|(?=\\\\E?\")|(?!\\\\E?#)((\\S+[ \\t]*)(?<![^\\\\]\\\\)(?:\\R|$))"
			patterns: [include: "$self", {match: "\\S+", name: "markup.bold.roff"}]
			beginCaptures:
				0: name: "meta.function.man.macro.roff"
				1: name: "punctuation.definition.function.macro.roff"
				2: name: "entity.name.function.roff"
				3: patterns: [include: "#escapes-copymode"]
			endCaptures:
				1: name: "markup.bold.roff"
				2: patterns: [include: "#escapes"]
		},{
			
			# .I: Italic
			begin: "^([.'])[ \\t]*(I)(\\s*\\\\E?[#\"].*$)?(?=$|[ \\t]+|\\\\)"
			end:   "^(?=[.'])|(?=\\\\E?\")|(?!\\\\E?#)((\\S+[ \\t]*)(?<![^\\\\]\\\\)(?:\\R|$))"
			patterns: [include: "$self", {match: "\\S+", name: "markup.italic.roff"}]
			beginCaptures:
				0: name: "meta.function.man.macro.roff"
				1: name: "punctuation.definition.function.macro.roff"
				2: name: "entity.name.function.roff"
				3: patterns: [include: "#escapes-copymode"]
			endCaptures:
				1: name: "markup.italic.roff"
				2: patterns: [include: "#escapes"]
		
		}, include: "#alternating-fonts"]


	# Repeating/combined-font macros
	"alternating-fonts":
		patterns: [{
			
			# .BI: Bold + Italic
			begin: "^([.'])[ \\t]*(BI)(?=\\s)"
			end:   '(?<![^\\\\]\\\\|^\\\\)(?=\\R|$)|(?=\\\\")'
			beginCaptures:
				0: name: "meta.function.man.macro.roff"
				1: name: "punctuation.definition.function.macro.roff"
				2: name: "entity.name.function.roff"
			patterns: [
				{include: "#odd-bold"}
				{include: "#even-italic-after-bold"}
				{include: "#even-italic"}
				{include: "#bridge-escapes"}
			]
		},{
			
			# .BR: Bold + Roman
			begin: "^([.'])[ \\t]*(BR)(?=\\s)"
			end:   '(?<![^\\\\]\\\\|^\\\\)(?=\\R|$)|(?=\\\\")'
			beginCaptures:
				0: name: "meta.function.man.macro.roff"
				1: name: "punctuation.definition.function.macro.roff"
				2: name: "entity.name.function.roff"
			patterns: [
				{include: "#odd-bold"}
				{include: "#even-roman-after-bold"}
				{include: "#even-roman"}
				{include: "#bridge-escapes"}
			]
		},{
			
			# .IB: Italic + Bold
			begin: "^([.'])[ \\t]*(IB)(?=\\s)"
			end:   '(?<![^\\\\]\\\\|^\\\\)(?=\\R|$)|(?=\\\\")'
			beginCaptures:
				0: name: "meta.function.man.macro.roff"
				1: name: "punctuation.definition.function.macro.roff"
				2: name: "entity.name.function.roff"
			patterns: [
				{include: "#odd-italic"}
				{include: "#even-bold-after-italic"}
				{include: "#even-bold"}
				{include: "#bridge-escapes"}
			]
		},{
			
			# .IR: Italic + Roman
			begin: "^([.'])[ \\t]*(IR)(?=\\s)"
			end:   '(?<![^\\\\]\\\\|^\\\\)(?=\\R|$)|(?=\\\\")'
			beginCaptures:
				0: name: "meta.function.man.macro.roff"
				1: name: "punctuation.definition.function.macro.roff"
				2: name: "entity.name.function.roff"
			patterns: [
				{include: "#odd-italic"}
				{include: "#even-roman-after-italic"}
				{include: "#even-roman"}
				{include: "#bridge-escapes"}
			]
		},{
			
			# .RB: Roman + Bold
			begin: "^([.'])[ \\t]*(RB)(?=\\s)"
			end:   '(?<![^\\\\]\\\\|^\\\\)(?=\\R|$)|(?=\\\\")'
			beginCaptures:
				0: name: "meta.function.man.macro.roff"
				1: name: "punctuation.definition.function.macro.roff"
				2: name: "entity.name.function.roff"
			patterns: [
				{include: "#odd-roman"}
				{include: "#even-bold-after-roman"}
				{include: "#even-bold"}
				{include: "#bridge-escapes"}
			]
		},{
			
			# .RI: Roman + Italic
			begin: "^([.'])[ \\t]*(RI)(?=\\s)"
			end:   '(?<![^\\\\]\\\\|^\\\\)(?=\\R|$)|(?=\\\\")'
			beginCaptures:
				0: name: "meta.function.man.macro.roff"
				1: name: "punctuation.definition.function.macro.roff"
				2: name: "entity.name.function.roff"
			patterns: [
				{include: "#odd-roman"}
				{include: "#even-italic-after-roman"}
				{include: "#even-italic"}
				{include: "#bridge-escapes"}
			]
		}]
	

	"bridge-escapes":
		patterns: [{
			
			name: "constant.character.escape.newline.roff"
			begin: "[ \\t]+(\\\\)$\\R?"
			end:   "^"
			beginCaptures:
				1: name: "punctuation.definition.escape.roff"
		},{
			
			name: "constant.character.escape.newline.roff"
			begin: "(\\\\)$\\R?"
			end:   "^[ \\t]*"
			beginCaptures:
				1: name: "punctuation.definition.escape.roff"
		}]


	"odd-bold":
		patterns: [{
			name: "markup.bold.roff"
			begin: '[ \\t]+(")'
			end:   '(")[ \\t]*|(?=\\\\E?")|(?<![^\\\\]\\\\|^\\\\)(?=\\R|$)'
			beginCaptures: 1: name: "punctuation.definition.string.begin.roff"
			endCaptures:   1: name: "punctuation.definition.string.end.roff"
			patterns: [{
				match: '((?:[^"\\\\]|""|\\\\(?!E?").)+)(?!$)'
				captures: 1: patterns: [include: "#string-escapes"]
			}, include: "#string-escapes"]
		},{
			name: "markup.bold.roff"
			begin: '[ \\t]+(\\\\$\\R?)'
			end:   '(?<!^)[ \\t]+|(?=\\\\E?")|(?<!\\\\)(?=\\R|$)'
			beginCaptures: 1: patterns: [include: "#escapes"]
			patterns: [include: "#escapes", {
				begin: "^[ \\t]+"
				end: "(?=\\S)|(?<!\\\\)(?:$|\\R)"
			}]
		},{
			name: "markup.bold.roff"
			begin: '[ \\t]+(?!")((?:[^\\s"\\\\]|\\\\(?!E?").)+)'
			end:   '[ \\t]+|(?<![^\\\\]\\\\|^\\\\)(?=\\R|$)|(?=\\\\E?")'
			beginCaptures: 1: patterns: [include: "#escapes"]
			patterns: [include: "#escapes"]
		}]


	"odd-italic":
		patterns: [{
			name: "markup.italic.roff"
			begin: '[ \\t]+(")'
			end:   '(")[ \\t]*|(?=\\\\E?")|(?<![^\\\\]\\\\|^\\\\)(?=\\R|$)'
			beginCaptures: 1: name: "punctuation.definition.string.begin.roff"
			endCaptures:   1: name: "punctuation.definition.string.end.roff"
			patterns: [{
				match: '((?:[^"\\\\]|""|\\\\(?!E?").)+)(?!$)'
				captures: 1: patterns: [include: "#string-escapes"]
			}, include: "#string-escapes"]
		},{
			name: "markup.italic.roff"
			begin: '[ \\t]+(\\\\$\\R?)'
			end:   '(?<!^)[ \\t]+|(?=\\\\E?")|(?<!\\\\)(?=\\R|$)'
			beginCaptures: 1: patterns: [include: "#escapes"]
			patterns: [include: "#escapes", {
				begin: "^[ \\t]+"
				end: "(?=\\S)|(?<!\\\\)(?:$|\\R)"
			}]
		},{
			name: "markup.italic.roff"
			begin: '[ \\t]+(?!")((?:[^\\s"\\\\]|\\\\(?!E?").)+)'
			end:   '[ \\t]+|(?<![^\\\\]\\\\|^\\\\)(?=\\R|$)|(?=\\\\E?")'
			beginCaptures: 1: patterns: [include: "#escapes"]
			patterns: [include: "#escapes"]
		}]


	"odd-roman":
		patterns: [{
			name: "markup.plain.roff"
			begin: '[ \\t]+(")'
			end:   '(")[ \\t]*|(?=\\\\E?")|(?<![^\\\\]\\\\|^\\\\)(?=\\R|$)'
			beginCaptures: 1: name: "punctuation.definition.string.begin.roff"
			endCaptures:   1: name: "punctuation.definition.string.end.roff"
			patterns: [{
				match: '((?:[^"\\\\]|""|\\\\(?!E?").)+)(?!$)'
				captures: 1: patterns: [include: "#string-escapes"]
			}, include: "#string-escapes"]
		},{
			name: "markup.plain.roff"
			begin: '[ \\t]+(\\\\$\\R?)'
			end:   '(?<!^)[ \\t]+|(?=\\\\E?")|(?<!\\\\)(?=\\R|$)'
			beginCaptures: 1: patterns: [include: "#escapes"]
			patterns: [include: "#escapes", {
				begin: "^[ \\t]+"
				end: "(?=\\S)|(?<!\\\\)(?:$|\\R)"
			}]
		},{
			name: "markup.plain.roff"
			begin: '[ \\t]+(?!")((?:[^\\s"\\\\]|\\\\(?!E?").)+)'
			end:   '[ \\t]+|(?<![^\\\\]\\\\|^\\\\)(?=\\R|$)|(?=\\\\E?")'
			beginCaptures: 1: patterns: [include: "#escapes"]
			patterns: [include: "#escapes"]
		}]



	"even-bold":
		patterns: [
			name: "markup.bold.roff"
			begin: '(?<=^|\\s|")(?!"|\\\\E?")((?:[^\\s"\\\\]|\\\\(?!E?").)+)'
			end:   '(?=[ \\t])|(?<![^\\\\]\\\\|^\\\\)(?=\\R|$)|(?=\\\\E?")'
			beginCaptures: 1: patterns: [include: "#escapes"]
			patterns: [include: "#escapes"]
		]

	"even-italic":
		patterns: [
			name: "markup.italic.roff"
			begin: '(?<=^|\\s|")(?!"|\\\\E?")((?:[^\\s"\\\\]|\\\\(?!E?").)+)'
			end:   '(?=[ \\t])|(?<![^\\\\]\\\\|^\\\\)(?=\\R|$)|(?=\\\\E?")'
			beginCaptures: 1: patterns: [include: "#escapes"]
			patterns: [include: "#escapes"]
		]
	
	"even-roman":
		patterns: [
			name: "markup.plain.roff"
			begin: '(?<=^|\\s|")(?!"|\\\\E?")((?:[^\\s"\\\\]|\\\\(?!E?").)+)'
			end:   '(?=[ \\t])|(?<![^\\\\]\\\\|^\\\\)(?=\\R|$)|(?=\\\\E?")'
			beginCaptures: 1: patterns: [include: "#escapes"]
			patterns: [include: "#escapes"]
		]
	
	
	"even-bold-after-italic":
		patterns: [{
			contentName: "markup.bold.roff"
			begin: '(")'
			end:   '(("))([^"\\s]+[ \\t]*)?|(?=\\\\E?")|(?<![^\\\\]\\\\|^\\\\)(?=\\R|$)'
			beginCaptures:
				0: name: "markup.bold.roff"
				1: name: "punctuation.definition.string.begin.roff"
			endCaptures:
				1: name: "markup.bold.roff"
				2: name: "punctuation.definition.string.end.roff"
				3: name: "markup.italic.roff"
			patterns: [{
				match: '((?:[^"\\\\]|""|\\\\(?!E?").)+)(?!$)'
				captures: 1: patterns: [include: "#string-escapes"]
			}, include: "#string-escapes"]
		}]
	
	"even-bold-after-roman":
		patterns: [{
			contentName: "markup.bold.roff"
			begin: '(")'
			end:   '(("))([^"\\s]+[ \\t]*)?|(?=\\\\E?")|(?<![^\\\\]\\\\|^\\\\)(?=\\R|$)'
			beginCaptures:
				0: name: "markup.bold.roff"
				1: name: "punctuation.definition.string.begin.roff"
			endCaptures:
				1: name: "markup.bold.roff"
				2: name: "punctuation.definition.string.end.roff"
				3: name: "markup.plain.roff"
			patterns: [{
				match: '((?:[^"\\\\]|""|\\\\(?!E?").)+)(?!$)'
				captures: 1: patterns: [include: "#string-escapes"]
			}, include: "#string-escapes"]
		}]
	
	
	"even-italic-after-bold":
		patterns: [{
			contentName: "markup.italic.roff"
			begin: '(")'
			end:   '(("))([^"\\s]+[ \\t]*)?|(?=\\\\E?")|(?<![^\\\\]\\\\|^\\\\)(?=\\R|$)'
			beginCaptures:
				0: name: "markup.italic.roff"
				1: name: "punctuation.definition.string.begin.roff"
			endCaptures:
				1: name: "markup.italic.roff"
				2: name: "punctuation.definition.string.end.roff"
				3: name: "markup.bold.roff"
			patterns: [{
				match: '((?:[^"\\\\]|""|\\\\(?!E?").)+)(?!$)'
				captures: 1: patterns: [include: "#string-escapes"]
			}, include: "#string-escapes"]
		}]
	
	"even-italic-after-roman":
		patterns: [{
			contentName: "markup.italic.roff"
			begin: '(")'
			end:   '(("))([^"\\s]+[ \\t]*)?|(?=\\\\E?")|(?<![^\\\\]\\\\|^\\\\)(?=\\R|$)'
			beginCaptures:
				0: name: "markup.italic.roff"
				1: name: "punctuation.definition.string.begin.roff"
			endCaptures:
				1: name: "markup.italic.roff"
				2: name: "punctuation.definition.string.end.roff"
				3: name: "markup.plain.roff"
			patterns: [{
				match: '((?:[^"\\\\]|""|\\\\(?!E?").)+)(?!$)'
				captures: 1: patterns: [include: "#string-escapes"]
			}, include: "#string-escapes"]
		}]


	"even-roman-after-bold":
		patterns: [{
			contentName: "markup.plain.roff"
			begin: '(")'
			end:   '(("))([^"\\s]+[ \\t]*)?|(?=\\\\E?")|(?<![^\\\\]\\\\|^\\\\)(?=\\R|$)'
			beginCaptures:
				0: name: "markup.plain.roff"
				1: name: "punctuation.definition.string.begin.roff"
			endCaptures:
				1: name: "markup.plain.roff"
				2: name: "punctuation.definition.string.end.roff"
				3: name: "markup.bold.roff"
			patterns: [{
				match: '((?:[^"\\\\]|""|\\\\(?!E?").)+)(?!$)'
				captures: 1: patterns: [include: "#string-escapes"]
			}, include: "#string-escapes"]
		}]

	"even-roman-after-italic":
		patterns: [{
			contentName: "markup.plain.roff"
			begin: '(")'
			end:   '(("))([^"\\s]+[ \\t]*)?|(?=\\\\E?")|(?<![^\\\\]\\\\|^\\\\)(?=\\R|$)'
			beginCaptures:
				0: name: "markup.plain.roff"
				1: name: "punctuation.definition.string.begin.roff"
			endCaptures:
				1: name: "markup.plain.roff"
				2: name: "punctuation.definition.string.end.roff"
				3: name: "markup.italic.roff"
			patterns: [{
				match: '((?:[^"\\\\]|""|\\\\(?!E?").)+)(?!$)'
				captures: 1: patterns: [include: "#string-escapes"]
			}, include: "#string-escapes"]
		}]



	# Embolden first argument only
	"bold-first":
		patterns: [{
			
			# Unquoted string
			name: "markup.bold.roff"
			begin: "\\G[ \\t]*(?!\")(?=(?:[^\\s\\\\]|\\\\(?!E?\").)+)"
			end:   "(?<![^\\\\]\\\\|^\\\\)(?=\\s|$)|(?=\\\\E?\")"
			patterns: [include: "#escapes"]
		},{
		
			# Null argument
			name: "markup.bold.roff"
			match: '(")(")'
			captures:
				0: {name: "string.quoted.double.empty.roff"}
				1: {name: "punctuation.definition.string.begin.roff"}
				2: {name: "punctuation.definition.string.end.roff"}
		},{
			# Quoted string
			name: "markup.bold.roff"
			contentName: "string.quoted.double.roff"
			begin: '\\G[ \\t]*(")'
			end:   '((?:"")*)"(?!")|(?<!\\\\)(?:$|\\R)|(?=\\\\E?")'
			beginCaptures:
				0: name: "string.quoted.double.roff"
				1: name: "punctuation.definition.string.begin.roff"
			endCaptures:
				0: name: "punctuation.definition.string.end.roff"
				1: name: "markup.bold.roff", patterns: [include: "#string-escapes"]
			patterns: [include: "#string-escapes"]
		}
		{include: "#escapes"}
		{include: "#string"}]
	
	
	# Italicise first argument only
	"italic-first":
		patterns: [{
			
			# Unquoted string
			name: "markup.italic.roff"
			begin: "\\G[ \\t]*(?!\")(?=(?:[^\\s\\\\]|\\\\(?!E?\").)+)"
			end:   "(?<![^\\\\]\\\\|^\\\\)(?=\\s|$)|(?=\\\\E?\")"
			patterns: [include: "#escapes"]
		},{
		
			# Null argument
			name: "markup.italic.roff"
			match: '(")(")'
			captures:
				0: {name: "string.quoted.double.empty.roff"}
				1: {name: "punctuation.definition.string.begin.roff"}
				2: {name: "punctuation.definition.string.end.roff"}
		},{
			# Quoted string
			name: "markup.italic.roff"
			contentName: "string.quoted.double.roff"
			begin: '\\G[ \\t]*(")'
			end:   '((?:"")*)"(?!")|(?<!\\\\)(?:$|\\R)|(?=\\\\E?")'
			beginCaptures:
				0: name: "string.quoted.double.roff"
				1: name: "punctuation.definition.string.begin.roff"
			endCaptures:
				0: name: "punctuation.definition.string.end.roff"
				1: name: "markup.italic.roff", patterns: [include: "#string-escapes"]
			patterns: [include: "#string-escapes"]
		}
		{include: "#escapes"}
		{include: "#string"}]



	# Embolden and italicise first argument only
	"bold-italic-first":
		patterns: [{
			
			# Unquoted string
			name: "markup.bold.italic.roff"
			begin: "\\G[ \\t]*(?!\")(?=(?:[^\\s\\\\]|\\\\(?!E?\").)+)"
			end:   "(?<![^\\\\]\\\\|^\\\\)(?=\\s|$)|(?=\\\\E?\")"
			patterns: [include: "#escapes"]
		},{
		
			# Null argument
			name: "markup.bold.italic.roff"
			match: '(")(")'
			captures:
				0: {name: "string.quoted.double.empty.roff"}
				1: {name: "punctuation.definition.string.begin.roff"}
				2: {name: "punctuation.definition.string.end.roff"}
		},{
			# Quoted string
			name: "markup.bold.italic.roff"
			contentName: "string.quoted.double.roff"
			begin: '\\G[ \\t]*(")'
			end:   '((?:"")*)"(?!")|(?<!\\\\)(?:$|\\R)|(?=\\\\E?")'
			beginCaptures:
				0: name: "string.quoted.double.roff"
				1: name: "punctuation.definition.string.begin.roff"
			endCaptures:
				0: name: "punctuation.definition.string.end.roff"
				1: name: "markup.bold.italic.roff", patterns: [include: "#string-escapes"]
			patterns: [include: "#string-escapes"]
		}
		{include: "#escapes"}
		{include: "#string"}]



	# Embolden a word
	"bold-word":
		name: "markup.bold.roff"
		match: "\\S+?(?=\\\\|$|\\s)"


	# Italicise a word
	"italic-word":
		match: "\\S+?(?=\\\\|$|\\s)"
		name: "markup.italic.roff"


	# Embolden and italicise a word
	"bold-italic-word":
		name: "markup.bold.italic.roff"
		match: "\\S+?(?=\\\\|$|\\s)"


	# Render a word as raw/verbatim text
	"monospace-word":
		name: "markup.raw.monospaced.roff"
		match: "\\S+?(?=\\\\|$|\\s)"



	# Underline first argument only
	"underline-first":
		patterns: [{
			
			# Unquoted string
			name: "string.other.link.roff"
			contentName: "markup.underline.roff"
			begin: "\\G[ \\t]*(?!\")(?=(?:[^\\s\\\\]|\\\\(?!E?\").)+)"
			end:   "(?<![^\\\\]\\\\|^\\\\)(?=\\s|$)|(?=\\\\E?\")"
			patterns: [include: "#escapes"]
		},{
		
			# Null argument
			name: "string.quoted.double.empty.roff"
			match: '(")(")'
			beginCaptures: 0: name: "punctuation.definition.string.begin.roff"
			endCaptures:   0: name: "punctuation.definition.string.end.roff"
		},{
			# Quoted string
			name: "string.other.link.roff"
			contentName: "markup.underline.roff"
			begin: '\\G[ \\t]*(")'
			end:   '((?:"")*)"(?!")|(?<!\\\\)$|(?=\\\\E?\")'
			beginCaptures: 1: name: "punctuation.definition.string.begin.roff"
			endCaptures:
				0: name: "punctuation.definition.string.end.roff"
				1: name: "markup.underline.roff", patterns: [include: "#string-escapes"]
			patterns: [include: "#string-escapes"]
		}
		{include: "#escapes"}
		{include: "#string"}]



	# Preprocessors for preparing Troff documents
	preprocessors:
		patterns: [{
			
			# .TS/.TE: Tbl
			begin: "^([.'])[ \\t]*(TS)(?=$|\\s|\\\\E?[\"#])(.*)"
			end:   "^([.'])[ \\t]*(TE)(?=$|\\s|\\\\E?[\"#])"
			contentName: "markup.other.table.preprocessor.tbl.roff"
			patterns: [include: "#tbl"]
			beginCaptures:
				0: name: "meta.function.begin.table.section.macro.roff"
				1: name: "punctuation.definition.macro.roff"
				2: name: "entity.function.name.roff"
				3: patterns: [include: "#escapes"]
			endCaptures:
				0: name: "meta.function.end.table.section.macro.roff"
				1: name: "punctuation.definition.macro.roff"
				2: name: "entity.name.function.roff"
		},{
			
			# .EQ/.EN: Eqn
			begin: "^([.'])[ \\t]*(EQ)(?=$|\\s|\\\\E?[\"#])[ \\t]*([LIC]\\b)?\\s*([^\\\\\"]+|\\\\[^\"])*(\\\\E?\".*)?$"
			end:   "^([.'])[ \\t]*(EN)(?=$|\\s|\\\\E?[\"#])"
			contentName: "markup.other.math.preprocessor.eqn.roff"
			patterns: [include: "#eqn"]
			beginCaptures:
				0: name: "meta.function.begin.math.section.macro.roff"
				1: name: "punctuation.definition.macro.roff"
				2: name: "entity.function.name.roff"
				3: name: "constant.language.alignment-mode.eqn.roff"
				4: name: "string.unquoted.equation-label.eqn.roff"
				5: patterns: [include: "#escapes"]
			endCaptures:
				0: name: "meta.function.end.math.section.macro.roff"
				1: name: "punctuation.definition.macro.roff"
				2: name: "entity.name.function.roff"
		
		},{
			# .[/.]: Refer
			begin: "^([.'])[ \\t]*(\\[)\\s*([-$'\\w.\\\\]*?)\\s*(\\\\E?[\"#].*)?$"
			end:   "^([.'])[ \\t]*(\\])\\s*([-$'\\w.\\\\]*?)(?=\\s|$|\\\\E?\")"
			contentName: "meta.citation.roff"
			patterns: [{
				
				# First line: Flags + Keywords
				begin: "\\G"
				end: "$|(?=\\\\E?[#\"])"
				patterns: [{
					name: "constant.character.flags.refer.gnu.roff"
					match: "^[#\\[\\]]+"
				}, include: "#params"]
			
			}, include: "#refer"]
			beginCaptures:
				1: name: "punctuation.definition.macro.roff"
				2: name: "punctuation.section.function.begin.roff"
				3: name: "string.unquoted.opening-text.refer.roff", patterns: [include: "#escapes"]
				4: patterns: [include: "#escapes"]
			endCaptures:
				1: name: "punctuation.definition.macro.roff"
				2: name: "punctuation.section.function.end.roff"
				3: name: "string.unquoted.closing-text.refer.roff", patterns: [include: "#escapes"]
		},{
			# Perl (GNU)
			begin: "^([.'])[ \\t]*(Perl)[ \\t]+(begin|start)(?=$|\\s|\\\\E?[\"#])(.*)$"
			end:   "^([.'])[ \\t]*(Perl)[ \\t]+(end|stop)(?=$|\\s|\\\\E?[\"#])"
			contentName: "source.embedded.perl.gnu.roff"
			patterns: [include: "source.perl"]
			beginCaptures:
				0: name: "meta.function.begin.perl.macro.gnu.roff"
				1: name: "punctuation.definition.macro.roff"
				2: name: "entity.function.name.roff"
				3: name: "constant.language.embedding-control.roff"
				4: patterns: [include: "#escapes"]
			endCaptures:
				0: name: "meta.function.end.perl.macro.gnu.roff"
				1: name: "punctuation.definition.macro.roff"
				2: name: "entity.function.name.roff"
				3: name: "constant.language.embedding-control.roff"
		},{
			# LilyPond (GNU)
			begin: "^([.'])[ \\t]*(lilypond)[ \\t]+(begin|start)(?=$|\\s|\\\\E?[\"#])(.*)$"
			end:   "^([.'])[ \\t]*(lilypond)[ \\t]+(end|stop)(?=$|\\s|\\\\E?[\"#])"
			contentName: "source.embedded.lilypond.gnu.roff"
			beginCaptures:
				0: name: "meta.function.begin.lilypond.macro.gnu.roff"
				1: name: "punctuation.definition.macro.roff"
				2: name: "entity.function.name.roff"
				3: name: "constant.language.embedding-control.roff"
				4: patterns: [include: "#escapes"]
			endCaptures:
				0: name: "meta.function.end.lilypond.macro.gnu.roff"
				1: name: "punctuation.definition.macro.roff"
				2: name: "entity.function.name.roff"
				3: name: "constant.language.embedding-control.roff"
			patterns: [include: "source.lilypond"]
		},{
			# Pinyin (GNU)
			begin: "^([.'])[ \\t]*(pinyin)[ \\t]+(begin|start)(?=$|\\s|\\\\E?[\"#])(.*)$"
			end:   "^([.'])[ \\t]*(pinyin)[ \\t]+(end|stop)(?=$|\\s|\\\\E?[\"#])"
			contentName: "meta.pinyin.gnu.roff"
			patterns: [include: "#main"]
			beginCaptures:
				0: name: "meta.function.begin.pinyin.macro.gnu.roff"
				1: name: "punctuation.definition.macro.roff"
				2: name: "entity.function.name.roff"
				3: name: "constant.language.embedding-control.roff"
				4: patterns: [include: "#escapes"]
			endCaptures:
				0: name: "meta.function.end.pinyin.macro.gnu.roff"
				1: name: "punctuation.definition.macro.roff"
				2: name: "entity.function.name.roff"
				3: name: "constant.language.embedding-control.roff"
		}
		{include: "source.pic#tags"}
		{include: "source.ideal#tags"}
		{include: "source.gremlin"}]


	# Equation preprocessor
	eqn:
		patterns: [{
			
			# Greek letters
			name: "constant.language.greek-letter.eqn.roff"
			match: """(?x)\\b
				(DELTA|GAMMA|LAMBDA|OMEGA|PHI|PI|PSI|SIGMA|THETA|UPSILON|XI|alpha|beta|chi
				|delta|epsilon|eta|gamma|iota|kappa|lambda|mu|nu|omega|omicron|phi|pi|psi
				|rho|sigma|tau|theta|upsilon|xi|zeta)\\b"""
		},{
			# Math functions
			name: "constant.language.math-function.eqn.roff"
			match: "\\b(and|arc|cos|cosh|det|exp|for|if|Im|lim|ln|log|max|min|Re|sin|sinh|tan|tanh)\\b"
		},{
			# Math symbols
			name: "constant.character.math-symbol.eqn.roff"
			match: """(?x)
				(?:[><=!]=|\\+-|->|<-|<<|>>|\\.{3}|,\\.+,|[-+=](?!\\d)|[*/<>])
				|\\b(?:approx|cdot|ceiling|del|grad|half|inf|inter|int|floor
				|nothing|partial|prime|prod|sum|times|union)\\b"""
		},{
			# Braced text
			begin: "{"
			end:   "}|(?=\\.EN)"
			beginCaptures: 0: name: "punctuation.section.bracket.curly.begin.eqn.roff"
			endCaptures:   0: name: "punctuation.section.bracket.curly.end.eqn.roff"
			patterns: [include: "#eqn"]
		},{
			# Punctuation
			match: "(~|\\^)|(,)"
			captures:
				1: name: "keyword.operator.spacing.eqn.roff"
				2: name: "punctuation.separator.delimiter.comma.eqn.roff"
		},{
			# Definition
			begin: "\\b([nts]?define)\\s*(\\S+)\\s*(\\S)"
			end:   "((?:(?!\\3).)*+)(\\3)|(?=\\.EN)"
			beginCaptures:
				1: name: "storage.type.function.definition.eqn.roff"
				2: name: "entity.name.function.eqn.roff"
				3: name: "punctuation.section.definition.begin.eqn.roff"
			endCaptures:
				1: patterns: [include: "#eqn"]
				2: name: "punctuation.section.definition.end.eqn.roff"
			patterns: [
				match: "(\\{)([^}]*)(\\})"
				captures:
					1: name: "punctuation.section.bracket.curly.begin.eqn.roff"
					2: patterns: [{include: "#eqn"}, {include: "#main"}]
					3: name: "punctuation.section.bracket.curly.end.eqn.roff"
				{include: "#eqn"}
				{include: "#main"}
			]
		},{
			# GNU Eqn: Conditional
			begin: "\\b(ifdef)\\s*(\\S+)\\s*(\\S)"
			end:   "((?:(?!\\3).)*+)(\\3)|(?=\\.EN)"
			beginCaptures:
				1: name: "keyword.control.flow.if-defined.eqn.roff"
				2: name: "entity.name.function.eqn.roff"
				3: name: "punctuation.section.definition.begin.eqn.roff"
			endCaptures:
				1: patterns: [include: "#eqn"]
				2: name: "punctuation.section.definition.end.eqn.roff"
			patterns: [
				match: "(\\{)([^}]*)(\\})"
				captures:
					1: name: "punctuation.section.bracket.curly.begin.eqn.roff"
					2: patterns: [{include: "#eqn"}, {include: "#main"}]
					3: name: "punctuation.section.bracket.curly.end.eqn.roff"
				{include: "#eqn"}
				{include: "#main"}
			]
		},{
			# Eqn keywords
			name: "keyword.language.eqn.roff"
			match: """(?x)\\b
				(above|back|bar|bold|ccol|col|cpile|delim|dot|dotdot|down|dyad|fat|font|from
				|fwd|gfont|gsize|hat|italic|lcol|left|lineup|lpile|mark|matrix|over|pile
				|rcol|right|roman|rpile|size|sqrt|sub|sup|tilde|to|under|up|vec)\\b"""
		},{
			# GNU Eqn: Keywords
			name: "keyword.language.eqn.gnu.roff"
			match: """(?x)\\b
				(accent|big|chartype|smallover|type|vcenter|uaccent|split|nosplit
				|opprime|special|include|ifdef|undef|g[rb]font|space)\\b"""
		},{
			
			# GNU Eqn: Character names
			name: "constant.language.eqn.gnu.roff"
			match: """(?x)\\b
				(Alpha|Beta|Chi|Delta|Epsilon|Eta|Gamma|Iota|Kappa|Lambda|Mu|Nu
				|Omega|Omicron|Phi|Pi|Psi|Rho|Sigma|Tau|Theta|Upsilon|Xi|Zeta
				|ldots|dollar)\\b"""
		},{
			
			# GNU Eqn: Set MathML variables
			name: "meta.set-variable.eqn.gnu.roff"
			match: """(?x)\\b(set)[ \\t]+
				(accent_width|axis_height|baseline_sep|big_op_spacing[1-5]|body_depth|body_height|column_sep
				|default_rule_thickness|delimiter_factor|delimiter_shortfall|denom[12]|draw_lines|fat_offset
				|matrix_side_sep|medium_space|minimum_size|nroff|null_delimiter_space|num[12]|over_hang
				|script_space|shift_down|su[bp]_drop|sub[12]|sup[1-3]|thick_space|thin_space|x_height)\\b"""
			captures:
				1: name: "storage.type.var.eqn.roff"
				2: name: "variable.other.mathml.eqn.roff"
		},{
			# Algebraic bareword string
			name: "string.unquoted.parameter.eqn.roff"
			match: "(?![\\d\\\\\"])[^-,!.{}\\[\\]*/^+<=>~\\s\"]+"
		},{
			# Boolean keywords
			match: "(?<=delim)\\s*(?:(on)|(off))\\b"
			captures:
				1: name: "constant.language.boolean.logical.true.eqn.roff"
				2: name: "constant.language.boolean.logical.false.eqn.roff"
		}
		{include: "#escapes"}
		{include: "#number"}
		{include: "#string"}]


	# Table preprocessor
	tbl:
		patterns: [{
			
			# Options/Formats
			name: "meta.function-call.arguments.tbl.roff"
			begin: "\\G|^((\\.)T&)[ \\t]*$"
			end:   "(\\.)$\\R?|^(?=[.'][ \\t]*TE(?=\\s))"
			beginCaptures:
				1: name: "entity.function.name.roff"
				2: name: "punctuation.definition.macro.roff"
			endCaptures:
				1: patterns: [include: "#params"]
				2: name: "punctuation.terminator.section.tbl.roff"
			patterns: [{
				
				# Not preprocessor source; abandon ship
				begin: "^(?=\\.)"
				end: "^(?=[.'][ \\t]*TE(?=\\s|\\\\E?[\"#]))"
				patterns: [include: "$self"]},{
				
				
				# Global options
				match: "^(.+)(;)$"
				captures:
					1: patterns: [
						{match: ",", name: "punctuation.separator.comma.tbl.roff"}
						{match: "\\b(center|centre|expand|box|allbox|doublebox)\\b", name: "constant.language.$1.tbl.roff"}
						{match: "\\b((tab|linesize|delim)(\\()([^\\)\\s]*)(\\)))"
						captures:
							1: name: "constant.language.$2.tbl.roff"
							3: name: "punctuation.definition.arguments.begin.tbl.roff"
							4: patterns: [include: "#params"]
							5: name: "punctuation.definition.arguments.end.tbl.roff"}]
					2: name: "punctuation.terminator.line.tbl.roff"}
				
				# Field specifiers
				{match: "[ABCEFILNPRSTUVWZabcefilnprstuvwz^]", name: "constant.language.key-letter.tbl.roff"}
				{match: "[|_=]",     name: "punctuation.keyword.tbl.roff"}
				{match: "[-+]?\\d+", name: "constant.numeric.tbl.roff"}
				{match: "\\.",       name: "punctuation.delimiter.period.full-stop.tbl.roff"}
				{match: ",",         name: "punctuation.separator.comma.tbl.roff"}
				{include: "#params"}
			]
		},{
			
			# Horizontal line indicators
			name: "punctuation.keyword.tbl.roff"
			match: "^\\s*([=_]|\\\\_)\\s*$"
		},{
			
			# Column-filling repeated character sequence
			name: "constant.character.escape.repeat.tbl.roff"
			match: "(?<!\\\\)((\\\\)R)(.)"
			captures:
				1: name: "keyword.operator.tbl.roff"
				2: name: "punctuation.definition.escape.roff"
				3: name: "string.unquoted.tbl.roff"
		},{
			
			# Vertically-spanned item indicator
			name: "constant.character.escape.vertical-span.tbl.roff"
			match: "(\\\\)\\^"
			captures:
				0: name: "keyword.operator.tbl.roff"
				1: name: "punctuation.definition.escape.roff"
		},{
			
			# Multiline cell content
			name: "meta.multiline-cell.tbl.roff"
			contentName: "string.unquoted.tbl.roff"
			begin: "T(\\{)"
			end:  "^T(\\})|^(?=[.'][ \\t]*TE\\b)"
			patterns: [include: "$self"]
			beginCaptures:
				0: name: "keyword.operator.section.begin.tbl.roff"
				1: name: "punctuation.embedded.tbl.roff"
			endCaptures:
				0: name: "keyword.operator.section.end.tbl.roff"
				1: name: "punctuation.embedded.tbl.roff"
			
		}, include: "$self"]


	# Bibliographic references
	refer:
		patterns: [{
			
			# Comment
			name: "comment.line.refer.roff"
			begin: "#"
			end:   "$"
			beginCaptures:
				0: name: "punctuation.definition.comment.refer.roff"
		},{
			
			# Names of each author, concatenated with the string specified by `join-authors`
			name: "variable.other.readonly.author-names.refer.roff"
			match: "@"
		},{
			
			# %KEY Value
			name: "meta.structure.dictionary.refer.roff"
			contentName: "meta.structure.dictionary.value.refer.roff"
			begin: "^([.'])?\\s*(%)([A-Z])(?=\\s)"
			end:   "(?<!\\\\)$"
			patterns: [{
				name: "string.unquoted.refer.roff"
				begin: "\\G"
				end:   "(?<!\\\\)$"
				patterns: [{
					
					# Make sure "special" characters don't trigger refer patterns
					name: "meta.symbol.refer.roff"
					match: "[-+'\"<>\\].*\\[~!&?:]"
					
				}, include: "#refer"]
			}, include: "#escapes"]
			beginCaptures:
				1: name: "punctuation.definition.macro.mdoc.roff"
				2: name: "punctuation.definition.percentage-sign.refer.roff"
				3: name: "variable.other.readonly.key-letter.refer.roff"
		},{
			
			# Literal/single-quoted string
			name: "string.quoted.single.refer.roff"
			begin: "'"
			end:   "'"
			beginCaptures: 0: name: "punctuation.definition.string.begin.roff"
			endCaptures:   0: name: "punctuation.definition.string.end.roff"
		},{
			
			# Formatted/placeholder value
			name: "variable.other.readonly.formatted.refer.roff"
			match: "(%+)[\\daiA-Z]"
			captures:
				1: name: "punctuation.definition.percentage-sign.refer.roff"
		},{
			# Label expressions
			name: "keyword.operator.label-expression.refer.roff"
			match: """(?x)
				(?<=\\S)(?:\\*|[-+]\\d+|(\\.)(?:[-+]?y|[lucran]))(?=\\s|$) |
				(?<=\\S)[~!&?:](?=\\S)"""
			captures:
				1: name: "punctuation.separator.period.full-stop.refer.roff"
		},{
			
			# Angle brackets
			begin: "<"
			end:   ">|^(?=\\.\\])"
			beginCaptures: 0: name: "punctuation.bracket.angle.refer.roff"
			endCaptures:   0: name: "punctuation.bracket.angle.refer.roff"
			patterns: [include: "#refer"]
		},{
			
			# Round brackets
			begin: "\\("
			end:   "\\)|^(?=\\.\\])"
			beginCaptures: 0: name: "punctuation.bracket.round.refer.roff"
			endCaptures:   0: name: "punctuation.bracket.round.refer.roff"
			patterns: [include: "#refer"]
		},{
			
			# Negatable commands
			name: "keyword.operator.negatable.refer.roff"
			match: """(?x)\\b
				(?:no-)?
				(?:abbreviate|abbreviate-label-ranges|accumulate|annotate|compatible|date-as-label
				|default-database|discard|et-al|label-in-reference|label-in-text|move-punctuation
				|reverse|search-ignore|search-truncate|short-label|sort|sort-adjacent-labels)\\b"""
			captures:
				0: name: "entity.function.name.refer.roff"
		},{
			
			# Non-negatable commands
			name: "keyword.operator.refer.roff"
			match: "\\b(articles|bibliography|capitalize|join-authors|label|separate-label-second-parts)\\b"
			captures:
				0: name: "entity.function.name.refer.roff" 
		},{
			
			# Commands that take filenames as arguments
			begin: "^\\s*\\b(database|include)\\b"
			end: "(?<!\\\\)$"
			beginCaptures:
				0: name: "keyword.operator.refer.roff"
				1: name: "entity.function.name.refer.roff"
			patterns: [
				{include: "#escapes"}
				
				# Add underlines to filenames for themes supporting them
				name: "string.other.link.filename.refer.roff"
				match: "((?:[^\\\\\\s]|\\\\(?!E?\").)+)"
				captures:
					0: name: "markup.link.underline.refer.roff"
					1: patterns: [include: "#escapes"]
			]
		}
		{include: "#string"}
		{include: "#escapes"}]
