/* Parses fenced code blocks with `annotate` in info string. Results in single line comments split out, output format is: .annotate .annotate-row (n) .annotate-code .annotate-note Contributing rules: - You must include `annotate` in the info string - You must include a language on the starting ` ``` ` tag. - Notes must start with one of: `#`, `//`, `` to maintain syntax highlighting; this will not impact what renders. `parse-info-string.ts` plugin is required for this to work, and must come before `remark-rehype`. `annotate` must come before the `highlight` plugin. */ import yaml from 'js-yaml' import fs from 'fs' import { chunk, last } from 'lodash-es' import { visit } from 'unist-util-visit' import { h } from 'hastscript' import { fromMarkdown } from 'mdast-util-from-markdown' import { toHast } from 'mdast-util-to-hast' import type { Root } from 'mdast' import { header } from './code-header' import findPage from '@/frame/lib/find-page' interface LanguageConfig { comment: 'number' | 'slash' | 'xml' | 'percent' | 'hyphen' [key: string]: any } interface ElementNode { type: 'element' tagName: string properties: { className?: string[] [key: string]: any } children: any[] data?: { meta?: { annotate?: boolean [key: string]: any } } } const languages = yaml.load(fs.readFileSync('./data/code-languages.yml', 'utf8')) as Record< string, LanguageConfig > const commentRegexes = { // Also known has hash or sharp; but the unicode name is "number sign". // The reason this has 2 variants is because the hash is used, in bash // for both hash-hang and for comments. // For example: // // #!/bin/bash // // ...is not a comment. // But if you only look for `#` followed by anything-but `!` it will not // match if the line is just `#`. // // > /^\s*#[^!]\s*/.test('#') // false // // Which makes sense, because the `#` is not followed by anything. // That's why we use the | operator to make an "exception" for that case. number: /^\s*#[^!]\s*|^\s*#$/, slash: /^\s*\/\/\s*/, xml: /^\s*