/**
 * Djot language definition for highlight.js
 *
 * Supports the full Djot specification plus djot-php enhancements.
 * @see https://djot.net for Djot specification
 * @see https://github.com/php-collective/djot-php for enhancements
 */
(function() {
    function djot(hljs) {
        // Block attributes: {.class #id key=value} or boolean {reversed}
        // Excludes special syntax like {= {+ {- {%
        const ATTRIBUTE = {
            className: 'attr',
            begin: /\{(?![=+\-%])[^}]+\}/,
            relevance: 5,
        };

        // Frontmatter: YAML metadata at document start
        const FRONTMATTER = {
            className: 'meta',
            begin: /^---$/,
            end: /^---$/,
            relevance: 10,
        };

        // Headings: # to ######
        const HEADING = {
            className: 'section',
            begin: /^#{1,6}\s/,
            end: /$/,
            relevance: 10,
        };

        // Forced emphasis: {_text_}
        const FORCED_EMPHASIS = {
            className: 'emphasis',
            begin: /\{_(?!\s)/,
            end: /_\}/,
            relevance: 5,
        };

        // Emphasis: _text_ - not in middle of words (defined first for nesting)
        const EMPHASIS = {
            className: 'emphasis',
            begin: /(?<!\w)_(?!\s)/,
            end: /_(?!\w)/,
            relevance: 0,
        };

        // Forced strong: {*text*}
        const FORCED_STRONG = {
            className: 'strong',
            begin: /\{\*(?!\s)/,
            end: /\*\}/,
            relevance: 5,
            contains: [FORCED_EMPHASIS, EMPHASIS],
        };

        // Strong: *text* - not in middle of words, can contain emphasis
        // Excludes *[ which is abbreviation definition syntax
        const STRONG = {
            className: 'strong',
            begin: /(?<!\w)\*(?![\s\[])/,
            end: /\*(?!\w)/,
            relevance: 0,
            contains: [EMPHASIS],
        };

        // Highlight: {=text=}
        const HIGHLIGHT = {
            className: 'addition',
            begin: /\{=/,
            end: /=\}/,
            relevance: 5,
        };

        // Insert: {+text+}
        const INSERT = {
            className: 'addition',
            begin: /\{\+/,
            end: /\+\}/,
            relevance: 5,
        };

        // Delete: {-text-}
        const DELETE = {
            className: 'deletion',
            begin: /\{-/,
            end: /-\}/,
            relevance: 5,
        };

        // Superscript: ^text^ or {^text^}
        const SUPERSCRIPT = {
            className: 'built_in',
            begin: /\^(?!\s)/,
            end: /\^/,
            relevance: 2,
        };

        // Braced superscript: {^text^}
        const BRACED_SUPERSCRIPT = {
            className: 'built_in',
            begin: /\{\^/,
            end: /\^\}/,
            relevance: 5,
        };

        // Subscript: ~text~ or {~text~}
        const SUBSCRIPT = {
            className: 'built_in',
            begin: /~(?!\s)/,
            end: /~/,
            relevance: 2,
        };

        // Braced subscript: {~text~}
        const BRACED_SUBSCRIPT = {
            className: 'built_in',
            begin: /\{~/,
            end: /~\}/,
            relevance: 5,
        };

        // Inline code: `code` or ``code``
        const INLINE_CODE = {
            className: 'code',
            begin: /`+/,
            end: /`+/,
            relevance: 0,
        };

        // Inline links: [text](url) with optional trailing attributes
        const LINK = {
            className: 'link',
            begin: /\[[^\]]*\]\([^)]*\)(\{[^}]+\})?/,
            relevance: 5,
        };

        // Autolinks: <https://...> or <mailto:...>
        const AUTOLINK = {
            className: 'link',
            begin: /<https?:\/\/[^>]+>/,
            relevance: 5,
        };

        // Email autolinks: <user@example.com>
        const EMAIL_AUTOLINK = {
            className: 'link',
            begin: /<[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}>/,
            relevance: 5,
        };

        // Images: ![alt](url) with optional trailing attributes
        const IMAGE = {
            className: 'link',
            begin: /!\[[^\]]*\]\([^)]*\)(\{[^}]+\})?/,
            relevance: 5,
        };

        // Reference links: [text][ref] with optional trailing attributes
        const REFERENCE_LINK = {
            className: 'link',
            begin: /\[[^\]]+\]\[[^\]]*\](\{[^}]+\})?/,
            relevance: 5,
        };

        // Spans with attributes: [text]{.class} or [text]{#id}
        const SPAN = {
            className: 'string',
            begin: /\[[^\]]+\]\{[^}]+\}/,
            relevance: 5,
        };

        // Reference definitions: [ref]: url
        const REFERENCE_DEF = {
            className: 'symbol',
            begin: /^\[[^\]^\]]+\]:/,
            end: /$/,
            relevance: 10,
        };

        // Footnote references: [^note]
        const FOOTNOTE_REF = {
            className: 'symbol',
            begin: /\[\^[^\]]+\]/,
            relevance: 5,
        };

        // Footnote definitions: [^note]: content
        const FOOTNOTE_DEF = {
            className: 'symbol',
            begin: /^\[\^[^\]]+\]:/,
            end: /$/,
            relevance: 10,
        };

        // Abbreviation definitions (djot-php extension): *[ABBR]: text
        const ABBREVIATION_DEF = {
            className: 'symbol',
            begin: /^\*\[[^\]]+\]:/,
            end: /$/,
            relevance: 10,
        };

        // Blockquotes: > text
        const BLOCKQUOTE = {
            className: 'quote',
            begin: /^>/,
            end: /$/,
            relevance: 0,
        };

        // Horizontal rules: --- or *** or ___
        const HORIZONTAL_RULE = {
            className: 'meta',
            begin: /^(-{3,}|\*{3,}|_{3,})$/,
            relevance: 10,
        };

        // Bullet list items: - or * or +
        const LIST_BULLET = {
            className: 'bullet',
            begin: /^[ \t]*[-*+](?=\s)/,
            relevance: 0,
        };

        // Numbered list items: decimal (1.), alpha (a. A.), roman (i. I.), enclosed ((1) (a) (i))
        const LIST_NUMBER = {
            className: 'bullet',
            begin: /^[ \t]*(\d+[.)]|[a-zA-Z][.)]|[ivxlcdmIVXLCDM]+[.)]|\([\da-zA-Z]+\)|\([ivxlcdmIVXLCDM]+\))(?=\s)/,
            relevance: 0,
        };

        // Task list items: - [ ] or - [x] or - [_]
        const TASK_LIST = {
            className: 'bullet',
            begin: /^[ \t]*[-*+]\s\[[ xX_]\]/,
            relevance: 5,
        };

        // Definition list terms: : term (at start of line with content after colon+space)
        const DEFINITION_TERM = {
            className: 'title',
            begin: /^: /,
            end: /$/,
            relevance: 5,
        };

        // Code fence opening: ``` or ~~~ with optional language or =format
        const CODE_FENCE_START = {
            className: 'keyword',
            begin: /^[`~]{3,}\s*=?[a-zA-Z]*$/,
            relevance: 10,
        };

        // Code fence closing: ``` or ~~~
        const CODE_FENCE_END = {
            className: 'keyword',
            begin: /^[`~]{3,}$/,
            relevance: 10,
        };

        // Div block opening: ::: with optional class
        const DIV_BLOCK_START = {
            className: 'keyword',
            begin: /^:{3,}\s*\w*$/,
            relevance: 10,
        };

        // Div block closing: :::
        const DIV_BLOCK_END = {
            className: 'keyword',
            begin: /^:{3,}$/,
            relevance: 10,
        };

        // Fenced comment opening (djot-php extension): %%%
        const FENCED_COMMENT_START = {
            className: 'comment',
            begin: /^%{3,}$/,
            relevance: 10,
        };

        // Fenced comment closing: %%%
        const FENCED_COMMENT_END = {
            className: 'comment',
            begin: /^%{3,}$/,
            relevance: 10,
        };

        // Inline comments: {% comment %}
        const INLINE_COMMENT = {
            className: 'comment',
            begin: /\{%/,
            end: /%\}/,
            relevance: 5,
        };

        // Table rows: | cell | cell |
        const TABLE_ROW = {
            className: 'string',
            begin: /^\|/,
            end: /\|(\{[^}]*\})?$/,
            relevance: 2,
        };

        // Table separator: |---|---|
        const TABLE_SEPARATOR = {
            className: 'meta',
            begin: /^\|[-:| ]+\|$/,
            relevance: 5,
        };

        // Line blocks: | text (for poetry)
        const LINE_BLOCK = {
            className: 'string',
            begin: /^\| /,
            end: /$/,
            relevance: 3,
        };

        // Captions (djot-php extension): ^ caption text
        const CAPTION = {
            className: 'title',
            begin: /^\^ /,
            end: /$/,
            relevance: 5,
        };

        // Symbols: :name:
        const SYMBOL = {
            className: 'symbol',
            begin: /:[a-zA-Z_][a-zA-Z0-9_]*:/,
            relevance: 3,
        };

        // Inline math: $`code`$
        const INLINE_MATH = {
            className: 'formula',
            begin: /\$`/,
            end: /`\$/,
            relevance: 5,
        };

        // Display math: $$`code`$$
        const DISPLAY_MATH = {
            className: 'formula',
            begin: /\$\$`/,
            end: /`\$\$/,
            relevance: 5,
        };

        // Raw format marker: {=html} or {=latex}
        const RAW_FORMAT = {
            className: 'meta',
            begin: /\{=[a-zA-Z]+\}/,
            relevance: 5,
        };

        // Smart punctuation: em-dash (---), en-dash (--), ellipsis (...)
        const EM_DASH = {
            className: 'punctuation',
            begin: /---/,
            relevance: 0,
        };

        const EN_DASH = {
            className: 'punctuation',
            begin: /--/,
            relevance: 0,
        };

        const ELLIPSIS = {
            className: 'punctuation',
            begin: /\.\.\./,
            relevance: 0,
        };

        // Escaped characters: \* \[ etc
        const ESCAPE = {
            className: 'symbol',
            begin: /\\[!"#$%&'()*+,.\/:;<=>?@\[\\\]^_`{|}~-]/,
            relevance: 0,
        };

        // Hard line break: \ at end of line
        const HARD_BREAK = {
            className: 'meta',
            begin: /\\$/,
            relevance: 2,
        };

        return {
            name: 'Djot',
            aliases: ['djot'],
            case_insensitive: false,
            contains: [
                // Block-level elements (order matters - more specific first)
                FRONTMATTER,       // Must be first (document start)
                HEADING,
                CODE_FENCE_START,
                CODE_FENCE_END,
                DIV_BLOCK_START,
                DIV_BLOCK_END,
                FENCED_COMMENT_START,
                FENCED_COMMENT_END,
                HORIZONTAL_RULE,
                TABLE_SEPARATOR,
                LINE_BLOCK,        // Must be before TABLE_ROW (both start with |)
                TABLE_ROW,
                BLOCKQUOTE,
                CAPTION,
                TASK_LIST,         // Must be before LIST_BULLET
                LIST_BULLET,
                LIST_NUMBER,
                DEFINITION_TERM,
                FOOTNOTE_DEF,      // Must be before REFERENCE_DEF
                ABBREVIATION_DEF,  // Must be before REFERENCE_DEF (*[ABBR]: vs [ref]:)
                REFERENCE_DEF,

                // Inline elements (order matters - more specific first)
                FOOTNOTE_REF,
                IMAGE,             // Must be before LINK (starts with !)
                SPAN,              // Must be before LINK ([text]{attr} vs [text](url))
                REFERENCE_LINK,    // Must be before LINK ([text][ref] vs [text](url))
                LINK,
                AUTOLINK,
                EMAIL_AUTOLINK,
                DISPLAY_MATH,      // Must be before INLINE_MATH ($$` vs $`)
                INLINE_MATH,
                RAW_FORMAT,        // {=html} - must be before HIGHLIGHT
                HIGHLIGHT,         // {=text=}
                INSERT,            // {+text+}
                DELETE,            // {-text-}
                BRACED_SUPERSCRIPT, // Must be before SUPERSCRIPT ({^text^} vs ^text^)
                BRACED_SUBSCRIPT,   // Must be before SUBSCRIPT ({~text~} vs ~text~)
                INLINE_COMMENT,    // {% %} - must be before ATTRIBUTE
                SUPERSCRIPT,
                SUBSCRIPT,
                FORCED_STRONG,     // Must be before STRONG ({*text*} vs *text*)
                FORCED_EMPHASIS,   // Must be before EMPHASIS ({_text_} vs _text_)
                STRONG,
                EMPHASIS,
                INLINE_CODE,
                SYMBOL,
                ATTRIBUTE,
                EM_DASH,           // Must be before EN_DASH (--- vs --)
                EN_DASH,
                ELLIPSIS,
                ESCAPE,
                HARD_BREAK,
            ],
        };
    }

    // Register with highlight.js
    if (typeof hljs !== 'undefined') {
        hljs.registerLanguage('djot', djot);
    }

    // Export for module systems
    if (typeof module !== 'undefined' && module.exports) {
        module.exports = djot;
    }
})();
