#compdef se
# shellcheck shell=bash disable=SC1087,SC1112,SC2154,SC2168

local state line ret

# Check if we've already seen a command line option with a value demarcated by a space of an equals.
_se_has_option(){
	local option word

	for word in "${words[@]}"; do
		for option in "$@"; do
			if [[ ${word} == "${option}" || ${word} == "${option}="* ]]; then
				return 0
			fi
		done
	done

	return 1
}

_arguments -C \
	'(- :)'{-h,--help}'[Show this help message and exit.]' \
	'(--color -p --plain)'--color'[Print output in color, even when not connected to an interactive terminal, but not if the NO_COLOR environmental variable is set.]' \
	'(--color -p --plain)'{-p,--plain}'[Print plain text output, without tables, colors, or other formatting. For tabular output but without colors, set the NO_COLOR environmental variable to a non-empty value instead of this option.]' \
	'(- :)'{-v,--version}'[Print version number and exit.]' \
	'(-): :->cmds' \
	'(-)*:: :->args'

ret=$?

case $state in
	cmds)
		_values "se command" \
			"add-file[Add a Standard Ebooks template file and any accompanying CSS.]" \
			"british2american[Try to convert British quote style to American quote style. Quotes must already be typogrified using se typogrify. This script isn’t perfect; proofreading is required, especially near closing quotes near to em-dashes.]" \
			"build[Build compatible .epub and advanced .epub ebooks from a Standard Ebook source directory. Output is placed in the current directory, or the target directory with --output-dir.]" \
			"build-ids[Change id attributes for non-sectioning content to their expected values across the entire ebook. IDs must be globally unique and correctly referenced, and the ebook spine must be complete.]" \
			"build-images[Generate ebook cover and titlepages for Standard Ebooks ebooks, and then build ebook covers and titlepages, placing the output in DIRECTORY/src/epub/images/.]" \
			"build-loi[Update the LoI file based on all <figure> elements that contain an <img>.]" \
			"build-manifest[Generate the <manifest> element for the given Standard Ebooks source directory and write it to the ebook’s metadata file.]" \
			"build-spine[Generate the <spine> element for the given Standard Ebooks source directory and write it to the ebook’s metadata file.]" \
			"build-svg-titles[Update or add SVG <title> elements based on the alt attributes from the <img> elements.]" \
			"build-title[Generate the title of an XHTML file based on its headings and update the file’s <title> element.]" \
			"build-toc[Generate the table of contents for the ebook’s source directory and update the ToC file.]" \
			"clean[Prettify and canonicalize individual XHTML, SVG, or CSS files, or all XHTML, SVG, or CSS files in a source directory.]" \
			"compare-versions[Use Firefox to render and compare XHTML files in an ebook repository. Run on a dirty repository to visually compare the repository’s dirty state with its clean state. If a file renders differently, place screenshots of the new, original, and diff (if available) renderings in the current working directory. A file called diff.html is created to allow for side-by-side comparisons of original and new files.]" \
			"create-draft[Create a skeleton of a new Standard Ebook in the current directory.]" \
			"css-select[Print the results of a CSS selector evaluated against a set of XHTML files.]" \
			"dec2roman[Convert a decimal number to a Roman numeral.]" \
			"extract-ebook[Extract an .epub, .mobi, or .azw3 ebook into ./FILENAME.extracted/ or a target directory.]" \
			"find-mismatched-dashes[Find words with mismatched dashes in a set of XHTML files. For example, extra-physical in one file and extraphysical in another.]" \
			"find-mismatched-diacritics[Find words with mismatched diacritics in a set of XHTML files. For example, cafe in one file and café in another.]" \
			"find-unusual-characters[Find characters outside a nominal expected range in a set of XHTML files. This can be useful to find transcription mistakes and mojibake.]" \
			"help[List available Standard Ebooks commands.]" \
			"hyphenate[Insert soft hyphens at syllable breaks in XHTML files.]" \
			"interactive-replace[Perform an interactive search and replace on a list of files using Python-flavored regex. The view is scrolled using the arrow keys, with alt to scroll by page in any direction. Basic Emacs (default) or Vim style navigation is available. The following actions are possible\: (y) Accept replacement. (n) Reject replacement. (a) Accept all remaining replacements in this file. (r) Reject all remaining replacements in this file. (c) Center on match. (q) Save this file and quit.]" \
			"lint[Check for various Standard Ebooks style errors.]" \
			"make-url-safe[Make a string URL-safe.]" \
			"modernize-spelling[Modernize spelling of some archaic words, and replace words that may be archaically compounded with a dash to a more modern spelling. For example, replace ash-tray with ashtray.]" \
			"prepare-release[Calculate work word count, insert release date if not yet set, and update modified date and revision number.]" \
			"recompose-epub[Recompose a Standard Ebooks source directory into a single (X?)HTML5 file, and print to standard output.]" \
			"renumber-endnotes[Renumber all endnotes and noterefs sequentially from the beginning, taking care to match noterefs and endnotes if possible.]" \
			"roman2dec[Convert a Roman numeral to a decimal number.]" \
			"semanticate[Automatically add semantics to Standard Ebooks source directories.]" \
			"shift-endnotes[Increment or decrement the specified endnote and all following endnotes by 1 or a specified amount.]" \
			"shift-illustrations[Increment or decrement the specified illustration and all following illustrations by 1 or a specified amount.]" \
			"split-file[Split an XHTML file into many files at all instances of <!--se\:split-->, and include a header template for each file.]" \
			"titlecase[Convert a string to titlecase.]" \
			"typogrify[Apply some scriptable typography rules from the Standard Ebooks typography manual to XHTML files.]" \
			"unicode-names[Display Unicode code points, descriptions, and links to more details for each character in a string. Useful for differentiating between different flavors of spaces, dashes, and invisible characters like word joiners.]" \
			"word-count[Count the number of words in an XHTML file and optionally categorize by length. If multiple files are specified, show the total word count for all.]" \
			"xpath[Print the results of an xpath expression evaluated against a set of XHTML files. The default namespace is removed.]"
			ret=$?
		;;
	args)
		case $line[1] in
			add-file)
				_arguments -s \
					{-f,--force}'[Overwrite any existing files.]' \
					{-h,--help}'[Show this help message and exit.]' \
					'1:The type of file to add.:(dedication dramatis-personae endnotes epigraph glossary halftitlepage ignore)' \
					'*:A Standard Ebooks source directory.:_directories'
				;;
			british2american)
				_arguments -s \
					{-f,--force}'[Force conversion of quote style.]' \
					{-h,--help}'[Show this help message and exit.]' \
					{-v,--verbose}'[Increase output verbosity.]' \
					'*:An XHTML file, or a directory containing XHTML files.:_files -g \*.xhtml'
				;;
			build)
				_arguments -s \
					{-b,--kobo}'[Also build a .kepub.epub file for Kobo.]' \
					{-c,--check}'[Use epubcheck to validate the compatible .epub file, and the Nu Validator (v.Nu) to validate XHTML5; if Ace is installed, also validate using Ace; if --kindle is also specified and epubcheck, v.Nu, or Ace fail, don’t create a Kindle file.]' \
					{-h,--help}'[Show this help message and exit.]' \
					{-k,--kindle}'[Also build an .azw3 file for Kindle.]' \
					{-o,--output-dir}'[A directory to place output files in; will be created if it doesn’t exist.]: :_directories' \
					{-p,--proof}'[Insert additional CSS rules that are helpful for proofreading; output filenames will end in .proof.]' \
					{-v,--verbose}'[Increase output verbosity.]' \
					{-y,--check-only}'[Run tests used by --check, but don’t output any ebook files, and exit after checking.]' \
					'*:A Standard Ebooks source directory.:_directories'
				;;
			build-ids)
				_arguments -s \
					{-h,--help}'[Show this help message and exit.]' \
					{-n,--no-endnotes}'[Exclude endnotes.]' \
					{-v,--verbose}'[Increase output verbosity.]' \
					'*:A Standard Ebooks source directory.:_directories'
				;;
			build-images)
				_arguments -s \
					{-g,--no-generate}'[Don’t generate new source cover/titlepage SVGs, only build existing ones.]' \
					{-h,--help}'[Show this help message and exit.]' \
					{-v,--verbose}'[Increase output verbosity.]' \
					'*:A Standard Ebooks source directory.:_directories'
				;;
			build-loi)
				_arguments -s \
					{-h,--help}'[Show this help message and exit.]' \
					{-s,--stdout}'[Print to stdout instead of writing to the LoI file.]' \
					'*:A Standard Ebooks source directory.:_directories'
				;;
			build-manifest)
				_arguments -s \
					{-h,--help}'[Show this help message and exit.]' \
					{-s,--stdout}'[Print to stdout instead of writing to the metadata file.]' \
					'*:A Standard Ebooks source directory.:_directories'
				;;
			build-spine)
				_arguments -s \
					{-h,--help}'[Show this help message and exit.]' \
					{-s,--stdout}'[Print to stdout instead of writing to the metadata file.]' \
					'*:A Standard Ebooks source directory.:_directories'
				;;
			build-svg-titles)
				_arguments -s \
					{-h,--help}'[Show this help message and exit.]' \
					{-v,--verbose}'[Increase output verbosity.]' \
					'*:A Standard Ebooks source directory.:_directories'
				;;
			build-title)
				_arguments -s \
					{-h,--help}'[Show this help message and exit.]' \
					{-n,--no-newline}'[With --stdout, don’t end output with a newline.]' \
					{-s,--stdout}'[Print to stdout instead of writing to the file.]' \
					'*:An XHTML file, or a directory containing XHTML files.:_files -g \*.xhtml'
				;;
			build-toc)
				_arguments -s \
					{-h,--help}'[Show this help message and exit.]' \
					{-s,--stdout}'[Print to stdout instead of writing to the ToC file.]' \
					'*:A Standard Ebooks source directory.:_directories'
				;;
			clean)
				_arguments -s \
					{-h,--help}'[Show this help message and exit.]' \
					{-v,--verbose}'[Increase output verbosity.]' \
					'*:An XHTML, SVG, or CSS file, or a directory containing XHTML, SVG, or CSS files.:_files -g \*.\(css\|svg\|xhtml\)'
				;;
			compare-versions)
				_arguments -s \
					{-h,--help}'[Show this help message and exit.]' \
					{-i,--include-se-files}'[Include commonly-excluded Standard Ebooks files like imprint, titlepage, and colophon.]' \
					{-n,--no-images}'[Don’t create images of diffs.]' \
					{-v,--verbose}'[Increase output verbosity.]' \
					'*:A directory containing XHTML files.:_directories'
				;;
			create-draft)
				local source_options=()
				if ! _se_has_option -f --fp-id -o --offline -p --pg-id; then
					source_options=(
						{-f,--fp-id}'[The Faded Page ID number of the ebook to download.]:id'
						{-o,--offline}'[Create a draft without network access.]'
						{-p,--pg-id}'[The Project Gutenberg ID number of the ebook to download.]:id'
					)
				fi

				_arguments -s \
					{-a,--author}'[An author of the ebook.]:name' \
					{-e,--email}'[Use this email address as the main committer for the local Git repository.]:email' \
					{-h,--help}'[Show this help message and exit.]' \
					"${source_options[@]}" \
					{-r,--translator}'[A translator of the ebook.]:name' \
					{-t,--title}'[The title of the ebook.]:title' \
					{-v,--verbose}'[Increase output verbosity.]' \
					{-w,--white-label}'[Create a generic epub skeleton without Standard Ebooks branding.]'
				;;
			css-select)
				local output_options=()
				if ! _se_has_option -f --only-filenames -q --quiet; then
					output_options=(
						{-f,--only-filenames}'[Only output filenames of files that contain matches, not the matches themselves.]'
						{-q,--quiet}'[Don’t output anything, only a return code if matches exist in any files.]'
					)
				fi

				_arguments -s \
					{-h,--help}'[Show this help message and exit.]' \
					"${output_options[@]}" \
					'1:A CSS selector.:' \
					'*:An XHTML file, or a directory containing XHTML files.:_files -g \*.xhtml'
				;;
			dec2roman)
				_arguments -s \
					{-h,--help}'[Show this help message and exit.]' \
					{-n,--no-newline}'[Don’t end output with a newline.]' \
					'*:An integer.:'
				;;
			extract-ebook)
				_arguments -s \
					{-h,--help}'[Show this help message and exit.]' \
					{-o,--output-dir}'[A target directory to extract into.]: :_directories' \
					{-v,--verbose}'[Increase output verbosity.]' \
					'*:An .epub, .mobi, or .azw3 file.:_files -g \*.\(epub\|mobi\|azw3\)'
				;;
			find-mismatched-dashes)
				_arguments -s \
					{-h,--help}'[Show this help message and exit.]' \
					'*:An XHTML file, or a directory containing XHTML files.:_files -g \*.xhtml'
				;;
			find-mismatched-diacritics)
				_arguments -s \
					{-h,--help}'[Show this help message and exit.]' \
					'*:An XHTML file, or a directory containing XHTML files.:_files -g \*.xhtml'
				;;
			find-unusual-characters)
				_arguments -s \
					{-h,--help}'[Show this help message and exit.]' \
					'*:An XHTML file, or a directory containing XHTML files.:_files -g \*.xhtml'
				;;
			help)
				;;
			hyphenate)
				_arguments -s \
					{-h,--help}'[Show this help message and exit.]' \
					{-i,--ignore-h-tags}'[Don’t add soft hyphens to text in <h1-6> tags.]' \
					{-l,--language}'[Specify the language for the XHTML files; if unspecified, defaults to the xml\:lang or lang attribute of the root <html> element.]:language' \
					{-v,--verbose}'[Increase output verbosity.]' \
					'*:An XHTML file, or a directory containing XHTML files.:_files -g \*.xhtml'
				;;
			interactive-replace)
				_arguments -s \
					{-d,--dot-all}'[Make . match newlines; equivalent to regex.DOTALL.]' \
					{-h,--help}'[Show this help message and exit.]' \
					{-i,--ignore-case}'[Ignore case when matching; equivalent to regex.IGNORECASE.]' \
					{-m,--multiline}'[Make ^ and $ consider each line; equivalent to regex.MULTILINE.]' \
					{-v,--vim}'[Use basic Vim-like navigation shortcuts.]' \
					'1:A regex of the type accepted by Python’s regex library.:' \
					'2:A replacement regex of the type accepted by Python’s regex library.:' \
					'*:A file or directory on which to perform the search and replace.:_files'
				;;
			lint)
				local lint_ignore_options=()
				if ! _se_has_option -a --allow -s --skip-lint-ignore; then
					lint_ignore_options=(
						{-a,--allow}'[If an se-lint-ignore.xml file is present, allow these specific codes to be raised by lint.]:value'
						{-s,--skip-lint-ignore}'[Ignore all rules in the se-lint-ignore.xml file.]'
					)
				fi

				_arguments -s \
					{-h,--help}'[Show this help message and exit.]' \
					"${lint_ignore_options[@]}" \
					{-v,--verbose}'[Increase output verbosity.]' \
					'*:A Standard Ebooks source directory.:_directories'
				;;
			make-url-safe)
				_arguments -s \
					{-h,--help}'[Show this help message and exit.]' \
					{-n,--no-newline}'[Don’t end output with a newline.]' \
					'*:A string.:'
				;;
			modernize-spelling)
				_arguments -s \
					{-h,--help}'[Show this help message and exit.]' \
					{-n,--no-hyphens}'[Don’t modernize hyphenation.]' \
					{-v,--verbose}'[Increase output verbosity.]' \
					'*:An XHTML file, or a directory containing XHTML files.:_files -g \*.xhtml'
				;;
			prepare-release)
				_arguments -s \
					{-h,--help}'[Show this help message and exit.]' \
					{-r,--no-revision}'[Don’t increment the revision number.]' \
					{-v,--verbose}'[Increase output verbosity.]' \
					{-w,--no-word-count}'[Don’t calculate word count.]' \
					'*:A Standard Ebooks source directory.:_directories'
				;;
			recompose-epub)
				_arguments -s \
					{-e,--extra-css-file}'[The path to an additional CSS file to include after any CSS files in the epub.]: :_files' \
					{-h,--help}'[Show this help message and exit.]' \
					{-i,--image-files}'[Leave image src attributes as relative URLs instead of inlining as data\: URIs.]' \
					{-o,--output}'[A file to write output to instead of printing to standard output.]: :_files' \
					{-x,--xhtml}'[Output XHTML instead of HTML5.]' \
					'1:A Standard Ebooks source directory.:_directories'
				;;
			renumber-endnotes)
				_arguments -s \
					{-b,--brute-force}'[Renumber without checking that noterefs and endnotes match; may result in endnotes with empty backlinks or noterefs without matching endnotes.]' \
					{-h,--help}'[Show this help message and exit.]' \
					{-v,--verbose}'[Increase output verbosity.]' \
					'*:A Standard Ebooks source directory.:_directories'
				;;
			roman2dec)
				_arguments -s \
					{-h,--help}'[Show this help message and exit.]' \
					{-n,--no-newline}'[Don’t end output with a newline.]' \
					'*:A Roman numeral.:'
				;;
			semanticate)
				_arguments -s \
					{-h,--help}'[Show this help message and exit.]' \
					{-v,--verbose}'[Increase output verbosity.]' \
					'*:An XHTML file, or a directory containing XHTML files.:_files -g \*.xhtml'
				;;
			shift-endnotes)
				_arguments -s \
					{-a,--amount}'[The amount to increment or decrement by; defaults to 1.]:value' \
					{-d,--decrement}'[Decrement the target endnote number and all following endnotes.]' \
					{-h,--help}'[Show this help message and exit.]' \
					{-i,--increment}'[Increment the target endnote number and all following endnotes.]' \
					'1:The endnote number to start shifting at.:' \
					'2:A Standard Ebooks source directory.:_directories'
				;;
			shift-illustrations)
				_arguments -s \
					{-a,--amount}'[The amount to increment or decrement by; defaults to 1.]:value' \
					{-d,--decrement}'[Decrement the target illustration number and all following illustrations.]' \
					{-h,--help}'[Show this help message and exit.]' \
					{-i,--increment}'[Increment the target illustration number and all following illustrations.]' \
					'1:The illustration number to start shifting at.:' \
					'2:A Standard Ebooks source directory.:_directories'
				;;
			split-file)
				_arguments -s \
					{-f,--filename-format}'[A format string for the output files; %%n is replaced with the current chapter number; defaults to chapter-%%n.xhtml.]:value' \
					{-h,--help}'[Show this help message and exit.]' \
					{-s,--start-at}'[Start numbering chapters at this number, instead of at 1.]:value' \
					{-t,--template-file}'[A file containing an XHTML template to use for each chapter; the string LANG is replaced by the guessed language, the string NUMBER is replaced by the chapter number, the string NUMERAL is replaced by the chapter Roman numeral, and the string TEXT is replaced by the chapter body.]: :_files' \
					'1:An HTML/XHTML file.:_files -g \*.\(htm\|html\|xhtml\)'
				;;
			titlecase)
				_arguments -s \
					{-h,--help}'[Show this help message and exit.]' \
					{-n,--no-newline}'[Don’t end output with a newline.]' \
					'*:A string.:'
				;;
			typogrify)
				_arguments -s \
					{-h,--help}'[Show this help message and exit.]' \
					{-n,--no-quotes}'[Don’t convert to smart quotes before doing other adjustments.]' \
					{-v,--verbose}'[Increase output verbosity.]' \
					'*:An XHTML file, or a directory containing XHTML files.:_files -g \*.xhtml'
				;;
			unicode-names)
				_arguments -s \
					{-h,--help}'[Show this help message and exit.]' \
					'*:A Unicode string.:'
				;;
			word-count)
				_arguments -s \
					{-c,--categorize}'[Include length categorization in output.]' \
					{-h,--help}'[Show this help message and exit.]' \
					{-p,--ignore-pg-boilerplate}'[Attempt to ignore Project Gutenberg boilerplate headers and footers before counting.]' \
					{-x,--exclude-se-files}'[Exclude some non-bodymatter files common to Standard Ebooks ebooks, like the ToC and colophon.]' \
					'*:An XHTML file, or a directory containing XHTML files.:_files -g \*.\(htm\|html\|xhtml\)'
				;;
			xpath)
				local output_options=()
				if ! _se_has_option -f --only-filenames -q --quiet; then
					output_options=(
						{-f,--only-filenames}'[Only output filenames of files that contain matches, not the matches themselves.]'
						{-q,--quiet}'[Don’t output anything, only a return code if matches exist in any files.]'
					)
				fi

				_arguments -s \
					{-h,--help}'[Show this help message and exit.]' \
					"${output_options[@]}" \
					'1:An xpath expression.:' \
					'*:An XHTML file, or a directory containing XHTML files.:_files -g \*.xhtml'
				;;
		esac
		ret=$?
		;;
esac

return $ret
