"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const language_core_1 = require("@volar/language-core");
const muggle_string_1 = require("muggle-string");
const buildMappings_1 = require("../utils/buildMappings");
const parseSfc_1 = require("../utils/parseSfc");
const frontmatterReg = /^---[\s\S]*?\n---(?:\r?\n|$)/;
const codeblockReg = /(`{3,})[\s\S]+?\1/g;
const inlineCodeblockReg = /`[^\n`]+?`/g;
const latexBlockReg = /(\${2,})[\s\S]+?\1/g;
const scriptSetupReg = /\\<[\s\S]+?>\n?/g;
const codeSnippetImportReg = /^\s*<<<\s*.+/gm;
const sfcBlockReg = /<(script|style)\b[\s\S]*?>([\s\S]*?)<\/\1>/g;
const angleBracketReg = /<\S*:\S*>/g;
const linkReg = /\[[\s\S]*?\]\([\s\S]*?\)/g;
const plugin = ({ vueCompilerOptions }) => {
    return {
        version: 2.2,
        getLanguageId(fileName) {
            if (vueCompilerOptions.vitePressExtensions.some(ext => fileName.endsWith(ext))) {
                return 'markdown';
            }
        },
        isValidFile(_fileName, languageId) {
            return languageId === 'markdown';
        },
        parseSFC2(_fileName, languageId, content) {
            if (languageId !== 'markdown') {
                return;
            }
            content = content
                // frontmatter
                .replace(frontmatterReg, match => ' '.repeat(match.length))
                // code block
                .replace(codeblockReg, (match, quotes) => quotes + ' '.repeat(match.length - quotes.length * 2) + quotes)
                // latex block
                .replace(latexBlockReg, (match, quotes) => quotes + ' '.repeat(match.length - quotes.length * 2) + quotes)
                // # \<script setup>
                .replace(scriptSetupReg, match => ' '.repeat(match.length))
                // <<< https://vitepress.dev/guide/markdown#import-code-snippets
                .replace(codeSnippetImportReg, match => ' '.repeat(match.length));
            const codes = [];
            for (const match of content.matchAll(sfcBlockReg)) {
                const matchText = match[0];
                codes.push([matchText, undefined, match.index]);
                codes.push('\n\n');
                content = content.slice(0, match.index) + ' '.repeat(matchText.length)
                    + content.slice(match.index + matchText.length);
            }
            content = content
                // inline code block
                .replace(inlineCodeblockReg, match => `\`${' '.repeat(match.length - 2)}\``)
                // angle bracket: <http://foo.com>
                .replace(angleBracketReg, match => ' '.repeat(match.length))
                // [foo](http://foo.com)
                .replace(linkReg, match => ' '.repeat(match.length));
            codes.push('<template>\n');
            codes.push([content, undefined, 0]);
            codes.push('\n</template>');
            const mappings = (0, buildMappings_1.buildMappings)(codes);
            const mapper = new language_core_1.SourceMap(mappings);
            const sfc = (0, parseSfc_1.parse)((0, muggle_string_1.toString)(codes));
            for (const block of [
                sfc.descriptor.template,
                sfc.descriptor.script,
                sfc.descriptor.scriptSetup,
                ...sfc.descriptor.styles,
                ...sfc.descriptor.customBlocks,
            ]) {
                if (block) {
                    transformRange(block);
                }
            }
            return sfc;
            function transformRange(block) {
                const { start, end } = block.loc;
                const startOffset = start.offset;
                const endOffset = end.offset;
                start.offset = -1;
                end.offset = -1;
                for (const [offset] of mapper.toSourceLocation(startOffset)) {
                    start.offset = offset;
                    break;
                }
                for (const [offset] of mapper.toSourceLocation(endOffset)) {
                    end.offset = offset;
                    break;
                }
            }
        },
    };
};
exports.default = plugin;
//# sourceMappingURL=file-md.js.map