"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.mdAutocomplete = exports.yfmCutDirectiveSnippet = exports.yfmCutDirectiveSnippetTemplate = exports.yfmCutSnippet = exports.yfmCutSnippetTemplate = exports.yfmNoteSnippets = exports.yfmNoteSnippetTemplate = exports.yfmNoteTypes = exports.customTags = void 0;
exports.yfmLang = yfmLang;
const autocomplete_1 = require("@codemirror/autocomplete");
const lang_markdown_1 = require("@codemirror/lang-markdown");
const highlight_1 = require("@lezer/highlight");
const lodash_1 = require("../../lodash.js");
const directive_facet_1 = require("./directive-facet.js");
exports.customTags = {
    underline: highlight_1.Tag.define(),
    monospace: highlight_1.Tag.define(),
    marked: highlight_1.Tag.define(),
};
function mdInlineFactory({ name, char, tag, }) {
    const NodeName = name;
    const MarkName = `${name}Mark`;
    const Delim = { resolve: NodeName, mark: MarkName };
    return {
        defineNodes: [
            { name: NodeName, style: { [`${NodeName}/...`]: tag } },
            { name: MarkName, style: highlight_1.tags.processingInstruction },
        ],
        parseInline: [
            {
                name,
                // TODO: remove types of arguments after https://github.com/lezer-parser/markdown/issues/51
                parse(cx, next, pos) {
                    if (next !== char || cx.char(pos + 1) !== char || cx.char(pos + 2) === char)
                        return -1;
                    return cx.addDelimiter(Delim, pos, pos + 2, true, true);
                },
                after: 'Emphasis',
            },
        ],
    };
}
const UnderlineExtension = mdInlineFactory({
    name: 'Underline',
    char: '+'.charCodeAt(0),
    tag: exports.customTags.underline,
});
const MonospaceExtension = mdInlineFactory({
    name: 'Monospace',
    char: '#'.charCodeAt(0),
    tag: exports.customTags.monospace,
});
const MarkedExtension = mdInlineFactory({
    name: 'Marked',
    char: '='.charCodeAt(0),
    tag: exports.customTags.marked,
});
exports.yfmNoteTypes = ['info', 'tip', 'warning', 'alert'];
const yfmNoteSnippetTemplate = (type) => `{% note ${type} %}\n\n#{}\n\n{% endnote %}\n\n`;
exports.yfmNoteSnippetTemplate = yfmNoteSnippetTemplate;
exports.yfmNoteSnippets = {
    info: (0, autocomplete_1.snippet)((0, exports.yfmNoteSnippetTemplate)('info')),
    tip: (0, autocomplete_1.snippet)((0, exports.yfmNoteSnippetTemplate)('tip')),
    warning: (0, autocomplete_1.snippet)((0, exports.yfmNoteSnippetTemplate)('warning')),
    alert: (0, autocomplete_1.snippet)((0, exports.yfmNoteSnippetTemplate)('alert')),
};
exports.yfmCutSnippetTemplate = '{% cut "#{title}" %}\n\n#{}\n\n{% endcut %}\n\n';
exports.yfmCutSnippet = (0, autocomplete_1.snippet)(exports.yfmCutSnippetTemplate);
exports.yfmCutDirectiveSnippetTemplate = ':::cut [#{title}]\n#{}\n:::\n\n';
exports.yfmCutDirectiveSnippet = (0, autocomplete_1.snippet)(exports.yfmCutDirectiveSnippetTemplate);
exports.mdAutocomplete = {
    autocomplete: (context) => {
        const directiveContext = context.state.facet(directive_facet_1.DirectiveSyntaxFacet);
        // TODO: add more actions and re-enable
        // let word = context.matchBefore(/\/.*/);
        // if (word) {
        //     return {
        //         from: word.from,
        //         options: [
        //             ...yfmNoteTypes.map<Completion>((type, index) => ({
        //                 label: `/yfm note ${type}`,
        //                 displayLabel: `YFM Note ${capitalize(type)}`,
        //                 type: 'text',
        //                 apply: yfmNoteSnippets[type],
        //                 boost: -index,
        //             })),
        //             {
        //                 label: '/yfm cut',
        //                 displayLabel: 'YFM Cut',
        //                 type: 'text',
        //                 apply: directiveFacet.shouldInsertDirectiveMarkup('yfmCut')
        //                      ? yfmCutDirectiveSnippet
        //                      : yfmCutSnippet,
        //             },
        //         ],
        //     };
        // }
        const word = context.matchBefore(/^.*/);
        if (directiveContext.option !== 'only' && word?.text.startsWith('{%')) {
            return {
                from: word.from,
                options: [
                    ...exports.yfmNoteTypes.map((type, index) => ({
                        label: `{% note ${type}`,
                        displayLabel: (0, lodash_1.capitalize)(type),
                        type: 'text',
                        section: 'YFM Note',
                        apply: exports.yfmNoteSnippets[type],
                        boost: -index,
                    })),
                    {
                        label: '{% cut',
                        displayLabel: 'YFM Cut',
                        type: 'text',
                        apply: directiveContext.shouldInsertDirectiveMarkup('yfmCut')
                            ? exports.yfmCutDirectiveSnippet
                            : exports.yfmCutSnippet,
                    },
                ],
            };
        }
        if (directiveContext.option !== 'disabled' && word?.text.startsWith(':')) {
            const options = [];
            if (directiveContext.valueFor('yfmCut') !== 'disabled') {
                options.push({
                    label: ':::cut',
                    displayLabel: 'YFM Cut',
                    type: 'text',
                    apply: exports.yfmCutDirectiveSnippet,
                });
            }
            if (options.length) {
                return { from: word.from, options };
            }
        }
        return null;
    },
};
function yfmLang({ languageData = [] } = {}) {
    const mdSupport = (0, lang_markdown_1.markdown)({
        // defaultCodeLanguage: markdownLanguage,
        base: lang_markdown_1.markdownLanguage,
        addKeymap: true,
        completeHTMLTags: false,
        extensions: [UnderlineExtension, MonospaceExtension, MarkedExtension],
    });
    return [
        mdSupport,
        mdSupport.language.data.of(exports.mdAutocomplete),
        languageData.map((item) => mdSupport.language.data.of(item)),
    ];
}
//# sourceMappingURL=yfm.js.map
