diff --git a/docs/publishing.md b/docs/publishing.md index 32a9bda..78e50fd 100644 --- a/docs/publishing.md +++ b/docs/publishing.md @@ -27,7 +27,9 @@ Release hooks are configured via `.releaserc.yml`. This repo does not stage a se `packages/` is the **only** source of truth. Never edit `skills/*/scripts/vendor/` directly. -Current package: `baoyu-chrome-cdp` (Chrome CDP utilities), consumed by 6 skills (`baoyu-danger-gemini-web`, `baoyu-danger-x-to-markdown`, `baoyu-post-to-wechat`, `baoyu-post-to-weibo`, `baoyu-post-to-x`, `baoyu-url-to-markdown`). +Current packages: +- `baoyu-chrome-cdp` (Chrome CDP utilities), consumed by 6 skills (`baoyu-danger-gemini-web`, `baoyu-danger-x-to-markdown`, `baoyu-post-to-wechat`, `baoyu-post-to-weibo`, `baoyu-post-to-x`, `baoyu-url-to-markdown`) +- `baoyu-md` (shared Markdown rendering and placeholder pipeline), consumed by 3 skills (`baoyu-markdown-to-html`, `baoyu-post-to-wechat`, `baoyu-post-to-weibo`) **How it works**: Sync script copies packages into each consuming skill's `vendor/` directory and rewrites dependency specs to `file:./vendor/`. Vendor copies are committed to git, making skills self-contained. diff --git a/skills/baoyu-post-to-wechat/scripts/md/package.json b/packages/baoyu-md/package.json similarity index 71% rename from skills/baoyu-post-to-wechat/scripts/md/package.json rename to packages/baoyu-md/package.json index 260394d..a6f7086 100644 --- a/skills/baoyu-post-to-wechat/scripts/md/package.json +++ b/packages/baoyu-md/package.json @@ -1,4 +1,11 @@ { + "name": "baoyu-md", + "private": true, + "version": "0.1.0", + "type": "module", + "exports": { + ".": "./src/index.ts" + }, "dependencies": { "fflate": "^0.8.2", "front-matter": "^4.0.2", diff --git a/skills/baoyu-markdown-to-html/scripts/md/LICENSE b/packages/baoyu-md/src/LICENSE similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/LICENSE rename to packages/baoyu-md/src/LICENSE diff --git a/skills/baoyu-markdown-to-html/scripts/md/cli.ts b/packages/baoyu-md/src/cli.ts similarity index 98% rename from skills/baoyu-markdown-to-html/scripts/md/cli.ts rename to packages/baoyu-md/src/cli.ts index 5b0263a..5a7861b 100644 --- a/skills/baoyu-markdown-to-html/scripts/md/cli.ts +++ b/packages/baoyu-md/src/cli.ts @@ -12,7 +12,7 @@ export function printUsage(): void { console.error( [ "Usage:", - " npx tsx src/md/render.ts [options]", + " npx tsx render.ts [options]", "", "Options:", ` --theme Theme (${THEME_NAMES.join(", ")})`, diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/1c-light.min.css b/packages/baoyu-md/src/code-themes/1c-light.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/1c-light.min.css rename to packages/baoyu-md/src/code-themes/1c-light.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/a11y-dark.min.css b/packages/baoyu-md/src/code-themes/a11y-dark.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/a11y-dark.min.css rename to packages/baoyu-md/src/code-themes/a11y-dark.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/a11y-light.min.css b/packages/baoyu-md/src/code-themes/a11y-light.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/a11y-light.min.css rename to packages/baoyu-md/src/code-themes/a11y-light.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/agate.min.css b/packages/baoyu-md/src/code-themes/agate.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/agate.min.css rename to packages/baoyu-md/src/code-themes/agate.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/an-old-hope.min.css b/packages/baoyu-md/src/code-themes/an-old-hope.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/an-old-hope.min.css rename to packages/baoyu-md/src/code-themes/an-old-hope.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/androidstudio.min.css b/packages/baoyu-md/src/code-themes/androidstudio.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/androidstudio.min.css rename to packages/baoyu-md/src/code-themes/androidstudio.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/arduino-light.min.css b/packages/baoyu-md/src/code-themes/arduino-light.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/arduino-light.min.css rename to packages/baoyu-md/src/code-themes/arduino-light.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/arta.min.css b/packages/baoyu-md/src/code-themes/arta.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/arta.min.css rename to packages/baoyu-md/src/code-themes/arta.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/ascetic.min.css b/packages/baoyu-md/src/code-themes/ascetic.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/ascetic.min.css rename to packages/baoyu-md/src/code-themes/ascetic.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/atom-one-dark-reasonable.min.css b/packages/baoyu-md/src/code-themes/atom-one-dark-reasonable.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/atom-one-dark-reasonable.min.css rename to packages/baoyu-md/src/code-themes/atom-one-dark-reasonable.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/atom-one-dark.min.css b/packages/baoyu-md/src/code-themes/atom-one-dark.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/atom-one-dark.min.css rename to packages/baoyu-md/src/code-themes/atom-one-dark.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/atom-one-light.min.css b/packages/baoyu-md/src/code-themes/atom-one-light.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/atom-one-light.min.css rename to packages/baoyu-md/src/code-themes/atom-one-light.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/brown-paper.min.css b/packages/baoyu-md/src/code-themes/brown-paper.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/brown-paper.min.css rename to packages/baoyu-md/src/code-themes/brown-paper.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/codepen-embed.min.css b/packages/baoyu-md/src/code-themes/codepen-embed.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/codepen-embed.min.css rename to packages/baoyu-md/src/code-themes/codepen-embed.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/color-brewer.min.css b/packages/baoyu-md/src/code-themes/color-brewer.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/color-brewer.min.css rename to packages/baoyu-md/src/code-themes/color-brewer.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/dark.min.css b/packages/baoyu-md/src/code-themes/dark.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/dark.min.css rename to packages/baoyu-md/src/code-themes/dark.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/default.min.css b/packages/baoyu-md/src/code-themes/default.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/default.min.css rename to packages/baoyu-md/src/code-themes/default.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/devibeans.min.css b/packages/baoyu-md/src/code-themes/devibeans.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/devibeans.min.css rename to packages/baoyu-md/src/code-themes/devibeans.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/docco.min.css b/packages/baoyu-md/src/code-themes/docco.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/docco.min.css rename to packages/baoyu-md/src/code-themes/docco.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/far.min.css b/packages/baoyu-md/src/code-themes/far.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/far.min.css rename to packages/baoyu-md/src/code-themes/far.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/felipec.min.css b/packages/baoyu-md/src/code-themes/felipec.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/felipec.min.css rename to packages/baoyu-md/src/code-themes/felipec.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/foundation.min.css b/packages/baoyu-md/src/code-themes/foundation.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/foundation.min.css rename to packages/baoyu-md/src/code-themes/foundation.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/github-dark-dimmed.min.css b/packages/baoyu-md/src/code-themes/github-dark-dimmed.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/github-dark-dimmed.min.css rename to packages/baoyu-md/src/code-themes/github-dark-dimmed.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/github-dark.min.css b/packages/baoyu-md/src/code-themes/github-dark.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/github-dark.min.css rename to packages/baoyu-md/src/code-themes/github-dark.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/github.min.css b/packages/baoyu-md/src/code-themes/github.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/github.min.css rename to packages/baoyu-md/src/code-themes/github.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/gml.min.css b/packages/baoyu-md/src/code-themes/gml.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/gml.min.css rename to packages/baoyu-md/src/code-themes/gml.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/googlecode.min.css b/packages/baoyu-md/src/code-themes/googlecode.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/googlecode.min.css rename to packages/baoyu-md/src/code-themes/googlecode.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/gradient-dark.min.css b/packages/baoyu-md/src/code-themes/gradient-dark.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/gradient-dark.min.css rename to packages/baoyu-md/src/code-themes/gradient-dark.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/gradient-light.min.css b/packages/baoyu-md/src/code-themes/gradient-light.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/gradient-light.min.css rename to packages/baoyu-md/src/code-themes/gradient-light.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/grayscale.min.css b/packages/baoyu-md/src/code-themes/grayscale.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/grayscale.min.css rename to packages/baoyu-md/src/code-themes/grayscale.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/hybrid.min.css b/packages/baoyu-md/src/code-themes/hybrid.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/hybrid.min.css rename to packages/baoyu-md/src/code-themes/hybrid.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/idea.min.css b/packages/baoyu-md/src/code-themes/idea.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/idea.min.css rename to packages/baoyu-md/src/code-themes/idea.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/intellij-light.min.css b/packages/baoyu-md/src/code-themes/intellij-light.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/intellij-light.min.css rename to packages/baoyu-md/src/code-themes/intellij-light.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/ir-black.min.css b/packages/baoyu-md/src/code-themes/ir-black.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/ir-black.min.css rename to packages/baoyu-md/src/code-themes/ir-black.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/isbl-editor-dark.min.css b/packages/baoyu-md/src/code-themes/isbl-editor-dark.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/isbl-editor-dark.min.css rename to packages/baoyu-md/src/code-themes/isbl-editor-dark.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/isbl-editor-light.min.css b/packages/baoyu-md/src/code-themes/isbl-editor-light.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/isbl-editor-light.min.css rename to packages/baoyu-md/src/code-themes/isbl-editor-light.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/kimbie-dark.min.css b/packages/baoyu-md/src/code-themes/kimbie-dark.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/kimbie-dark.min.css rename to packages/baoyu-md/src/code-themes/kimbie-dark.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/kimbie-light.min.css b/packages/baoyu-md/src/code-themes/kimbie-light.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/kimbie-light.min.css rename to packages/baoyu-md/src/code-themes/kimbie-light.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/lightfair.min.css b/packages/baoyu-md/src/code-themes/lightfair.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/lightfair.min.css rename to packages/baoyu-md/src/code-themes/lightfair.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/lioshi.min.css b/packages/baoyu-md/src/code-themes/lioshi.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/lioshi.min.css rename to packages/baoyu-md/src/code-themes/lioshi.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/magula.min.css b/packages/baoyu-md/src/code-themes/magula.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/magula.min.css rename to packages/baoyu-md/src/code-themes/magula.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/mono-blue.min.css b/packages/baoyu-md/src/code-themes/mono-blue.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/mono-blue.min.css rename to packages/baoyu-md/src/code-themes/mono-blue.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/monokai-sublime.min.css b/packages/baoyu-md/src/code-themes/monokai-sublime.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/monokai-sublime.min.css rename to packages/baoyu-md/src/code-themes/monokai-sublime.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/monokai.min.css b/packages/baoyu-md/src/code-themes/monokai.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/monokai.min.css rename to packages/baoyu-md/src/code-themes/monokai.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/night-owl.min.css b/packages/baoyu-md/src/code-themes/night-owl.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/night-owl.min.css rename to packages/baoyu-md/src/code-themes/night-owl.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/nnfx-dark.min.css b/packages/baoyu-md/src/code-themes/nnfx-dark.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/nnfx-dark.min.css rename to packages/baoyu-md/src/code-themes/nnfx-dark.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/nnfx-light.min.css b/packages/baoyu-md/src/code-themes/nnfx-light.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/nnfx-light.min.css rename to packages/baoyu-md/src/code-themes/nnfx-light.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/nord.min.css b/packages/baoyu-md/src/code-themes/nord.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/nord.min.css rename to packages/baoyu-md/src/code-themes/nord.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/obsidian.min.css b/packages/baoyu-md/src/code-themes/obsidian.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/obsidian.min.css rename to packages/baoyu-md/src/code-themes/obsidian.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/panda-syntax-dark.min.css b/packages/baoyu-md/src/code-themes/panda-syntax-dark.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/panda-syntax-dark.min.css rename to packages/baoyu-md/src/code-themes/panda-syntax-dark.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/panda-syntax-light.min.css b/packages/baoyu-md/src/code-themes/panda-syntax-light.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/panda-syntax-light.min.css rename to packages/baoyu-md/src/code-themes/panda-syntax-light.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/paraiso-dark.min.css b/packages/baoyu-md/src/code-themes/paraiso-dark.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/paraiso-dark.min.css rename to packages/baoyu-md/src/code-themes/paraiso-dark.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/paraiso-light.min.css b/packages/baoyu-md/src/code-themes/paraiso-light.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/paraiso-light.min.css rename to packages/baoyu-md/src/code-themes/paraiso-light.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/pojoaque.min.css b/packages/baoyu-md/src/code-themes/pojoaque.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/pojoaque.min.css rename to packages/baoyu-md/src/code-themes/pojoaque.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/purebasic.min.css b/packages/baoyu-md/src/code-themes/purebasic.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/purebasic.min.css rename to packages/baoyu-md/src/code-themes/purebasic.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/qtcreator-dark.min.css b/packages/baoyu-md/src/code-themes/qtcreator-dark.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/qtcreator-dark.min.css rename to packages/baoyu-md/src/code-themes/qtcreator-dark.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/qtcreator-light.min.css b/packages/baoyu-md/src/code-themes/qtcreator-light.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/qtcreator-light.min.css rename to packages/baoyu-md/src/code-themes/qtcreator-light.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/rainbow.min.css b/packages/baoyu-md/src/code-themes/rainbow.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/rainbow.min.css rename to packages/baoyu-md/src/code-themes/rainbow.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/routeros.min.css b/packages/baoyu-md/src/code-themes/routeros.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/routeros.min.css rename to packages/baoyu-md/src/code-themes/routeros.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/school-book.min.css b/packages/baoyu-md/src/code-themes/school-book.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/school-book.min.css rename to packages/baoyu-md/src/code-themes/school-book.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/shades-of-purple.min.css b/packages/baoyu-md/src/code-themes/shades-of-purple.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/shades-of-purple.min.css rename to packages/baoyu-md/src/code-themes/shades-of-purple.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/srcery.min.css b/packages/baoyu-md/src/code-themes/srcery.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/srcery.min.css rename to packages/baoyu-md/src/code-themes/srcery.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/stackoverflow-dark.min.css b/packages/baoyu-md/src/code-themes/stackoverflow-dark.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/stackoverflow-dark.min.css rename to packages/baoyu-md/src/code-themes/stackoverflow-dark.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/stackoverflow-light.min.css b/packages/baoyu-md/src/code-themes/stackoverflow-light.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/stackoverflow-light.min.css rename to packages/baoyu-md/src/code-themes/stackoverflow-light.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/sunburst.min.css b/packages/baoyu-md/src/code-themes/sunburst.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/sunburst.min.css rename to packages/baoyu-md/src/code-themes/sunburst.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/tokyo-night-dark.min.css b/packages/baoyu-md/src/code-themes/tokyo-night-dark.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/tokyo-night-dark.min.css rename to packages/baoyu-md/src/code-themes/tokyo-night-dark.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/tokyo-night-light.min.css b/packages/baoyu-md/src/code-themes/tokyo-night-light.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/tokyo-night-light.min.css rename to packages/baoyu-md/src/code-themes/tokyo-night-light.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/tomorrow-night-blue.min.css b/packages/baoyu-md/src/code-themes/tomorrow-night-blue.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/tomorrow-night-blue.min.css rename to packages/baoyu-md/src/code-themes/tomorrow-night-blue.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/tomorrow-night-bright.min.css b/packages/baoyu-md/src/code-themes/tomorrow-night-bright.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/tomorrow-night-bright.min.css rename to packages/baoyu-md/src/code-themes/tomorrow-night-bright.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/vs.min.css b/packages/baoyu-md/src/code-themes/vs.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/vs.min.css rename to packages/baoyu-md/src/code-themes/vs.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/vs2015.min.css b/packages/baoyu-md/src/code-themes/vs2015.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/vs2015.min.css rename to packages/baoyu-md/src/code-themes/vs2015.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/xcode.min.css b/packages/baoyu-md/src/code-themes/xcode.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/xcode.min.css rename to packages/baoyu-md/src/code-themes/xcode.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/code-themes/xt256.min.css b/packages/baoyu-md/src/code-themes/xt256.min.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/code-themes/xt256.min.css rename to packages/baoyu-md/src/code-themes/xt256.min.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/constants.ts b/packages/baoyu-md/src/constants.ts similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/constants.ts rename to packages/baoyu-md/src/constants.ts diff --git a/packages/baoyu-md/src/content.ts b/packages/baoyu-md/src/content.ts new file mode 100644 index 0000000..6be2b51 --- /dev/null +++ b/packages/baoyu-md/src/content.ts @@ -0,0 +1,105 @@ +import { Lexer } from "marked"; + +export type FrontmatterFields = Record; + +export function parseFrontmatter(content: string): { + frontmatter: FrontmatterFields; + body: string; +} { + const match = content.match(/^\s*---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/); + if (!match) { + return { frontmatter: {}, body: content }; + } + + const frontmatter: FrontmatterFields = {}; + const lines = match[1]!.split("\n"); + for (const line of lines) { + const colonIdx = line.indexOf(":"); + if (colonIdx <= 0) continue; + + const key = line.slice(0, colonIdx).trim(); + const value = line.slice(colonIdx + 1).trim(); + frontmatter[key] = stripWrappingQuotes(value); + } + + return { frontmatter, body: match[2]! }; +} + +export function serializeFrontmatter(frontmatter: FrontmatterFields): string { + const entries = Object.entries(frontmatter); + if (entries.length === 0) return ""; + return `---\n${entries.map(([key, value]) => `${key}: ${value}`).join("\n")}\n---\n`; +} + +export function stripWrappingQuotes(value: string): string { + if (!value) return value; + + const doubleQuoted = value.startsWith('"') && value.endsWith('"'); + const singleQuoted = value.startsWith("'") && value.endsWith("'"); + const cjkDoubleQuoted = value.startsWith("\u201c") && value.endsWith("\u201d"); + const cjkSingleQuoted = value.startsWith("\u2018") && value.endsWith("\u2019"); + + if (doubleQuoted || singleQuoted || cjkDoubleQuoted || cjkSingleQuoted) { + return value.slice(1, -1).trim(); + } + + return value.trim(); +} + +export function toFrontmatterString(value: unknown): string | undefined { + if (typeof value === "string") { + return stripWrappingQuotes(value); + } + if (typeof value === "number" || typeof value === "boolean") { + return String(value); + } + return undefined; +} + +export function pickFirstString( + frontmatter: Record, + keys: string[], +): string | undefined { + for (const key of keys) { + const value = toFrontmatterString(frontmatter[key]); + if (value) return value; + } + return undefined; +} + +export function extractTitleFromMarkdown(markdown: string): string { + const tokens = Lexer.lex(markdown, { gfm: true, breaks: true }); + for (const token of tokens) { + if (token.type !== "heading" || (token.depth !== 1 && token.depth !== 2)) continue; + return stripWrappingQuotes(token.text); + } + return ""; +} + +export function extractSummaryFromBody(body: string, maxLen: number): string { + const lines = body.split("\n"); + + for (const line of lines) { + const trimmed = line.trim(); + if (!trimmed) continue; + if (trimmed.startsWith("#")) continue; + if (trimmed.startsWith("![")) continue; + if (trimmed.startsWith(">")) continue; + if (trimmed.startsWith("-") || trimmed.startsWith("*")) continue; + if (/^\d+\./.test(trimmed)) continue; + if (trimmed.startsWith("```")) continue; + + const cleanText = trimmed + .replace(/\*\*(.+?)\*\*/g, "$1") + .replace(/\*(.+?)\*/g, "$1") + .replace(/\[([^\]]+)\]\([^)]+\)/g, "$1") + .replace(/`([^`]+)`/g, "$1"); + + if (cleanText.length > 20) { + if (cleanText.length <= maxLen) return cleanText; + return `${cleanText.slice(0, maxLen - 3)}...`; + } + } + + return ""; +} diff --git a/packages/baoyu-md/src/document.ts b/packages/baoyu-md/src/document.ts new file mode 100644 index 0000000..e370740 --- /dev/null +++ b/packages/baoyu-md/src/document.ts @@ -0,0 +1,206 @@ +import fs from "node:fs"; +import path from "node:path"; + +import type { ReadTimeResults } from "reading-time"; + +import { + COLOR_PRESETS, + DEFAULT_STYLE, + FONT_FAMILY_MAP, + THEME_STYLE_DEFAULTS, +} from "./constants.js"; +import { + extractSummaryFromBody, + extractTitleFromMarkdown, + pickFirstString, + stripWrappingQuotes, +} from "./content.js"; +import { loadExtendConfig } from "./extend-config.js"; +import { + buildCss, + buildHtmlDocument, + inlineCss, + loadCodeThemeCss, + modifyHtmlStructure, + normalizeInlineCss, + removeFirstHeading, +} from "./html-builder.js"; +import { initRenderer, postProcessHtml, renderMarkdown } from "./renderer.js"; +import { loadThemeCss, normalizeThemeCss } from "./themes.js"; +import type { HtmlDocumentMeta, IOpts, StyleConfig, ThemeName } from "./types.js"; + +export interface RenderMarkdownDocumentOptions { + codeTheme?: string; + countStatus?: boolean; + citeStatus?: boolean; + defaultTitle?: string; + fontFamily?: string; + fontSize?: string; + isMacCodeBlock?: boolean; + isShowLineNumber?: boolean; + keepTitle?: boolean; + legend?: string; + primaryColor?: string; + theme?: ThemeName; + themeMode?: IOpts["themeMode"]; +} + +export interface RenderMarkdownDocumentResult { + contentHtml: string; + html: string; + meta: HtmlDocumentMeta; + readingTime: ReadTimeResults; + style: StyleConfig; + yamlData: Record; +} + +export function resolveColorToken(value?: string): string | undefined { + if (!value) return undefined; + return COLOR_PRESETS[value] ?? value; +} + +export function resolveFontFamilyToken(value?: string): string | undefined { + if (!value) return undefined; + return FONT_FAMILY_MAP[value] ?? value; +} + +export function formatTimestamp(date = new Date()): string { + const pad = (value: number) => String(value).padStart(2, "0"); + return `${date.getFullYear()}${pad(date.getMonth() + 1)}${pad( + date.getDate(), + )}${pad(date.getHours())}${pad(date.getMinutes())}${pad(date.getSeconds())}`; +} + +export function buildMarkdownDocumentMeta( + markdown: string, + yamlData: Record, + defaultTitle = "document", +): HtmlDocumentMeta { + const title = pickFirstString(yamlData, ["title"]) + || extractTitleFromMarkdown(markdown) + || defaultTitle; + const author = pickFirstString(yamlData, ["author"]); + const description = pickFirstString(yamlData, ["description", "summary"]) + || extractSummaryFromBody(markdown, 120); + + return { + title: stripWrappingQuotes(title), + author: author ? stripWrappingQuotes(author) : undefined, + description: description ? stripWrappingQuotes(description) : undefined, + }; +} + +export function resolveMarkdownStyle(options: RenderMarkdownDocumentOptions = {}): StyleConfig { + const theme = options.theme ?? "default"; + const themeDefaults = THEME_STYLE_DEFAULTS[theme] ?? {}; + + return { + ...DEFAULT_STYLE, + ...themeDefaults, + ...(options.primaryColor !== undefined ? { primaryColor: options.primaryColor } : {}), + ...(options.fontFamily !== undefined ? { fontFamily: options.fontFamily } : {}), + ...(options.fontSize !== undefined ? { fontSize: options.fontSize } : {}), + }; +} + +export function resolveRenderOptions( + options: RenderMarkdownDocumentOptions = {}, +): RenderMarkdownDocumentOptions { + const extendConfig = loadExtendConfig(); + + return { + codeTheme: options.codeTheme ?? extendConfig.default_code_theme ?? "github", + countStatus: options.countStatus ?? extendConfig.count ?? false, + citeStatus: options.citeStatus ?? extendConfig.cite ?? false, + defaultTitle: options.defaultTitle, + fontFamily: options.fontFamily ?? resolveFontFamilyToken(extendConfig.default_font_family ?? undefined), + fontSize: options.fontSize ?? extendConfig.default_font_size ?? undefined, + isMacCodeBlock: options.isMacCodeBlock ?? extendConfig.mac_code_block ?? true, + isShowLineNumber: options.isShowLineNumber ?? extendConfig.show_line_number ?? false, + keepTitle: options.keepTitle ?? extendConfig.keep_title ?? false, + legend: options.legend ?? extendConfig.legend ?? "alt", + primaryColor: options.primaryColor ?? resolveColorToken(extendConfig.default_color ?? undefined), + theme: options.theme ?? extendConfig.default_theme ?? "default", + themeMode: options.themeMode, + }; +} + +export async function renderMarkdownDocument( + markdown: string, + options: RenderMarkdownDocumentOptions = {}, +): Promise { + const resolvedOptions = resolveRenderOptions(options); + const theme = resolvedOptions.theme ?? "default"; + const codeTheme = resolvedOptions.codeTheme ?? "github"; + const style = resolveMarkdownStyle(resolvedOptions); + + const { baseCss, themeCss } = loadThemeCss(theme); + const css = normalizeThemeCss(buildCss(baseCss, themeCss, style)); + const codeThemeCss = loadCodeThemeCss(codeTheme); + + const renderer = initRenderer({ + citeStatus: resolvedOptions.citeStatus ?? false, + countStatus: resolvedOptions.countStatus ?? false, + isMacCodeBlock: resolvedOptions.isMacCodeBlock ?? true, + isShowLineNumber: resolvedOptions.isShowLineNumber ?? false, + legend: resolvedOptions.legend ?? "alt", + themeMode: resolvedOptions.themeMode, + }); + + const { yamlData, markdownContent, readingTime } = renderer.parseFrontMatterAndContent(markdown); + const { html: baseHtml, readingTime: readingTimeResult } = renderMarkdown(markdown, renderer); + + let contentHtml = postProcessHtml(baseHtml, readingTimeResult, renderer); + if (!(resolvedOptions.keepTitle ?? false)) { + contentHtml = removeFirstHeading(contentHtml); + } + + const meta = buildMarkdownDocumentMeta( + markdownContent, + yamlData as Record, + resolvedOptions.defaultTitle, + ); + const html = buildHtmlDocument(meta, css, contentHtml, codeThemeCss); + const inlinedHtml = normalizeInlineCss(await inlineCss(html), style); + + return { + contentHtml, + html: modifyHtmlStructure(inlinedHtml), + meta, + readingTime, + style, + yamlData: yamlData as Record, + }; +} + +export async function renderMarkdownFileToHtml( + inputPath: string, + options: RenderMarkdownDocumentOptions = {}, +): Promise { + const markdown = fs.readFileSync(inputPath, "utf-8"); + const outputPath = path.resolve( + path.dirname(inputPath), + `${path.basename(inputPath, path.extname(inputPath))}.html`, + ); + const result = await renderMarkdownDocument(markdown, { + ...options, + defaultTitle: options.defaultTitle ?? path.basename(outputPath, ".html"), + }); + + let backupPath: string | undefined; + if (fs.existsSync(outputPath)) { + backupPath = `${outputPath}.bak-${formatTimestamp()}`; + fs.renameSync(outputPath, backupPath); + } + + fs.writeFileSync(outputPath, result.html, "utf-8"); + + return { + ...result, + backupPath, + outputPath, + }; +} diff --git a/skills/baoyu-markdown-to-html/scripts/md/extend-config.ts b/packages/baoyu-md/src/extend-config.ts similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/extend-config.ts rename to packages/baoyu-md/src/extend-config.ts diff --git a/skills/baoyu-markdown-to-html/scripts/md/extensions/alert.ts b/packages/baoyu-md/src/extensions/alert.ts similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/extensions/alert.ts rename to packages/baoyu-md/src/extensions/alert.ts diff --git a/skills/baoyu-markdown-to-html/scripts/md/extensions/footnotes.ts b/packages/baoyu-md/src/extensions/footnotes.ts similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/extensions/footnotes.ts rename to packages/baoyu-md/src/extensions/footnotes.ts diff --git a/skills/baoyu-markdown-to-html/scripts/md/extensions/index.ts b/packages/baoyu-md/src/extensions/index.ts similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/extensions/index.ts rename to packages/baoyu-md/src/extensions/index.ts diff --git a/skills/baoyu-markdown-to-html/scripts/md/extensions/infographic.ts b/packages/baoyu-md/src/extensions/infographic.ts similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/extensions/infographic.ts rename to packages/baoyu-md/src/extensions/infographic.ts diff --git a/skills/baoyu-markdown-to-html/scripts/md/extensions/katex.ts b/packages/baoyu-md/src/extensions/katex.ts similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/extensions/katex.ts rename to packages/baoyu-md/src/extensions/katex.ts diff --git a/skills/baoyu-markdown-to-html/scripts/md/extensions/markup.ts b/packages/baoyu-md/src/extensions/markup.ts similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/extensions/markup.ts rename to packages/baoyu-md/src/extensions/markup.ts diff --git a/skills/baoyu-markdown-to-html/scripts/md/extensions/plantuml.ts b/packages/baoyu-md/src/extensions/plantuml.ts similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/extensions/plantuml.ts rename to packages/baoyu-md/src/extensions/plantuml.ts diff --git a/skills/baoyu-markdown-to-html/scripts/md/extensions/ruby.ts b/packages/baoyu-md/src/extensions/ruby.ts similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/extensions/ruby.ts rename to packages/baoyu-md/src/extensions/ruby.ts diff --git a/skills/baoyu-markdown-to-html/scripts/md/extensions/slider.ts b/packages/baoyu-md/src/extensions/slider.ts similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/extensions/slider.ts rename to packages/baoyu-md/src/extensions/slider.ts diff --git a/skills/baoyu-markdown-to-html/scripts/md/extensions/toc.ts b/packages/baoyu-md/src/extensions/toc.ts similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/extensions/toc.ts rename to packages/baoyu-md/src/extensions/toc.ts diff --git a/skills/baoyu-markdown-to-html/scripts/md/html-builder.ts b/packages/baoyu-md/src/html-builder.ts similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/html-builder.ts rename to packages/baoyu-md/src/html-builder.ts diff --git a/packages/baoyu-md/src/images.ts b/packages/baoyu-md/src/images.ts new file mode 100644 index 0000000..f0a3f00 --- /dev/null +++ b/packages/baoyu-md/src/images.ts @@ -0,0 +1,127 @@ +import { createHash } from "node:crypto"; +import fs from "node:fs"; +import http from "node:http"; +import https from "node:https"; +import path from "node:path"; + +export interface ImagePlaceholder { + originalPath: string; + placeholder: string; +} + +export interface ResolvedImageInfo extends ImagePlaceholder { + localPath: string; +} + +export function replaceMarkdownImagesWithPlaceholders( + markdown: string, + placeholderPrefix: string, +): { + images: ImagePlaceholder[]; + markdown: string; +} { + const images: ImagePlaceholder[] = []; + let imageCounter = 0; + + const rewritten = markdown.replace(/!\[([^\]]*)\]\(([^)]+)\)/g, (_match, _alt, src) => { + const placeholder = `${placeholderPrefix}${++imageCounter}`; + images.push({ + originalPath: src, + placeholder, + }); + return placeholder; + }); + + return { images, markdown: rewritten }; +} + +export function getImageExtension(urlOrPath: string): string { + const match = urlOrPath.match(/\.(jpg|jpeg|png|gif|webp)(\?|$)/i); + return match ? match[1]!.toLowerCase() : "png"; +} + +export async function downloadFile(url: string, destPath: string): Promise { + return await new Promise((resolve, reject) => { + const protocol = url.startsWith("https://") ? https : http; + const file = fs.createWriteStream(destPath); + + const request = protocol.get(url, { headers: { "User-Agent": "Mozilla/5.0" } }, (response) => { + if (response.statusCode === 301 || response.statusCode === 302) { + const redirectUrl = response.headers.location; + if (redirectUrl) { + file.close(); + fs.unlinkSync(destPath); + void downloadFile(redirectUrl, destPath).then(resolve).catch(reject); + return; + } + } + + if (response.statusCode !== 200) { + file.close(); + fs.unlinkSync(destPath); + reject(new Error(`Failed to download: ${response.statusCode}`)); + return; + } + + response.pipe(file); + file.on("finish", () => { + file.close(); + resolve(); + }); + }); + + request.on("error", (error) => { + file.close(); + fs.unlink(destPath, () => {}); + reject(error); + }); + + request.setTimeout(30_000, () => { + request.destroy(); + reject(new Error("Download timeout")); + }); + }); +} + +export async function resolveImagePath( + imagePath: string, + baseDir: string, + tempDir: string, + logLabel = "baoyu-md", +): Promise { + if (imagePath.startsWith("http://") || imagePath.startsWith("https://")) { + const hash = createHash("md5").update(imagePath).digest("hex").slice(0, 8); + const ext = getImageExtension(imagePath); + const localPath = path.join(tempDir, `remote_${hash}.${ext}`); + + if (!fs.existsSync(localPath)) { + console.error(`[${logLabel}] Downloading: ${imagePath}`); + await downloadFile(imagePath, localPath); + } + return localPath; + } + + if (path.isAbsolute(imagePath)) { + return imagePath; + } + + return path.resolve(baseDir, imagePath); +} + +export async function resolveContentImages( + images: ImagePlaceholder[], + baseDir: string, + tempDir: string, + logLabel = "baoyu-md", +): Promise { + const resolved: ResolvedImageInfo[] = []; + + for (const image of images) { + resolved.push({ + ...image, + localPath: await resolveImagePath(image.originalPath, baseDir, tempDir, logLabel), + }); + } + + return resolved; +} diff --git a/packages/baoyu-md/src/index.ts b/packages/baoyu-md/src/index.ts new file mode 100644 index 0000000..eeec395 --- /dev/null +++ b/packages/baoyu-md/src/index.ts @@ -0,0 +1,10 @@ +export * from "./cli.js"; +export * from "./constants.js"; +export * from "./content.js"; +export * from "./document.js"; +export * from "./extend-config.js"; +export * from "./html-builder.js"; +export * from "./images.js"; +export * from "./renderer.js"; +export * from "./themes.js"; +export * from "./types.js"; diff --git a/packages/baoyu-md/src/render.ts b/packages/baoyu-md/src/render.ts new file mode 100644 index 0000000..85415d6 --- /dev/null +++ b/packages/baoyu-md/src/render.ts @@ -0,0 +1,43 @@ +#!/usr/bin/env npx tsx + +import path from "node:path"; +import { parseArgs, printUsage } from "./cli.js"; +import { renderMarkdownFileToHtml } from "./document.js"; + +async function main(): Promise { + const options = parseArgs(process.argv.slice(2)); + if (!options) { + printUsage(); + process.exit(1); + } + + const inputPath = path.resolve(process.cwd(), options.inputPath); + if (!inputPath.toLowerCase().endsWith(".md")) { + console.error("Input file must end with .md"); + process.exit(1); + } + + const result = await renderMarkdownFileToHtml(inputPath, { + codeTheme: options.codeTheme, + countStatus: options.countStatus, + citeStatus: options.citeStatus, + fontFamily: options.fontFamily, + fontSize: options.fontSize, + isMacCodeBlock: options.isMacCodeBlock, + isShowLineNumber: options.isShowLineNumber, + keepTitle: options.keepTitle, + legend: options.legend, + primaryColor: options.primaryColor, + theme: options.theme, + }); + + if (result.backupPath) { + console.log(`Backup created: ${result.backupPath}`); + } + console.log(`HTML written: ${result.outputPath}`); +} + +main().catch((error) => { + console.error(error); + process.exit(1); +}); diff --git a/skills/baoyu-markdown-to-html/scripts/md/renderer.ts b/packages/baoyu-md/src/renderer.ts similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/renderer.ts rename to packages/baoyu-md/src/renderer.ts diff --git a/skills/baoyu-markdown-to-html/scripts/md/themes.ts b/packages/baoyu-md/src/themes.ts similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/themes.ts rename to packages/baoyu-md/src/themes.ts diff --git a/skills/baoyu-markdown-to-html/scripts/md/themes/base.css b/packages/baoyu-md/src/themes/base.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/themes/base.css rename to packages/baoyu-md/src/themes/base.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/themes/default.css b/packages/baoyu-md/src/themes/default.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/themes/default.css rename to packages/baoyu-md/src/themes/default.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/themes/grace.css b/packages/baoyu-md/src/themes/grace.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/themes/grace.css rename to packages/baoyu-md/src/themes/grace.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/themes/modern.css b/packages/baoyu-md/src/themes/modern.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/themes/modern.css rename to packages/baoyu-md/src/themes/modern.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/themes/simple.css b/packages/baoyu-md/src/themes/simple.css similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/themes/simple.css rename to packages/baoyu-md/src/themes/simple.css diff --git a/skills/baoyu-markdown-to-html/scripts/md/types.ts b/packages/baoyu-md/src/types.ts similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/types.ts rename to packages/baoyu-md/src/types.ts diff --git a/skills/baoyu-markdown-to-html/scripts/md/utils/languages.ts b/packages/baoyu-md/src/utils/languages.ts similarity index 100% rename from skills/baoyu-markdown-to-html/scripts/md/utils/languages.ts rename to packages/baoyu-md/src/utils/languages.ts diff --git a/scripts/sync-md-to-wechat.sh b/scripts/sync-md-to-wechat.sh deleted file mode 100755 index fa3c7ad..0000000 --- a/scripts/sync-md-to-wechat.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)" -SRC="$REPO_ROOT/skills/baoyu-markdown-to-html/scripts/md/" -DEST="$REPO_ROOT/skills/baoyu-post-to-wechat/scripts/md/" - -echo "Syncing: $SRC → $DEST" - -rsync -av --delete \ - --exclude 'node_modules/' \ - --exclude 'package-lock.json' \ - "$SRC" "$DEST" - -echo "Installing dependencies..." -cd "$DEST" && npm install - -echo "Done." diff --git a/skills/baoyu-markdown-to-html/scripts/bun.lock b/skills/baoyu-markdown-to-html/scripts/bun.lock new file mode 100644 index 0000000..f27ea0e --- /dev/null +++ b/skills/baoyu-markdown-to-html/scripts/bun.lock @@ -0,0 +1,206 @@ +{ + "lockfileVersion": 1, + "workspaces": { + "": { + "name": "baoyu-markdown-to-html-scripts", + "dependencies": { + "baoyu-md": "file:./vendor/baoyu-md", + }, + }, + }, + "packages": { + "@types/debug": ["@types/debug@4.1.12", "", { "dependencies": { "@types/ms": "*" } }, "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ=="], + + "@types/mdast": ["@types/mdast@4.0.4", "", { "dependencies": { "@types/unist": "*" } }, "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA=="], + + "@types/ms": ["@types/ms@2.1.0", "", {}, "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA=="], + + "@types/unist": ["@types/unist@3.0.3", "", {}, "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="], + + "ansi-colors": ["ansi-colors@4.1.3", "", {}, "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw=="], + + "argparse": ["argparse@1.0.10", "", { "dependencies": { "sprintf-js": "~1.0.2" } }, "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg=="], + + "bail": ["bail@2.0.2", "", {}, "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw=="], + + "baoyu-md": ["baoyu-md@file:vendor/baoyu-md", { "dependencies": { "fflate": "^0.8.2", "front-matter": "^4.0.2", "highlight.js": "^11.11.1", "juice": "^11.0.1", "marked": "^15.0.6", "reading-time": "^1.5.0", "remark-cjk-friendly": "^1.1.0", "remark-parse": "^11.0.0", "remark-stringify": "^11.0.0", "unified": "^11.0.5" } }], + + "boolbase": ["boolbase@1.0.0", "", {}, "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="], + + "character-entities": ["character-entities@2.0.2", "", {}, "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ=="], + + "cheerio": ["cheerio@1.0.0", "", { "dependencies": { "cheerio-select": "^2.1.0", "dom-serializer": "^2.0.0", "domhandler": "^5.0.3", "domutils": "^3.1.0", "encoding-sniffer": "^0.2.0", "htmlparser2": "^9.1.0", "parse5": "^7.1.2", "parse5-htmlparser2-tree-adapter": "^7.0.0", "parse5-parser-stream": "^7.1.2", "undici": "^6.19.5", "whatwg-mimetype": "^4.0.0" } }, "sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww=="], + + "cheerio-select": ["cheerio-select@2.1.0", "", { "dependencies": { "boolbase": "^1.0.0", "css-select": "^5.1.0", "css-what": "^6.1.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.3", "domutils": "^3.0.1" } }, "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g=="], + + "commander": ["commander@12.1.0", "", {}, "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA=="], + + "css-select": ["css-select@5.2.2", "", { "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.1.0", "domhandler": "^5.0.2", "domutils": "^3.0.1", "nth-check": "^2.0.1" } }, "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw=="], + + "css-what": ["css-what@6.2.2", "", {}, "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA=="], + + "debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], + + "decode-named-character-reference": ["decode-named-character-reference@1.3.0", "", { "dependencies": { "character-entities": "^2.0.0" } }, "sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q=="], + + "dequal": ["dequal@2.0.3", "", {}, "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA=="], + + "devlop": ["devlop@1.1.0", "", { "dependencies": { "dequal": "^2.0.0" } }, "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA=="], + + "dom-serializer": ["dom-serializer@2.0.0", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", "entities": "^4.2.0" } }, "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg=="], + + "domelementtype": ["domelementtype@2.3.0", "", {}, "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw=="], + + "domhandler": ["domhandler@5.0.3", "", { "dependencies": { "domelementtype": "^2.3.0" } }, "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w=="], + + "domutils": ["domutils@3.2.2", "", { "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.3" } }, "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw=="], + + "encoding-sniffer": ["encoding-sniffer@0.2.1", "", { "dependencies": { "iconv-lite": "^0.6.3", "whatwg-encoding": "^3.1.1" } }, "sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw=="], + + "entities": ["entities@7.0.1", "", {}, "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA=="], + + "escape-goat": ["escape-goat@3.0.0", "", {}, "sha512-w3PwNZJwRxlp47QGzhuEBldEqVHHhh8/tIPcl6ecf2Bou99cdAt0knihBV0Ecc7CGxYduXVBDheH1K2oADRlvw=="], + + "esprima": ["esprima@4.0.1", "", { "bin": { "esparse": "./bin/esparse.js", "esvalidate": "./bin/esvalidate.js" } }, "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="], + + "extend": ["extend@3.0.2", "", {}, "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="], + + "fflate": ["fflate@0.8.2", "", {}, "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A=="], + + "front-matter": ["front-matter@4.0.2", "", { "dependencies": { "js-yaml": "^3.13.1" } }, "sha512-I8ZuJ/qG92NWX8i5x1Y8qyj3vizhXS31OxjKDu3LKP+7/qBgfIKValiZIEwoVoJKUHlhWtYrktkxV1XsX+pPlg=="], + + "get-east-asian-width": ["get-east-asian-width@1.5.0", "", {}, "sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA=="], + + "highlight.js": ["highlight.js@11.11.1", "", {}, "sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w=="], + + "htmlparser2": ["htmlparser2@9.1.0", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.3", "domutils": "^3.1.0", "entities": "^4.5.0" } }, "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ=="], + + "iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="], + + "is-plain-obj": ["is-plain-obj@4.1.0", "", {}, "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg=="], + + "js-yaml": ["js-yaml@3.14.2", "", { "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg=="], + + "juice": ["juice@11.1.1", "", { "dependencies": { "cheerio": "1.0.0", "commander": "^12.1.0", "entities": "^7.0.0", "mensch": "^0.3.4", "slick": "^1.12.2", "web-resource-inliner": "^8.0.0" }, "bin": { "juice": "bin/juice" } }, "sha512-4SBfZqKcc6DrIS+5b/WiGoWaZsdUPBH+e6SbRlNjJpaIRtfoBhYReAtobIEW6mcLeFFDXLBJMuZwkJLkBJjs2w=="], + + "longest-streak": ["longest-streak@3.1.0", "", {}, "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g=="], + + "marked": ["marked@15.0.12", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-8dD6FusOQSrpv9Z1rdNMdlSgQOIP880DHqnohobOmYLElGEqAL/JvxvuxZO16r4HtjTlfPRDC1hbvxC9dPN2nA=="], + + "mdast-util-from-markdown": ["mdast-util-from-markdown@2.0.3", "", { "dependencies": { "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", "decode-named-character-reference": "^1.0.0", "devlop": "^1.0.0", "mdast-util-to-string": "^4.0.0", "micromark": "^4.0.0", "micromark-util-decode-numeric-character-reference": "^2.0.0", "micromark-util-decode-string": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q=="], + + "mdast-util-phrasing": ["mdast-util-phrasing@4.1.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "unist-util-is": "^6.0.0" } }, "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w=="], + + "mdast-util-to-markdown": ["mdast-util-to-markdown@2.1.2", "", { "dependencies": { "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", "longest-streak": "^3.0.0", "mdast-util-phrasing": "^4.0.0", "mdast-util-to-string": "^4.0.0", "micromark-util-classify-character": "^2.0.0", "micromark-util-decode-string": "^2.0.0", "unist-util-visit": "^5.0.0", "zwitch": "^2.0.0" } }, "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA=="], + + "mdast-util-to-string": ["mdast-util-to-string@4.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0" } }, "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg=="], + + "mensch": ["mensch@0.3.4", "", {}, "sha512-IAeFvcOnV9V0Yk+bFhYR07O3yNina9ANIN5MoXBKYJ/RLYPurd2d0yw14MDhpr9/momp0WofT1bPUh3hkzdi/g=="], + + "micromark": ["micromark@4.0.2", "", { "dependencies": { "@types/debug": "^4.0.0", "debug": "^4.0.0", "decode-named-character-reference": "^1.0.0", "devlop": "^1.0.0", "micromark-core-commonmark": "^2.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-chunked": "^2.0.0", "micromark-util-combine-extensions": "^2.0.0", "micromark-util-decode-numeric-character-reference": "^2.0.0", "micromark-util-encode": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-resolve-all": "^2.0.0", "micromark-util-sanitize-uri": "^2.0.0", "micromark-util-subtokenize": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA=="], + + "micromark-core-commonmark": ["micromark-core-commonmark@2.0.3", "", { "dependencies": { "decode-named-character-reference": "^1.0.0", "devlop": "^1.0.0", "micromark-factory-destination": "^2.0.0", "micromark-factory-label": "^2.0.0", "micromark-factory-space": "^2.0.0", "micromark-factory-title": "^2.0.0", "micromark-factory-whitespace": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-chunked": "^2.0.0", "micromark-util-classify-character": "^2.0.0", "micromark-util-html-tag-name": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-resolve-all": "^2.0.0", "micromark-util-subtokenize": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg=="], + + "micromark-extension-cjk-friendly": ["micromark-extension-cjk-friendly@1.2.3", "", { "dependencies": { "devlop": "^1.1.0", "micromark-extension-cjk-friendly-util": "2.1.1", "micromark-util-chunked": "^2.0.1", "micromark-util-resolve-all": "^2.0.1", "micromark-util-symbol": "^2.0.1" }, "peerDependencies": { "micromark": "^4.0.0", "micromark-util-types": "^2.0.0" }, "optionalPeers": ["micromark-util-types"] }, "sha512-gRzVLUdjXBLX6zNPSnHGDoo+ZTp5zy+MZm0g3sv+3chPXY7l9gW+DnrcHcZh/jiPR6MjPKO4AEJNp4Aw6V9z5Q=="], + + "micromark-extension-cjk-friendly-util": ["micromark-extension-cjk-friendly-util@2.1.1", "", { "dependencies": { "get-east-asian-width": "^1.3.0", "micromark-util-character": "^2.1.1", "micromark-util-symbol": "^2.0.1" } }, "sha512-egs6+12JU2yutskHY55FyR48ZiEcFOJFyk9rsiyIhcJ6IvWB6ABBqVrBw8IobqJTDZ/wdSr9eoXDPb5S2nW1bg=="], + + "micromark-factory-destination": ["micromark-factory-destination@2.0.1", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA=="], + + "micromark-factory-label": ["micromark-factory-label@2.0.1", "", { "dependencies": { "devlop": "^1.0.0", "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg=="], + + "micromark-factory-space": ["micromark-factory-space@2.0.1", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg=="], + + "micromark-factory-title": ["micromark-factory-title@2.0.1", "", { "dependencies": { "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw=="], + + "micromark-factory-whitespace": ["micromark-factory-whitespace@2.0.1", "", { "dependencies": { "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ=="], + + "micromark-util-character": ["micromark-util-character@2.1.1", "", { "dependencies": { "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q=="], + + "micromark-util-chunked": ["micromark-util-chunked@2.0.1", "", { "dependencies": { "micromark-util-symbol": "^2.0.0" } }, "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA=="], + + "micromark-util-classify-character": ["micromark-util-classify-character@2.0.1", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q=="], + + "micromark-util-combine-extensions": ["micromark-util-combine-extensions@2.0.1", "", { "dependencies": { "micromark-util-chunked": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg=="], + + "micromark-util-decode-numeric-character-reference": ["micromark-util-decode-numeric-character-reference@2.0.2", "", { "dependencies": { "micromark-util-symbol": "^2.0.0" } }, "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw=="], + + "micromark-util-decode-string": ["micromark-util-decode-string@2.0.1", "", { "dependencies": { "decode-named-character-reference": "^1.0.0", "micromark-util-character": "^2.0.0", "micromark-util-decode-numeric-character-reference": "^2.0.0", "micromark-util-symbol": "^2.0.0" } }, "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ=="], + + "micromark-util-encode": ["micromark-util-encode@2.0.1", "", {}, "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw=="], + + "micromark-util-html-tag-name": ["micromark-util-html-tag-name@2.0.1", "", {}, "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA=="], + + "micromark-util-normalize-identifier": ["micromark-util-normalize-identifier@2.0.1", "", { "dependencies": { "micromark-util-symbol": "^2.0.0" } }, "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q=="], + + "micromark-util-resolve-all": ["micromark-util-resolve-all@2.0.1", "", { "dependencies": { "micromark-util-types": "^2.0.0" } }, "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg=="], + + "micromark-util-sanitize-uri": ["micromark-util-sanitize-uri@2.0.1", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-encode": "^2.0.0", "micromark-util-symbol": "^2.0.0" } }, "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ=="], + + "micromark-util-subtokenize": ["micromark-util-subtokenize@2.1.0", "", { "dependencies": { "devlop": "^1.0.0", "micromark-util-chunked": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA=="], + + "micromark-util-symbol": ["micromark-util-symbol@2.0.1", "", {}, "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q=="], + + "micromark-util-types": ["micromark-util-types@2.0.2", "", {}, "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA=="], + + "mime": ["mime@2.6.0", "", { "bin": { "mime": "cli.js" } }, "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg=="], + + "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], + + "nth-check": ["nth-check@2.1.1", "", { "dependencies": { "boolbase": "^1.0.0" } }, "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w=="], + + "parse5": ["parse5@7.3.0", "", { "dependencies": { "entities": "^6.0.0" } }, "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw=="], + + "parse5-htmlparser2-tree-adapter": ["parse5-htmlparser2-tree-adapter@7.1.0", "", { "dependencies": { "domhandler": "^5.0.3", "parse5": "^7.0.0" } }, "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g=="], + + "parse5-parser-stream": ["parse5-parser-stream@7.1.2", "", { "dependencies": { "parse5": "^7.0.0" } }, "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow=="], + + "reading-time": ["reading-time@1.5.0", "", {}, "sha512-onYyVhBNr4CmAxFsKS7bz+uTLRakypIe4R+5A824vBSkQy/hB3fZepoVEf8OVAxzLvK+H/jm9TzpI3ETSm64Kg=="], + + "remark-cjk-friendly": ["remark-cjk-friendly@1.2.3", "", { "dependencies": { "micromark-extension-cjk-friendly": "1.2.3" }, "peerDependencies": { "@types/mdast": "^4.0.0", "unified": "^11.0.0" }, "optionalPeers": ["@types/mdast"] }, "sha512-UvAgxwlNk+l9Oqgl/9MWK2eWRS7zgBW/nXX9AthV7nd/3lNejF138E7Xbmk9Zs4WjTJGs721r7fAEc7tNFoH7g=="], + + "remark-parse": ["remark-parse@11.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-from-markdown": "^2.0.0", "micromark-util-types": "^2.0.0", "unified": "^11.0.0" } }, "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA=="], + + "remark-stringify": ["remark-stringify@11.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-to-markdown": "^2.0.0", "unified": "^11.0.0" } }, "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw=="], + + "safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="], + + "slick": ["slick@1.12.2", "", {}, "sha512-4qdtOGcBjral6YIBCWJ0ljFSKNLz9KkhbWtuGvUyRowl1kxfuE1x/Z/aJcaiilpb3do9bl5K7/1h9XC5wWpY/A=="], + + "sprintf-js": ["sprintf-js@1.0.3", "", {}, "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g=="], + + "trough": ["trough@2.2.0", "", {}, "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw=="], + + "undici": ["undici@6.24.0", "", {}, "sha512-lVLNosgqo5EkGqh5XUDhGfsMSoO8K0BAN0TyJLvwNRSl4xWGZlCVYsAIpa/OpA3TvmnM01GWcoKmc3ZWo5wKKA=="], + + "unified": ["unified@11.0.5", "", { "dependencies": { "@types/unist": "^3.0.0", "bail": "^2.0.0", "devlop": "^1.0.0", "extend": "^3.0.0", "is-plain-obj": "^4.0.0", "trough": "^2.0.0", "vfile": "^6.0.0" } }, "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA=="], + + "unist-util-is": ["unist-util-is@6.0.1", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g=="], + + "unist-util-stringify-position": ["unist-util-stringify-position@4.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ=="], + + "unist-util-visit": ["unist-util-visit@5.1.0", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0", "unist-util-visit-parents": "^6.0.0" } }, "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg=="], + + "unist-util-visit-parents": ["unist-util-visit-parents@6.0.2", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0" } }, "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ=="], + + "valid-data-url": ["valid-data-url@3.0.1", "", {}, "sha512-jOWVmzVceKlVVdwjNSenT4PbGghU0SBIizAev8ofZVgivk/TVHXSbNL8LP6M3spZvkR9/QolkyJavGSX5Cs0UA=="], + + "vfile": ["vfile@6.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "vfile-message": "^4.0.0" } }, "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q=="], + + "vfile-message": ["vfile-message@4.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw=="], + + "web-resource-inliner": ["web-resource-inliner@8.0.0", "", { "dependencies": { "ansi-colors": "^4.1.1", "escape-goat": "^3.0.0", "htmlparser2": "^9.1.0", "mime": "^2.4.6", "valid-data-url": "^3.0.0" } }, "sha512-Ezr98sqXW/+OCGoUEXuOKVR+oVFlSdn1tIySEEJdiSAw4IjrW8hQkwARSSBJTSB5Us5dnytDgL0ZDliAYBhaNA=="], + + "whatwg-encoding": ["whatwg-encoding@3.1.1", "", { "dependencies": { "iconv-lite": "0.6.3" } }, "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ=="], + + "whatwg-mimetype": ["whatwg-mimetype@4.0.0", "", {}, "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg=="], + + "zwitch": ["zwitch@2.0.4", "", {}, "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A=="], + + "dom-serializer/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="], + + "htmlparser2/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="], + + "parse5/entities": ["entities@6.0.1", "", {}, "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="], + } +} diff --git a/skills/baoyu-markdown-to-html/scripts/main.ts b/skills/baoyu-markdown-to-html/scripts/main.ts index 8e069dc..9b25c56 100644 --- a/skills/baoyu-markdown-to-html/scripts/main.ts +++ b/skills/baoyu-markdown-to-html/scripts/main.ts @@ -1,17 +1,19 @@ -import fs from 'node:fs'; -import path from 'node:path'; -import { createHash } from 'node:crypto'; -import https from 'node:https'; -import http from 'node:http'; -import process from 'node:process'; -import type { StyleConfig, HtmlDocumentMeta } from './md/types.js'; -import { DEFAULT_STYLE, THEME_STYLE_DEFAULTS } from './md/constants.js'; -import { loadThemeCss, normalizeThemeCss } from './md/themes.js'; -import { initRenderer, renderMarkdown, postProcessHtml } from './md/renderer.js'; +import fs from "node:fs"; +import os from "node:os"; +import path from "node:path"; +import process from "node:process"; + import { - buildCss, loadCodeThemeCss, buildHtmlDocument, - inlineCss, normalizeInlineCss, modifyHtmlStructure, removeFirstHeading, -} from './md/html-builder.js'; + extractSummaryFromBody, + extractTitleFromMarkdown, + formatTimestamp, + parseFrontmatter, + renderMarkdownDocument, + replaceMarkdownImagesWithPlaceholders, + resolveContentImages, + serializeFrontmatter, + stripWrappingQuotes, +} from "baoyu-md"; interface ImageInfo { placeholder: string; @@ -28,192 +30,50 @@ interface ParsedResult { contentImages: ImageInfo[]; } -function formatTimestamp(date = new Date()): string { - const pad = (v: number) => String(v).padStart(2, '0'); - return `${date.getFullYear()}${pad(date.getMonth() + 1)}${pad(date.getDate())}${pad(date.getHours())}${pad(date.getMinutes())}${pad(date.getSeconds())}`; -} - -function downloadFile(url: string, destPath: string): Promise { - return new Promise((resolve, reject) => { - const protocol = url.startsWith('https') ? https : http; - const file = fs.createWriteStream(destPath); - - const request = protocol.get(url, { headers: { 'User-Agent': 'Mozilla/5.0' } }, (response) => { - if (response.statusCode === 301 || response.statusCode === 302) { - const redirectUrl = response.headers.location; - if (redirectUrl) { - file.close(); - fs.unlinkSync(destPath); - downloadFile(redirectUrl, destPath).then(resolve).catch(reject); - return; - } - } - - if (response.statusCode !== 200) { - file.close(); - fs.unlinkSync(destPath); - reject(new Error(`Failed to download: ${response.statusCode}`)); - return; - } - - response.pipe(file); - file.on('finish', () => { - file.close(); - resolve(); - }); - }); - - request.on('error', (err) => { - file.close(); - fs.unlink(destPath, () => {}); - reject(err); - }); - - request.setTimeout(30000, () => { - request.destroy(); - reject(new Error('Download timeout')); - }); - }); -} - -function getImageExtension(urlOrPath: string): string { - const match = urlOrPath.match(/\.(jpg|jpeg|png|gif|webp)(\?|$)/i); - return match ? match[1]!.toLowerCase() : 'png'; -} - -async function resolveImagePath(imagePath: string, baseDir: string, tempDir: string): Promise { - if (imagePath.startsWith('http://') || imagePath.startsWith('https://')) { - const hash = createHash('md5').update(imagePath).digest('hex').slice(0, 8); - const ext = getImageExtension(imagePath); - const localPath = path.join(tempDir, `remote_${hash}.${ext}`); - - if (!fs.existsSync(localPath)) { - console.error(`[markdown-to-html] Downloading: ${imagePath}`); - await downloadFile(imagePath, localPath); - } - return localPath; - } - - if (path.isAbsolute(imagePath)) { - return imagePath; - } - - return path.resolve(baseDir, imagePath); -} - -function parseFrontmatter(content: string): { frontmatter: Record; body: string } { - const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/); - if (!match) return { frontmatter: {}, body: content }; - - const frontmatter: Record = {}; - const lines = match[1]!.split('\n'); - for (const line of lines) { - const colonIdx = line.indexOf(':'); - if (colonIdx > 0) { - const key = line.slice(0, colonIdx).trim(); - let value = line.slice(colonIdx + 1).trim(); - if ((value.startsWith('"') && value.endsWith('"')) || (value.startsWith("'") && value.endsWith("'"))) { - value = value.slice(1, -1); - } - frontmatter[key] = value; - } - } - - return { frontmatter, body: match[2]! }; -} - export async function convertMarkdown( markdownPath: string, - options?: { title?: string; theme?: string; keepTitle?: boolean; citeStatus?: boolean } + options?: { title?: string; theme?: string; keepTitle?: boolean; citeStatus?: boolean }, ): Promise { const baseDir = path.dirname(markdownPath); - const content = fs.readFileSync(markdownPath, 'utf-8'); - const theme = options?.theme ?? 'default'; + const content = fs.readFileSync(markdownPath, "utf-8"); + const theme = options?.theme; const keepTitle = options?.keepTitle ?? false; const citeStatus = options?.citeStatus ?? false; const { frontmatter, body } = parseFrontmatter(content); - const stripQuotes = (s?: string): string => { - if (!s) return ''; - if ((s.startsWith('"') && s.endsWith('"')) || (s.startsWith("'") && s.endsWith("'"))) { - return s.slice(1, -1); - } - if ((s.startsWith('\u201c') && s.endsWith('\u201d')) || (s.startsWith('\u2018') && s.endsWith('\u2019'))) { - return s.slice(1, -1); - } - return s; - }; - - let title = options?.title ?? stripQuotes(frontmatter.title) ?? ''; + let title = stripWrappingQuotes(options?.title ?? "") + || stripWrappingQuotes(frontmatter.title ?? "") + || extractTitleFromMarkdown(body); if (!title) { - const lines = body.split('\n'); - for (const line of lines) { - const trimmed = line.trim(); - if (!trimmed) continue; - const headingMatch = trimmed.match(/^#{1,2}\s+(.+)$/); - if (headingMatch) title = headingMatch[1]!; - break; - } + title = path.basename(markdownPath, path.extname(markdownPath)); } - if (!title) title = path.basename(markdownPath, path.extname(markdownPath)); - const author = stripQuotes(frontmatter.author); - let summary = stripQuotes(frontmatter.description) || stripQuotes(frontmatter.summary); + const author = stripWrappingQuotes(frontmatter.author ?? ""); + let summary = stripWrappingQuotes(frontmatter.description ?? "") + || stripWrappingQuotes(frontmatter.summary ?? ""); if (!summary) { - const lines = body.split('\n'); - for (const line of lines) { - const trimmed = line.trim(); - if (!trimmed) continue; - if (trimmed.startsWith('#')) continue; - if (trimmed.startsWith('![')) continue; - if (trimmed.startsWith('>')) continue; - if (trimmed.startsWith('-') || trimmed.startsWith('*')) continue; - if (/^\d+\./.test(trimmed)) continue; - - const cleanText = trimmed - .replace(/\*\*(.+?)\*\*/g, '$1') - .replace(/\*(.+?)\*/g, '$1') - .replace(/\[([^\]]+)\]\([^)]+\)/g, '$1') - .replace(/`([^`]+)`/g, '$1'); - - if (cleanText.length > 20) { - summary = cleanText.length > 120 ? cleanText.slice(0, 117) + '...' : cleanText; - break; - } - } + summary = extractSummaryFromBody(body, 120); } - const images: Array<{ src: string; placeholder: string }> = []; - let imageCounter = 0; + const { images, markdown: rewrittenBody } = replaceMarkdownImagesWithPlaceholders( + body, + "MDTOHTMLIMGPH_", + ); + const rewrittenMarkdown = `${serializeFrontmatter(frontmatter)}${rewrittenBody}`; - const modifiedBody = body.replace(/!\[([^\]]*)\]\(([^)]+)\)/g, (match, alt, src) => { - const placeholder = `MDTOHTMLIMGPH_${++imageCounter}`; - images.push({ src, placeholder }); - return placeholder; + console.error( + `[markdown-to-html] Rendering with theme: ${theme ?? "default"}, keepTitle: ${keepTitle}, citeStatus: ${citeStatus}`, + ); + + const { html } = await renderMarkdownDocument(rewrittenMarkdown, { + citeStatus, + defaultTitle: title, + keepTitle, + theme, }); - const modifiedMarkdown = `---\n${Object.entries(frontmatter).map(([k, v]) => `${k}: ${v}`).join('\n')}\n---\n${modifiedBody}`; - - console.error(`[markdown-to-html] Rendering with theme: ${theme}, keepTitle: ${keepTitle}, citeStatus: ${citeStatus}`); - - const themeDefaults = THEME_STYLE_DEFAULTS[theme] ?? {}; - const style: StyleConfig = { ...DEFAULT_STYLE, ...themeDefaults }; - const { baseCss, themeCss } = loadThemeCss(theme); - const css = normalizeThemeCss(buildCss(baseCss, themeCss, style)); - const codeThemeCss = loadCodeThemeCss('github'); - - const renderer = initRenderer({ citeStatus }); - const { html: baseHtml, readingTime } = renderMarkdown(modifiedMarkdown, renderer); - let htmlContent = postProcessHtml(baseHtml, readingTime, renderer); - if (!keepTitle) htmlContent = removeFirstHeading(htmlContent); - - const meta: HtmlDocumentMeta = { title, author, description: summary }; - const fullHtml = buildHtmlDocument(meta, css, htmlContent, codeThemeCss); - const inlinedHtml = normalizeInlineCss(await inlineCss(fullHtml), style); - const renderedHtml = modifyHtmlStructure(inlinedHtml); - - const finalHtmlPath = markdownPath.replace(/\.md$/i, '.html'); + const finalHtmlPath = markdownPath.replace(/\.md$/i, ".html"); let backupPath: string | undefined; if (fs.existsSync(finalHtmlPath)) { @@ -222,29 +82,22 @@ export async function convertMarkdown( fs.renameSync(finalHtmlPath, backupPath); } - fs.writeFileSync(finalHtmlPath, renderedHtml, 'utf-8'); + fs.writeFileSync(finalHtmlPath, html, "utf-8"); - const contentImages: ImageInfo[] = []; - let tempDir: string | undefined; - for (const img of images) { - if (!tempDir && (img.src.startsWith('http://') || img.src.startsWith('https://'))) { - const os = await import('node:os'); - tempDir = fs.mkdtempSync(path.join(os.default.tmpdir(), 'markdown-to-html-')); - } - const localPath = await resolveImagePath(img.src, baseDir, tempDir ?? baseDir); - contentImages.push({ - placeholder: img.placeholder, - localPath, - originalPath: img.src, - }); - } + const hasRemoteImages = images.some((image) => + image.originalPath.startsWith("http://") || image.originalPath.startsWith("https://"), + ); + const tempDir = hasRemoteImages + ? fs.mkdtempSync(path.join(os.tmpdir(), "markdown-to-html-")) + : baseDir; + const contentImages = await resolveContentImages(images, baseDir, tempDir, "markdown-to-html"); - let finalContent = fs.readFileSync(finalHtmlPath, 'utf-8'); - for (const img of contentImages) { - const imgTag = ``; - finalContent = finalContent.replace(img.placeholder, imgTag); + let finalContent = fs.readFileSync(finalHtmlPath, "utf-8"); + for (const image of contentImages) { + const imgTag = ``; + finalContent = finalContent.replace(image.placeholder, imgTag); } - fs.writeFileSync(finalHtmlPath, finalContent, 'utf-8'); + fs.writeFileSync(finalHtmlPath, finalContent, "utf-8"); console.error(`[markdown-to-html] HTML saved to: ${finalHtmlPath}`); @@ -296,7 +149,7 @@ Example: async function main(): Promise { const args = process.argv.slice(2); - if (args.length === 0 || args.includes('--help') || args.includes('-h')) { + if (args.length === 0 || args.includes("--help") || args.includes("-h")) { printUsage(); } @@ -308,21 +161,21 @@ async function main(): Promise { for (let i = 0; i < args.length; i++) { const arg = args[i]!; - if (arg === '--title' && args[i + 1]) { + if (arg === "--title" && args[i + 1]) { title = args[++i]; - } else if (arg === '--theme' && args[i + 1]) { + } else if (arg === "--theme" && args[i + 1]) { theme = args[++i]; - } else if (arg === '--cite') { + } else if (arg === "--cite") { citeStatus = true; - } else if (arg === '--keep-title') { + } else if (arg === "--keep-title") { keepTitle = true; - } else if (!arg.startsWith('-')) { + } else if (!arg.startsWith("-")) { markdownPath = arg; } } if (!markdownPath) { - console.error('Error: Markdown file path is required'); + console.error("Error: Markdown file path is required"); process.exit(1); } @@ -335,7 +188,7 @@ async function main(): Promise { console.log(JSON.stringify(result, null, 2)); } -await main().catch((err) => { - console.error(`Error: ${err instanceof Error ? err.message : String(err)}`); +await main().catch((error) => { + console.error(`Error: ${error instanceof Error ? error.message : String(error)}`); process.exit(1); }); diff --git a/skills/baoyu-markdown-to-html/scripts/md/package-lock.json b/skills/baoyu-markdown-to-html/scripts/md/package-lock.json deleted file mode 100644 index 202469d..0000000 --- a/skills/baoyu-markdown-to-html/scripts/md/package-lock.json +++ /dev/null @@ -1,1395 +0,0 @@ -{ - "name": "md", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "dependencies": { - "fflate": "^0.8.2", - "front-matter": "^4.0.2", - "highlight.js": "^11.11.1", - "juice": "^11.0.1", - "marked": "^15.0.6", - "reading-time": "^1.5.0", - "remark-cjk-friendly": "^1.1.0", - "remark-parse": "^11.0.0", - "remark-stringify": "^11.0.0", - "unified": "^11.0.5" - } - }, - "node_modules/@types/debug": { - "version": "4.1.12", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", - "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", - "license": "MIT", - "dependencies": { - "@types/ms": "*" - } - }, - "node_modules/@types/mdast": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", - "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", - "license": "MIT", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/@types/ms": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", - "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", - "license": "MIT" - }, - "node_modules/@types/unist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", - "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", - "license": "MIT" - }, - "node_modules/ansi-colors": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", - "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "license": "MIT", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/bail": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", - "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", - "license": "ISC" - }, - "node_modules/character-entities": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", - "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/cheerio": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0.tgz", - "integrity": "sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww==", - "license": "MIT", - "dependencies": { - "cheerio-select": "^2.1.0", - "dom-serializer": "^2.0.0", - "domhandler": "^5.0.3", - "domutils": "^3.1.0", - "encoding-sniffer": "^0.2.0", - "htmlparser2": "^9.1.0", - "parse5": "^7.1.2", - "parse5-htmlparser2-tree-adapter": "^7.0.0", - "parse5-parser-stream": "^7.1.2", - "undici": "^6.19.5", - "whatwg-mimetype": "^4.0.0" - }, - "engines": { - "node": ">=18.17" - }, - "funding": { - "url": "https://github.com/cheeriojs/cheerio?sponsor=1" - } - }, - "node_modules/cheerio-select": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", - "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0", - "css-select": "^5.1.0", - "css-what": "^6.1.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/commander": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", - "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/css-select": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", - "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==", - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.1.0", - "domhandler": "^5.0.2", - "domutils": "^3.0.1", - "nth-check": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/css-what": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz", - "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==", - "license": "BSD-2-Clause", - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decode-named-character-reference": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.3.0.tgz", - "integrity": "sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==", - "license": "MIT", - "dependencies": { - "character-entities": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/dequal": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", - "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/devlop": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", - "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", - "license": "MIT", - "dependencies": { - "dequal": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/dom-serializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", - "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", - "license": "MIT", - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.2", - "entities": "^4.2.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "node_modules/dom-serializer/node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/domelementtype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "license": "BSD-2-Clause" - }, - "node_modules/domhandler": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", - "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", - "license": "BSD-2-Clause", - "dependencies": { - "domelementtype": "^2.3.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/domutils": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", - "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", - "license": "BSD-2-Clause", - "dependencies": { - "dom-serializer": "^2.0.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, - "node_modules/encoding-sniffer": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.1.tgz", - "integrity": "sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==", - "license": "MIT", - "dependencies": { - "iconv-lite": "^0.6.3", - "whatwg-encoding": "^3.1.1" - }, - "funding": { - "url": "https://github.com/fb55/encoding-sniffer?sponsor=1" - } - }, - "node_modules/entities": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz", - "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/escape-goat": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-3.0.0.tgz", - "integrity": "sha512-w3PwNZJwRxlp47QGzhuEBldEqVHHhh8/tIPcl6ecf2Bou99cdAt0knihBV0Ecc7CGxYduXVBDheH1K2oADRlvw==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "license": "BSD-2-Clause", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "license": "MIT" - }, - "node_modules/fflate": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", - "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==", - "license": "MIT" - }, - "node_modules/front-matter": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/front-matter/-/front-matter-4.0.2.tgz", - "integrity": "sha512-I8ZuJ/qG92NWX8i5x1Y8qyj3vizhXS31OxjKDu3LKP+7/qBgfIKValiZIEwoVoJKUHlhWtYrktkxV1XsX+pPlg==", - "license": "MIT", - "dependencies": { - "js-yaml": "^3.13.1" - } - }, - "node_modules/get-east-asian-width": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.4.0.tgz", - "integrity": "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/highlight.js": { - "version": "11.11.1", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.11.1.tgz", - "integrity": "sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/htmlparser2": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz", - "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==", - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "license": "MIT", - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.1.0", - "entities": "^4.5.0" - } - }, - "node_modules/htmlparser2/node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-plain-obj": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", - "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/js-yaml": { - "version": "3.14.2", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", - "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", - "license": "MIT", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/juice": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/juice/-/juice-11.1.0.tgz", - "integrity": "sha512-jZj/pUGFddSU7HS6ThAdiQ21IILIM23JNdFNgTacwxFUMTw/6qvMv3suv/I66Bz2xZ6yC3Vl8fWl0At/wVcH3A==", - "license": "MIT", - "dependencies": { - "cheerio": "1.0.0", - "commander": "^12.1.0", - "entities": "^7.0.0", - "mensch": "^0.3.4", - "slick": "^1.12.2", - "web-resource-inliner": "^8.0.0" - }, - "bin": { - "juice": "bin/juice" - }, - "engines": { - "node": ">=18.17" - } - }, - "node_modules/longest-streak": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", - "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/marked": { - "version": "15.0.12", - "resolved": "https://registry.npmjs.org/marked/-/marked-15.0.12.tgz", - "integrity": "sha512-8dD6FusOQSrpv9Z1rdNMdlSgQOIP880DHqnohobOmYLElGEqAL/JvxvuxZO16r4HtjTlfPRDC1hbvxC9dPN2nA==", - "license": "MIT", - "bin": { - "marked": "bin/marked.js" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/mdast-util-from-markdown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz", - "integrity": "sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "mdast-util-to-string": "^4.0.0", - "micromark": "^4.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-decode-string": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-phrasing": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", - "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-markdown": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz", - "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "longest-streak": "^3.0.0", - "mdast-util-phrasing": "^4.0.0", - "mdast-util-to-string": "^4.0.0", - "micromark-util-classify-character": "^2.0.0", - "micromark-util-decode-string": "^2.0.0", - "unist-util-visit": "^5.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", - "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mensch": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/mensch/-/mensch-0.3.4.tgz", - "integrity": "sha512-IAeFvcOnV9V0Yk+bFhYR07O3yNina9ANIN5MoXBKYJ/RLYPurd2d0yw14MDhpr9/momp0WofT1bPUh3hkzdi/g==", - "license": "MIT" - }, - "node_modules/micromark": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", - "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "@types/debug": "^4.0.0", - "debug": "^4.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-combine-extensions": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-core-commonmark": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz", - "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-factory-destination": "^2.0.0", - "micromark-factory-label": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-factory-title": "^2.0.0", - "micromark-factory-whitespace": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-classify-character": "^2.0.0", - "micromark-util-html-tag-name": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-cjk-friendly": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/micromark-extension-cjk-friendly/-/micromark-extension-cjk-friendly-1.2.3.tgz", - "integrity": "sha512-gRzVLUdjXBLX6zNPSnHGDoo+ZTp5zy+MZm0g3sv+3chPXY7l9gW+DnrcHcZh/jiPR6MjPKO4AEJNp4Aw6V9z5Q==", - "license": "MIT", - "dependencies": { - "devlop": "^1.1.0", - "micromark-extension-cjk-friendly-util": "2.1.1", - "micromark-util-chunked": "^2.0.1", - "micromark-util-resolve-all": "^2.0.1", - "micromark-util-symbol": "^2.0.1" - }, - "engines": { - "node": ">=16" - }, - "peerDependencies": { - "micromark": "^4.0.0", - "micromark-util-types": "^2.0.0" - }, - "peerDependenciesMeta": { - "micromark-util-types": { - "optional": true - } - } - }, - "node_modules/micromark-extension-cjk-friendly-util": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-extension-cjk-friendly-util/-/micromark-extension-cjk-friendly-util-2.1.1.tgz", - "integrity": "sha512-egs6+12JU2yutskHY55FyR48ZiEcFOJFyk9rsiyIhcJ6IvWB6ABBqVrBw8IobqJTDZ/wdSr9eoXDPb5S2nW1bg==", - "license": "MIT", - "dependencies": { - "get-east-asian-width": "^1.3.0", - "micromark-util-character": "^2.1.1", - "micromark-util-symbol": "^2.0.1" - }, - "engines": { - "node": ">=16" - }, - "peerDependenciesMeta": { - "micromark-util-types": { - "optional": true - } - } - }, - "node_modules/micromark-factory-destination": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", - "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-label": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", - "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-space": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", - "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-title": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", - "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-whitespace": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", - "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-character": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", - "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-chunked": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", - "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-classify-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", - "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-combine-extensions": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", - "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-chunked": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-decode-numeric-character-reference": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", - "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-decode-string": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz", - "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-encode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", - "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-html-tag-name": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", - "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-normalize-identifier": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", - "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-resolve-all": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", - "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-sanitize-uri": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", - "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-subtokenize": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz", - "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", - "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/mime": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", - "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", - "license": "MIT", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/nth-check": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0" - }, - "funding": { - "url": "https://github.com/fb55/nth-check?sponsor=1" - } - }, - "node_modules/parse5": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", - "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", - "license": "MIT", - "dependencies": { - "entities": "^6.0.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/parse5-htmlparser2-tree-adapter": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz", - "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==", - "license": "MIT", - "dependencies": { - "domhandler": "^5.0.3", - "parse5": "^7.0.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/parse5-parser-stream": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz", - "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==", - "license": "MIT", - "dependencies": { - "parse5": "^7.0.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/parse5/node_modules/entities": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", - "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/reading-time": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/reading-time/-/reading-time-1.5.0.tgz", - "integrity": "sha512-onYyVhBNr4CmAxFsKS7bz+uTLRakypIe4R+5A824vBSkQy/hB3fZepoVEf8OVAxzLvK+H/jm9TzpI3ETSm64Kg==", - "license": "MIT" - }, - "node_modules/remark-cjk-friendly": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/remark-cjk-friendly/-/remark-cjk-friendly-1.2.3.tgz", - "integrity": "sha512-UvAgxwlNk+l9Oqgl/9MWK2eWRS7zgBW/nXX9AthV7nd/3lNejF138E7Xbmk9Zs4WjTJGs721r7fAEc7tNFoH7g==", - "license": "MIT", - "dependencies": { - "micromark-extension-cjk-friendly": "1.2.3" - }, - "engines": { - "node": ">=16" - }, - "peerDependencies": { - "@types/mdast": "^4.0.0", - "unified": "^11.0.0" - }, - "peerDependenciesMeta": { - "@types/mdast": { - "optional": true - } - } - }, - "node_modules/remark-parse": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", - "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-from-markdown": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-stringify": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", - "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-to-markdown": "^2.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "license": "MIT" - }, - "node_modules/slick": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/slick/-/slick-1.12.2.tgz", - "integrity": "sha512-4qdtOGcBjral6YIBCWJ0ljFSKNLz9KkhbWtuGvUyRowl1kxfuE1x/Z/aJcaiilpb3do9bl5K7/1h9XC5wWpY/A==", - "license": "MIT (http://mootools.net/license.txt)", - "engines": { - "node": "*" - } - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "license": "BSD-3-Clause" - }, - "node_modules/trough": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", - "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/undici": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.23.0.tgz", - "integrity": "sha512-VfQPToRA5FZs/qJxLIinmU59u0r7LXqoJkCzinq3ckNJp3vKEh7jTWN589YQ5+aoAC/TGRLyJLCPKcLQbM8r9g==", - "license": "MIT", - "engines": { - "node": ">=18.17" - } - }, - "node_modules/unified": { - "version": "11.0.5", - "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", - "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "bail": "^2.0.0", - "devlop": "^1.0.0", - "extend": "^3.0.0", - "is-plain-obj": "^4.0.0", - "trough": "^2.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-is": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.1.tgz", - "integrity": "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-stringify-position": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-visit": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.1.0.tgz", - "integrity": "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-visit-parents": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.2.tgz", - "integrity": "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/valid-data-url": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/valid-data-url/-/valid-data-url-3.0.1.tgz", - "integrity": "sha512-jOWVmzVceKlVVdwjNSenT4PbGghU0SBIizAev8ofZVgivk/TVHXSbNL8LP6M3spZvkR9/QolkyJavGSX5Cs0UA==", - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/vfile": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", - "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/vfile-message": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz", - "integrity": "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/web-resource-inliner": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/web-resource-inliner/-/web-resource-inliner-8.0.0.tgz", - "integrity": "sha512-Ezr98sqXW/+OCGoUEXuOKVR+oVFlSdn1tIySEEJdiSAw4IjrW8hQkwARSSBJTSB5Us5dnytDgL0ZDliAYBhaNA==", - "license": "MIT", - "dependencies": { - "ansi-colors": "^4.1.1", - "escape-goat": "^3.0.0", - "htmlparser2": "^9.1.0", - "mime": "^2.4.6", - "valid-data-url": "^3.0.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/whatwg-encoding": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", - "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", - "deprecated": "Use @exodus/bytes instead for a more spec-conformant and faster implementation", - "license": "MIT", - "dependencies": { - "iconv-lite": "0.6.3" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/whatwg-mimetype": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", - "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/zwitch": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", - "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - } - } -} diff --git a/skills/baoyu-markdown-to-html/scripts/md/render.ts b/skills/baoyu-markdown-to-html/scripts/md/render.ts deleted file mode 100644 index 840dc3e..0000000 --- a/skills/baoyu-markdown-to-html/scripts/md/render.ts +++ /dev/null @@ -1,119 +0,0 @@ -#!/usr/bin/env npx tsx - -import fs from "node:fs"; -import path from "node:path"; -import type { StyleConfig, HtmlDocumentMeta } from "./types.js"; -import { DEFAULT_STYLE, THEME_STYLE_DEFAULTS } from "./constants.js"; -import { loadThemeCss, normalizeThemeCss } from "./themes.js"; -import { parseArgs, printUsage } from "./cli.js"; -import { initRenderer, renderMarkdown, postProcessHtml } from "./renderer.js"; -import { - buildCss, - loadCodeThemeCss, - buildHtmlDocument, - inlineCss, - normalizeInlineCss, - modifyHtmlStructure, - removeFirstHeading, -} from "./html-builder.js"; - -function formatTimestamp(date = new Date()): string { - const pad = (value: number) => String(value).padStart(2, "0"); - return `${date.getFullYear()}${pad(date.getMonth() + 1)}${pad( - date.getDate() - )}${pad(date.getHours())}${pad(date.getMinutes())}${pad(date.getSeconds())}`; -} - -async function main(): Promise { - const options = parseArgs(process.argv.slice(2)); - if (!options) { - printUsage(); - process.exit(1); - } - - const inputPath = path.resolve(process.cwd(), options.inputPath); - if (!inputPath.toLowerCase().endsWith(".md")) { - console.error("Input file must end with .md"); - process.exit(1); - } - - if (!fs.existsSync(inputPath)) { - console.error(`File not found: ${inputPath}`); - process.exit(1); - } - - const outputPath = path.resolve( - process.cwd(), - options.inputPath.replace(/\.md$/i, ".html") - ); - - const themeDefaults = THEME_STYLE_DEFAULTS[options.theme] ?? {}; - const style: StyleConfig = { - ...DEFAULT_STYLE, - ...themeDefaults, - ...(options.primaryColor !== undefined ? { primaryColor: options.primaryColor } : {}), - ...(options.fontFamily !== undefined ? { fontFamily: options.fontFamily } : {}), - ...(options.fontSize !== undefined ? { fontSize: options.fontSize } : {}), - }; - - const { baseCss, themeCss } = loadThemeCss(options.theme); - const css = normalizeThemeCss(buildCss(baseCss, themeCss, style)); - const codeThemeCss = loadCodeThemeCss(options.codeTheme); - - const markdown = fs.readFileSync(inputPath, "utf-8"); - - const renderer = initRenderer({ - legend: options.legend, - citeStatus: options.citeStatus, - countStatus: options.countStatus, - isMacCodeBlock: options.isMacCodeBlock, - isShowLineNumber: options.isShowLineNumber, - }); - const { yamlData } = renderer.parseFrontMatterAndContent(markdown); - const { html: baseHtml, readingTime: readingTimeResult } = renderMarkdown( - markdown, - renderer - ); - let content = postProcessHtml(baseHtml, readingTimeResult, renderer); - if (!options.keepTitle) { - content = removeFirstHeading(content); - } - - const stripQuotes = (s?: string): string | undefined => { - if (!s) return s; - if ((s.startsWith('"') && s.endsWith('"')) || (s.startsWith("'") && s.endsWith("'"))) { - return s.slice(1, -1); - } - if ((s.startsWith('\u201c') && s.endsWith('\u201d')) || (s.startsWith('\u2018') && s.endsWith('\u2019'))) { - return s.slice(1, -1); - } - return s; - }; - - const meta: HtmlDocumentMeta = { - title: stripQuotes(yamlData.title) || path.basename(outputPath, ".html"), - author: stripQuotes(yamlData.author), - description: stripQuotes(yamlData.description) || stripQuotes(yamlData.summary), - }; - const html = buildHtmlDocument(meta, css, content, codeThemeCss); - const inlinedHtml = normalizeInlineCss(await inlineCss(html), style); - const finalHtml = modifyHtmlStructure(inlinedHtml); - - let backupPath = ""; - if (fs.existsSync(outputPath)) { - backupPath = `${outputPath}.bak-${formatTimestamp()}`; - fs.renameSync(outputPath, backupPath); - } - - fs.writeFileSync(outputPath, finalHtml, "utf-8"); - - if (backupPath) { - console.log(`Backup created: ${backupPath}`); - } - console.log(`HTML written: ${outputPath}`); -} - -main().catch((error) => { - console.error(error); - process.exit(1); -}); diff --git a/skills/baoyu-markdown-to-html/scripts/package.json b/skills/baoyu-markdown-to-html/scripts/package.json new file mode 100644 index 0000000..cabd95b --- /dev/null +++ b/skills/baoyu-markdown-to-html/scripts/package.json @@ -0,0 +1,8 @@ +{ + "name": "baoyu-markdown-to-html-scripts", + "private": true, + "type": "module", + "dependencies": { + "baoyu-md": "file:./vendor/baoyu-md" + } +} diff --git a/skills/baoyu-markdown-to-html/scripts/md/package.json b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/package.json similarity index 71% rename from skills/baoyu-markdown-to-html/scripts/md/package.json rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/package.json index 260394d..a6f7086 100644 --- a/skills/baoyu-markdown-to-html/scripts/md/package.json +++ b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/package.json @@ -1,4 +1,11 @@ { + "name": "baoyu-md", + "private": true, + "version": "0.1.0", + "type": "module", + "exports": { + ".": "./src/index.ts" + }, "dependencies": { "fflate": "^0.8.2", "front-matter": "^4.0.2", diff --git a/skills/baoyu-post-to-wechat/scripts/md/LICENSE b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/LICENSE similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/LICENSE rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/LICENSE diff --git a/skills/baoyu-post-to-wechat/scripts/md/cli.ts b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/cli.ts similarity index 98% rename from skills/baoyu-post-to-wechat/scripts/md/cli.ts rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/cli.ts index 5b0263a..5a7861b 100644 --- a/skills/baoyu-post-to-wechat/scripts/md/cli.ts +++ b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/cli.ts @@ -12,7 +12,7 @@ export function printUsage(): void { console.error( [ "Usage:", - " npx tsx src/md/render.ts [options]", + " npx tsx render.ts [options]", "", "Options:", ` --theme Theme (${THEME_NAMES.join(", ")})`, diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/1c-light.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/1c-light.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/1c-light.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/1c-light.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/a11y-dark.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/a11y-dark.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/a11y-dark.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/a11y-dark.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/a11y-light.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/a11y-light.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/a11y-light.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/a11y-light.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/agate.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/agate.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/agate.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/agate.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/an-old-hope.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/an-old-hope.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/an-old-hope.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/an-old-hope.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/androidstudio.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/androidstudio.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/androidstudio.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/androidstudio.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/arduino-light.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/arduino-light.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/arduino-light.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/arduino-light.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/arta.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/arta.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/arta.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/arta.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/ascetic.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/ascetic.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/ascetic.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/ascetic.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/atom-one-dark-reasonable.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/atom-one-dark-reasonable.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/atom-one-dark-reasonable.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/atom-one-dark-reasonable.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/atom-one-dark.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/atom-one-dark.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/atom-one-dark.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/atom-one-dark.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/atom-one-light.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/atom-one-light.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/atom-one-light.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/atom-one-light.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/brown-paper.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/brown-paper.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/brown-paper.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/brown-paper.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/codepen-embed.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/codepen-embed.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/codepen-embed.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/codepen-embed.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/color-brewer.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/color-brewer.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/color-brewer.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/color-brewer.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/dark.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/dark.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/dark.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/dark.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/default.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/default.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/default.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/default.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/devibeans.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/devibeans.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/devibeans.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/devibeans.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/docco.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/docco.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/docco.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/docco.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/far.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/far.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/far.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/far.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/felipec.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/felipec.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/felipec.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/felipec.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/foundation.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/foundation.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/foundation.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/foundation.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/github-dark-dimmed.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/github-dark-dimmed.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/github-dark-dimmed.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/github-dark-dimmed.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/github-dark.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/github-dark.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/github-dark.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/github-dark.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/github.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/github.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/github.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/github.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/gml.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/gml.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/gml.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/gml.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/googlecode.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/googlecode.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/googlecode.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/googlecode.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/gradient-dark.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/gradient-dark.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/gradient-dark.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/gradient-dark.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/gradient-light.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/gradient-light.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/gradient-light.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/gradient-light.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/grayscale.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/grayscale.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/grayscale.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/grayscale.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/hybrid.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/hybrid.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/hybrid.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/hybrid.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/idea.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/idea.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/idea.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/idea.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/intellij-light.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/intellij-light.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/intellij-light.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/intellij-light.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/ir-black.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/ir-black.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/ir-black.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/ir-black.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/isbl-editor-dark.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/isbl-editor-dark.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/isbl-editor-dark.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/isbl-editor-dark.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/isbl-editor-light.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/isbl-editor-light.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/isbl-editor-light.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/isbl-editor-light.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/kimbie-dark.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/kimbie-dark.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/kimbie-dark.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/kimbie-dark.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/kimbie-light.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/kimbie-light.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/kimbie-light.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/kimbie-light.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/lightfair.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/lightfair.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/lightfair.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/lightfair.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/lioshi.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/lioshi.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/lioshi.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/lioshi.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/magula.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/magula.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/magula.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/magula.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/mono-blue.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/mono-blue.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/mono-blue.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/mono-blue.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/monokai-sublime.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/monokai-sublime.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/monokai-sublime.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/monokai-sublime.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/monokai.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/monokai.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/monokai.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/monokai.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/night-owl.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/night-owl.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/night-owl.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/night-owl.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/nnfx-dark.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/nnfx-dark.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/nnfx-dark.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/nnfx-dark.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/nnfx-light.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/nnfx-light.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/nnfx-light.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/nnfx-light.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/nord.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/nord.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/nord.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/nord.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/obsidian.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/obsidian.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/obsidian.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/obsidian.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/panda-syntax-dark.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/panda-syntax-dark.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/panda-syntax-dark.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/panda-syntax-dark.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/panda-syntax-light.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/panda-syntax-light.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/panda-syntax-light.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/panda-syntax-light.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/paraiso-dark.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/paraiso-dark.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/paraiso-dark.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/paraiso-dark.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/paraiso-light.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/paraiso-light.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/paraiso-light.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/paraiso-light.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/pojoaque.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/pojoaque.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/pojoaque.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/pojoaque.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/purebasic.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/purebasic.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/purebasic.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/purebasic.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/qtcreator-dark.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/qtcreator-dark.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/qtcreator-dark.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/qtcreator-dark.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/qtcreator-light.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/qtcreator-light.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/qtcreator-light.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/qtcreator-light.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/rainbow.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/rainbow.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/rainbow.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/rainbow.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/routeros.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/routeros.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/routeros.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/routeros.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/school-book.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/school-book.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/school-book.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/school-book.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/shades-of-purple.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/shades-of-purple.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/shades-of-purple.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/shades-of-purple.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/srcery.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/srcery.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/srcery.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/srcery.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/stackoverflow-dark.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/stackoverflow-dark.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/stackoverflow-dark.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/stackoverflow-dark.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/stackoverflow-light.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/stackoverflow-light.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/stackoverflow-light.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/stackoverflow-light.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/sunburst.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/sunburst.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/sunburst.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/sunburst.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/tokyo-night-dark.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/tokyo-night-dark.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/tokyo-night-dark.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/tokyo-night-dark.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/tokyo-night-light.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/tokyo-night-light.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/tokyo-night-light.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/tokyo-night-light.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/tomorrow-night-blue.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/tomorrow-night-blue.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/tomorrow-night-blue.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/tomorrow-night-blue.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/tomorrow-night-bright.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/tomorrow-night-bright.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/tomorrow-night-bright.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/tomorrow-night-bright.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/vs.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/vs.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/vs.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/vs.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/vs2015.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/vs2015.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/vs2015.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/vs2015.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/xcode.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/xcode.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/xcode.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/xcode.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/code-themes/xt256.min.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/xt256.min.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/code-themes/xt256.min.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/code-themes/xt256.min.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/constants.ts b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/constants.ts similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/constants.ts rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/constants.ts diff --git a/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/content.ts b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/content.ts new file mode 100644 index 0000000..6be2b51 --- /dev/null +++ b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/content.ts @@ -0,0 +1,105 @@ +import { Lexer } from "marked"; + +export type FrontmatterFields = Record; + +export function parseFrontmatter(content: string): { + frontmatter: FrontmatterFields; + body: string; +} { + const match = content.match(/^\s*---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/); + if (!match) { + return { frontmatter: {}, body: content }; + } + + const frontmatter: FrontmatterFields = {}; + const lines = match[1]!.split("\n"); + for (const line of lines) { + const colonIdx = line.indexOf(":"); + if (colonIdx <= 0) continue; + + const key = line.slice(0, colonIdx).trim(); + const value = line.slice(colonIdx + 1).trim(); + frontmatter[key] = stripWrappingQuotes(value); + } + + return { frontmatter, body: match[2]! }; +} + +export function serializeFrontmatter(frontmatter: FrontmatterFields): string { + const entries = Object.entries(frontmatter); + if (entries.length === 0) return ""; + return `---\n${entries.map(([key, value]) => `${key}: ${value}`).join("\n")}\n---\n`; +} + +export function stripWrappingQuotes(value: string): string { + if (!value) return value; + + const doubleQuoted = value.startsWith('"') && value.endsWith('"'); + const singleQuoted = value.startsWith("'") && value.endsWith("'"); + const cjkDoubleQuoted = value.startsWith("\u201c") && value.endsWith("\u201d"); + const cjkSingleQuoted = value.startsWith("\u2018") && value.endsWith("\u2019"); + + if (doubleQuoted || singleQuoted || cjkDoubleQuoted || cjkSingleQuoted) { + return value.slice(1, -1).trim(); + } + + return value.trim(); +} + +export function toFrontmatterString(value: unknown): string | undefined { + if (typeof value === "string") { + return stripWrappingQuotes(value); + } + if (typeof value === "number" || typeof value === "boolean") { + return String(value); + } + return undefined; +} + +export function pickFirstString( + frontmatter: Record, + keys: string[], +): string | undefined { + for (const key of keys) { + const value = toFrontmatterString(frontmatter[key]); + if (value) return value; + } + return undefined; +} + +export function extractTitleFromMarkdown(markdown: string): string { + const tokens = Lexer.lex(markdown, { gfm: true, breaks: true }); + for (const token of tokens) { + if (token.type !== "heading" || (token.depth !== 1 && token.depth !== 2)) continue; + return stripWrappingQuotes(token.text); + } + return ""; +} + +export function extractSummaryFromBody(body: string, maxLen: number): string { + const lines = body.split("\n"); + + for (const line of lines) { + const trimmed = line.trim(); + if (!trimmed) continue; + if (trimmed.startsWith("#")) continue; + if (trimmed.startsWith("![")) continue; + if (trimmed.startsWith(">")) continue; + if (trimmed.startsWith("-") || trimmed.startsWith("*")) continue; + if (/^\d+\./.test(trimmed)) continue; + if (trimmed.startsWith("```")) continue; + + const cleanText = trimmed + .replace(/\*\*(.+?)\*\*/g, "$1") + .replace(/\*(.+?)\*/g, "$1") + .replace(/\[([^\]]+)\]\([^)]+\)/g, "$1") + .replace(/`([^`]+)`/g, "$1"); + + if (cleanText.length > 20) { + if (cleanText.length <= maxLen) return cleanText; + return `${cleanText.slice(0, maxLen - 3)}...`; + } + } + + return ""; +} diff --git a/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/document.ts b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/document.ts new file mode 100644 index 0000000..e370740 --- /dev/null +++ b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/document.ts @@ -0,0 +1,206 @@ +import fs from "node:fs"; +import path from "node:path"; + +import type { ReadTimeResults } from "reading-time"; + +import { + COLOR_PRESETS, + DEFAULT_STYLE, + FONT_FAMILY_MAP, + THEME_STYLE_DEFAULTS, +} from "./constants.js"; +import { + extractSummaryFromBody, + extractTitleFromMarkdown, + pickFirstString, + stripWrappingQuotes, +} from "./content.js"; +import { loadExtendConfig } from "./extend-config.js"; +import { + buildCss, + buildHtmlDocument, + inlineCss, + loadCodeThemeCss, + modifyHtmlStructure, + normalizeInlineCss, + removeFirstHeading, +} from "./html-builder.js"; +import { initRenderer, postProcessHtml, renderMarkdown } from "./renderer.js"; +import { loadThemeCss, normalizeThemeCss } from "./themes.js"; +import type { HtmlDocumentMeta, IOpts, StyleConfig, ThemeName } from "./types.js"; + +export interface RenderMarkdownDocumentOptions { + codeTheme?: string; + countStatus?: boolean; + citeStatus?: boolean; + defaultTitle?: string; + fontFamily?: string; + fontSize?: string; + isMacCodeBlock?: boolean; + isShowLineNumber?: boolean; + keepTitle?: boolean; + legend?: string; + primaryColor?: string; + theme?: ThemeName; + themeMode?: IOpts["themeMode"]; +} + +export interface RenderMarkdownDocumentResult { + contentHtml: string; + html: string; + meta: HtmlDocumentMeta; + readingTime: ReadTimeResults; + style: StyleConfig; + yamlData: Record; +} + +export function resolveColorToken(value?: string): string | undefined { + if (!value) return undefined; + return COLOR_PRESETS[value] ?? value; +} + +export function resolveFontFamilyToken(value?: string): string | undefined { + if (!value) return undefined; + return FONT_FAMILY_MAP[value] ?? value; +} + +export function formatTimestamp(date = new Date()): string { + const pad = (value: number) => String(value).padStart(2, "0"); + return `${date.getFullYear()}${pad(date.getMonth() + 1)}${pad( + date.getDate(), + )}${pad(date.getHours())}${pad(date.getMinutes())}${pad(date.getSeconds())}`; +} + +export function buildMarkdownDocumentMeta( + markdown: string, + yamlData: Record, + defaultTitle = "document", +): HtmlDocumentMeta { + const title = pickFirstString(yamlData, ["title"]) + || extractTitleFromMarkdown(markdown) + || defaultTitle; + const author = pickFirstString(yamlData, ["author"]); + const description = pickFirstString(yamlData, ["description", "summary"]) + || extractSummaryFromBody(markdown, 120); + + return { + title: stripWrappingQuotes(title), + author: author ? stripWrappingQuotes(author) : undefined, + description: description ? stripWrappingQuotes(description) : undefined, + }; +} + +export function resolveMarkdownStyle(options: RenderMarkdownDocumentOptions = {}): StyleConfig { + const theme = options.theme ?? "default"; + const themeDefaults = THEME_STYLE_DEFAULTS[theme] ?? {}; + + return { + ...DEFAULT_STYLE, + ...themeDefaults, + ...(options.primaryColor !== undefined ? { primaryColor: options.primaryColor } : {}), + ...(options.fontFamily !== undefined ? { fontFamily: options.fontFamily } : {}), + ...(options.fontSize !== undefined ? { fontSize: options.fontSize } : {}), + }; +} + +export function resolveRenderOptions( + options: RenderMarkdownDocumentOptions = {}, +): RenderMarkdownDocumentOptions { + const extendConfig = loadExtendConfig(); + + return { + codeTheme: options.codeTheme ?? extendConfig.default_code_theme ?? "github", + countStatus: options.countStatus ?? extendConfig.count ?? false, + citeStatus: options.citeStatus ?? extendConfig.cite ?? false, + defaultTitle: options.defaultTitle, + fontFamily: options.fontFamily ?? resolveFontFamilyToken(extendConfig.default_font_family ?? undefined), + fontSize: options.fontSize ?? extendConfig.default_font_size ?? undefined, + isMacCodeBlock: options.isMacCodeBlock ?? extendConfig.mac_code_block ?? true, + isShowLineNumber: options.isShowLineNumber ?? extendConfig.show_line_number ?? false, + keepTitle: options.keepTitle ?? extendConfig.keep_title ?? false, + legend: options.legend ?? extendConfig.legend ?? "alt", + primaryColor: options.primaryColor ?? resolveColorToken(extendConfig.default_color ?? undefined), + theme: options.theme ?? extendConfig.default_theme ?? "default", + themeMode: options.themeMode, + }; +} + +export async function renderMarkdownDocument( + markdown: string, + options: RenderMarkdownDocumentOptions = {}, +): Promise { + const resolvedOptions = resolveRenderOptions(options); + const theme = resolvedOptions.theme ?? "default"; + const codeTheme = resolvedOptions.codeTheme ?? "github"; + const style = resolveMarkdownStyle(resolvedOptions); + + const { baseCss, themeCss } = loadThemeCss(theme); + const css = normalizeThemeCss(buildCss(baseCss, themeCss, style)); + const codeThemeCss = loadCodeThemeCss(codeTheme); + + const renderer = initRenderer({ + citeStatus: resolvedOptions.citeStatus ?? false, + countStatus: resolvedOptions.countStatus ?? false, + isMacCodeBlock: resolvedOptions.isMacCodeBlock ?? true, + isShowLineNumber: resolvedOptions.isShowLineNumber ?? false, + legend: resolvedOptions.legend ?? "alt", + themeMode: resolvedOptions.themeMode, + }); + + const { yamlData, markdownContent, readingTime } = renderer.parseFrontMatterAndContent(markdown); + const { html: baseHtml, readingTime: readingTimeResult } = renderMarkdown(markdown, renderer); + + let contentHtml = postProcessHtml(baseHtml, readingTimeResult, renderer); + if (!(resolvedOptions.keepTitle ?? false)) { + contentHtml = removeFirstHeading(contentHtml); + } + + const meta = buildMarkdownDocumentMeta( + markdownContent, + yamlData as Record, + resolvedOptions.defaultTitle, + ); + const html = buildHtmlDocument(meta, css, contentHtml, codeThemeCss); + const inlinedHtml = normalizeInlineCss(await inlineCss(html), style); + + return { + contentHtml, + html: modifyHtmlStructure(inlinedHtml), + meta, + readingTime, + style, + yamlData: yamlData as Record, + }; +} + +export async function renderMarkdownFileToHtml( + inputPath: string, + options: RenderMarkdownDocumentOptions = {}, +): Promise { + const markdown = fs.readFileSync(inputPath, "utf-8"); + const outputPath = path.resolve( + path.dirname(inputPath), + `${path.basename(inputPath, path.extname(inputPath))}.html`, + ); + const result = await renderMarkdownDocument(markdown, { + ...options, + defaultTitle: options.defaultTitle ?? path.basename(outputPath, ".html"), + }); + + let backupPath: string | undefined; + if (fs.existsSync(outputPath)) { + backupPath = `${outputPath}.bak-${formatTimestamp()}`; + fs.renameSync(outputPath, backupPath); + } + + fs.writeFileSync(outputPath, result.html, "utf-8"); + + return { + ...result, + backupPath, + outputPath, + }; +} diff --git a/skills/baoyu-post-to-wechat/scripts/md/extend-config.ts b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/extend-config.ts similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/extend-config.ts rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/extend-config.ts diff --git a/skills/baoyu-post-to-wechat/scripts/md/extensions/alert.ts b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/extensions/alert.ts similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/extensions/alert.ts rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/extensions/alert.ts diff --git a/skills/baoyu-post-to-wechat/scripts/md/extensions/footnotes.ts b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/extensions/footnotes.ts similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/extensions/footnotes.ts rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/extensions/footnotes.ts diff --git a/skills/baoyu-post-to-wechat/scripts/md/extensions/index.ts b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/extensions/index.ts similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/extensions/index.ts rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/extensions/index.ts diff --git a/skills/baoyu-post-to-wechat/scripts/md/extensions/infographic.ts b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/extensions/infographic.ts similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/extensions/infographic.ts rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/extensions/infographic.ts diff --git a/skills/baoyu-post-to-wechat/scripts/md/extensions/katex.ts b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/extensions/katex.ts similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/extensions/katex.ts rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/extensions/katex.ts diff --git a/skills/baoyu-post-to-wechat/scripts/md/extensions/markup.ts b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/extensions/markup.ts similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/extensions/markup.ts rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/extensions/markup.ts diff --git a/skills/baoyu-post-to-wechat/scripts/md/extensions/plantuml.ts b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/extensions/plantuml.ts similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/extensions/plantuml.ts rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/extensions/plantuml.ts diff --git a/skills/baoyu-post-to-wechat/scripts/md/extensions/ruby.ts b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/extensions/ruby.ts similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/extensions/ruby.ts rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/extensions/ruby.ts diff --git a/skills/baoyu-post-to-wechat/scripts/md/extensions/slider.ts b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/extensions/slider.ts similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/extensions/slider.ts rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/extensions/slider.ts diff --git a/skills/baoyu-post-to-wechat/scripts/md/extensions/toc.ts b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/extensions/toc.ts similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/extensions/toc.ts rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/extensions/toc.ts diff --git a/skills/baoyu-post-to-wechat/scripts/md/html-builder.ts b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/html-builder.ts similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/html-builder.ts rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/html-builder.ts diff --git a/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/images.ts b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/images.ts new file mode 100644 index 0000000..f0a3f00 --- /dev/null +++ b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/images.ts @@ -0,0 +1,127 @@ +import { createHash } from "node:crypto"; +import fs from "node:fs"; +import http from "node:http"; +import https from "node:https"; +import path from "node:path"; + +export interface ImagePlaceholder { + originalPath: string; + placeholder: string; +} + +export interface ResolvedImageInfo extends ImagePlaceholder { + localPath: string; +} + +export function replaceMarkdownImagesWithPlaceholders( + markdown: string, + placeholderPrefix: string, +): { + images: ImagePlaceholder[]; + markdown: string; +} { + const images: ImagePlaceholder[] = []; + let imageCounter = 0; + + const rewritten = markdown.replace(/!\[([^\]]*)\]\(([^)]+)\)/g, (_match, _alt, src) => { + const placeholder = `${placeholderPrefix}${++imageCounter}`; + images.push({ + originalPath: src, + placeholder, + }); + return placeholder; + }); + + return { images, markdown: rewritten }; +} + +export function getImageExtension(urlOrPath: string): string { + const match = urlOrPath.match(/\.(jpg|jpeg|png|gif|webp)(\?|$)/i); + return match ? match[1]!.toLowerCase() : "png"; +} + +export async function downloadFile(url: string, destPath: string): Promise { + return await new Promise((resolve, reject) => { + const protocol = url.startsWith("https://") ? https : http; + const file = fs.createWriteStream(destPath); + + const request = protocol.get(url, { headers: { "User-Agent": "Mozilla/5.0" } }, (response) => { + if (response.statusCode === 301 || response.statusCode === 302) { + const redirectUrl = response.headers.location; + if (redirectUrl) { + file.close(); + fs.unlinkSync(destPath); + void downloadFile(redirectUrl, destPath).then(resolve).catch(reject); + return; + } + } + + if (response.statusCode !== 200) { + file.close(); + fs.unlinkSync(destPath); + reject(new Error(`Failed to download: ${response.statusCode}`)); + return; + } + + response.pipe(file); + file.on("finish", () => { + file.close(); + resolve(); + }); + }); + + request.on("error", (error) => { + file.close(); + fs.unlink(destPath, () => {}); + reject(error); + }); + + request.setTimeout(30_000, () => { + request.destroy(); + reject(new Error("Download timeout")); + }); + }); +} + +export async function resolveImagePath( + imagePath: string, + baseDir: string, + tempDir: string, + logLabel = "baoyu-md", +): Promise { + if (imagePath.startsWith("http://") || imagePath.startsWith("https://")) { + const hash = createHash("md5").update(imagePath).digest("hex").slice(0, 8); + const ext = getImageExtension(imagePath); + const localPath = path.join(tempDir, `remote_${hash}.${ext}`); + + if (!fs.existsSync(localPath)) { + console.error(`[${logLabel}] Downloading: ${imagePath}`); + await downloadFile(imagePath, localPath); + } + return localPath; + } + + if (path.isAbsolute(imagePath)) { + return imagePath; + } + + return path.resolve(baseDir, imagePath); +} + +export async function resolveContentImages( + images: ImagePlaceholder[], + baseDir: string, + tempDir: string, + logLabel = "baoyu-md", +): Promise { + const resolved: ResolvedImageInfo[] = []; + + for (const image of images) { + resolved.push({ + ...image, + localPath: await resolveImagePath(image.originalPath, baseDir, tempDir, logLabel), + }); + } + + return resolved; +} diff --git a/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/index.ts b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/index.ts new file mode 100644 index 0000000..eeec395 --- /dev/null +++ b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/index.ts @@ -0,0 +1,10 @@ +export * from "./cli.js"; +export * from "./constants.js"; +export * from "./content.js"; +export * from "./document.js"; +export * from "./extend-config.js"; +export * from "./html-builder.js"; +export * from "./images.js"; +export * from "./renderer.js"; +export * from "./themes.js"; +export * from "./types.js"; diff --git a/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/render.ts b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/render.ts new file mode 100644 index 0000000..85415d6 --- /dev/null +++ b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/render.ts @@ -0,0 +1,43 @@ +#!/usr/bin/env npx tsx + +import path from "node:path"; +import { parseArgs, printUsage } from "./cli.js"; +import { renderMarkdownFileToHtml } from "./document.js"; + +async function main(): Promise { + const options = parseArgs(process.argv.slice(2)); + if (!options) { + printUsage(); + process.exit(1); + } + + const inputPath = path.resolve(process.cwd(), options.inputPath); + if (!inputPath.toLowerCase().endsWith(".md")) { + console.error("Input file must end with .md"); + process.exit(1); + } + + const result = await renderMarkdownFileToHtml(inputPath, { + codeTheme: options.codeTheme, + countStatus: options.countStatus, + citeStatus: options.citeStatus, + fontFamily: options.fontFamily, + fontSize: options.fontSize, + isMacCodeBlock: options.isMacCodeBlock, + isShowLineNumber: options.isShowLineNumber, + keepTitle: options.keepTitle, + legend: options.legend, + primaryColor: options.primaryColor, + theme: options.theme, + }); + + if (result.backupPath) { + console.log(`Backup created: ${result.backupPath}`); + } + console.log(`HTML written: ${result.outputPath}`); +} + +main().catch((error) => { + console.error(error); + process.exit(1); +}); diff --git a/skills/baoyu-post-to-wechat/scripts/md/renderer.ts b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/renderer.ts similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/renderer.ts rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/renderer.ts diff --git a/skills/baoyu-post-to-wechat/scripts/md/themes.ts b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/themes.ts similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/themes.ts rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/themes.ts diff --git a/skills/baoyu-post-to-wechat/scripts/md/themes/base.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/themes/base.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/themes/base.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/themes/base.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/themes/default.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/themes/default.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/themes/default.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/themes/default.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/themes/grace.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/themes/grace.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/themes/grace.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/themes/grace.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/themes/modern.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/themes/modern.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/themes/modern.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/themes/modern.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/themes/simple.css b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/themes/simple.css similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/themes/simple.css rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/themes/simple.css diff --git a/skills/baoyu-post-to-wechat/scripts/md/types.ts b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/types.ts similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/types.ts rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/types.ts diff --git a/skills/baoyu-post-to-wechat/scripts/md/utils/languages.ts b/skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/utils/languages.ts similarity index 100% rename from skills/baoyu-post-to-wechat/scripts/md/utils/languages.ts rename to skills/baoyu-markdown-to-html/scripts/vendor/baoyu-md/src/utils/languages.ts diff --git a/skills/baoyu-post-to-wechat/scripts/bun.lock b/skills/baoyu-post-to-wechat/scripts/bun.lock index 1cab200..bd132c1 100644 --- a/skills/baoyu-post-to-wechat/scripts/bun.lock +++ b/skills/baoyu-post-to-wechat/scripts/bun.lock @@ -5,10 +5,205 @@ "name": "baoyu-post-to-wechat-scripts", "dependencies": { "baoyu-chrome-cdp": "file:./vendor/baoyu-chrome-cdp", + "baoyu-md": "file:./vendor/baoyu-md", }, }, }, "packages": { + "@types/debug": ["@types/debug@4.1.12", "", { "dependencies": { "@types/ms": "*" } }, "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ=="], + + "@types/mdast": ["@types/mdast@4.0.4", "", { "dependencies": { "@types/unist": "*" } }, "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA=="], + + "@types/ms": ["@types/ms@2.1.0", "", {}, "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA=="], + + "@types/unist": ["@types/unist@3.0.3", "", {}, "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="], + + "ansi-colors": ["ansi-colors@4.1.3", "", {}, "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw=="], + + "argparse": ["argparse@1.0.10", "", { "dependencies": { "sprintf-js": "~1.0.2" } }, "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg=="], + + "bail": ["bail@2.0.2", "", {}, "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw=="], + "baoyu-chrome-cdp": ["baoyu-chrome-cdp@file:vendor/baoyu-chrome-cdp", {}], + + "baoyu-md": ["baoyu-md@file:vendor/baoyu-md", { "dependencies": { "fflate": "^0.8.2", "front-matter": "^4.0.2", "highlight.js": "^11.11.1", "juice": "^11.0.1", "marked": "^15.0.6", "reading-time": "^1.5.0", "remark-cjk-friendly": "^1.1.0", "remark-parse": "^11.0.0", "remark-stringify": "^11.0.0", "unified": "^11.0.5" } }], + + "boolbase": ["boolbase@1.0.0", "", {}, "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="], + + "character-entities": ["character-entities@2.0.2", "", {}, "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ=="], + + "cheerio": ["cheerio@1.0.0", "", { "dependencies": { "cheerio-select": "^2.1.0", "dom-serializer": "^2.0.0", "domhandler": "^5.0.3", "domutils": "^3.1.0", "encoding-sniffer": "^0.2.0", "htmlparser2": "^9.1.0", "parse5": "^7.1.2", "parse5-htmlparser2-tree-adapter": "^7.0.0", "parse5-parser-stream": "^7.1.2", "undici": "^6.19.5", "whatwg-mimetype": "^4.0.0" } }, "sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww=="], + + "cheerio-select": ["cheerio-select@2.1.0", "", { "dependencies": { "boolbase": "^1.0.0", "css-select": "^5.1.0", "css-what": "^6.1.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.3", "domutils": "^3.0.1" } }, "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g=="], + + "commander": ["commander@12.1.0", "", {}, "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA=="], + + "css-select": ["css-select@5.2.2", "", { "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.1.0", "domhandler": "^5.0.2", "domutils": "^3.0.1", "nth-check": "^2.0.1" } }, "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw=="], + + "css-what": ["css-what@6.2.2", "", {}, "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA=="], + + "debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], + + "decode-named-character-reference": ["decode-named-character-reference@1.3.0", "", { "dependencies": { "character-entities": "^2.0.0" } }, "sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q=="], + + "dequal": ["dequal@2.0.3", "", {}, "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA=="], + + "devlop": ["devlop@1.1.0", "", { "dependencies": { "dequal": "^2.0.0" } }, "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA=="], + + "dom-serializer": ["dom-serializer@2.0.0", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", "entities": "^4.2.0" } }, "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg=="], + + "domelementtype": ["domelementtype@2.3.0", "", {}, "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw=="], + + "domhandler": ["domhandler@5.0.3", "", { "dependencies": { "domelementtype": "^2.3.0" } }, "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w=="], + + "domutils": ["domutils@3.2.2", "", { "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.3" } }, "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw=="], + + "encoding-sniffer": ["encoding-sniffer@0.2.1", "", { "dependencies": { "iconv-lite": "^0.6.3", "whatwg-encoding": "^3.1.1" } }, "sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw=="], + + "entities": ["entities@7.0.1", "", {}, "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA=="], + + "escape-goat": ["escape-goat@3.0.0", "", {}, "sha512-w3PwNZJwRxlp47QGzhuEBldEqVHHhh8/tIPcl6ecf2Bou99cdAt0knihBV0Ecc7CGxYduXVBDheH1K2oADRlvw=="], + + "esprima": ["esprima@4.0.1", "", { "bin": { "esparse": "./bin/esparse.js", "esvalidate": "./bin/esvalidate.js" } }, "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="], + + "extend": ["extend@3.0.2", "", {}, "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="], + + "fflate": ["fflate@0.8.2", "", {}, "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A=="], + + "front-matter": ["front-matter@4.0.2", "", { "dependencies": { "js-yaml": "^3.13.1" } }, "sha512-I8ZuJ/qG92NWX8i5x1Y8qyj3vizhXS31OxjKDu3LKP+7/qBgfIKValiZIEwoVoJKUHlhWtYrktkxV1XsX+pPlg=="], + + "get-east-asian-width": ["get-east-asian-width@1.5.0", "", {}, "sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA=="], + + "highlight.js": ["highlight.js@11.11.1", "", {}, "sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w=="], + + "htmlparser2": ["htmlparser2@9.1.0", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.3", "domutils": "^3.1.0", "entities": "^4.5.0" } }, "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ=="], + + "iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="], + + "is-plain-obj": ["is-plain-obj@4.1.0", "", {}, "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg=="], + + "js-yaml": ["js-yaml@3.14.2", "", { "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg=="], + + "juice": ["juice@11.1.1", "", { "dependencies": { "cheerio": "1.0.0", "commander": "^12.1.0", "entities": "^7.0.0", "mensch": "^0.3.4", "slick": "^1.12.2", "web-resource-inliner": "^8.0.0" }, "bin": { "juice": "bin/juice" } }, "sha512-4SBfZqKcc6DrIS+5b/WiGoWaZsdUPBH+e6SbRlNjJpaIRtfoBhYReAtobIEW6mcLeFFDXLBJMuZwkJLkBJjs2w=="], + + "longest-streak": ["longest-streak@3.1.0", "", {}, "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g=="], + + "marked": ["marked@15.0.12", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-8dD6FusOQSrpv9Z1rdNMdlSgQOIP880DHqnohobOmYLElGEqAL/JvxvuxZO16r4HtjTlfPRDC1hbvxC9dPN2nA=="], + + "mdast-util-from-markdown": ["mdast-util-from-markdown@2.0.3", "", { "dependencies": { "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", "decode-named-character-reference": "^1.0.0", "devlop": "^1.0.0", "mdast-util-to-string": "^4.0.0", "micromark": "^4.0.0", "micromark-util-decode-numeric-character-reference": "^2.0.0", "micromark-util-decode-string": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q=="], + + "mdast-util-phrasing": ["mdast-util-phrasing@4.1.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "unist-util-is": "^6.0.0" } }, "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w=="], + + "mdast-util-to-markdown": ["mdast-util-to-markdown@2.1.2", "", { "dependencies": { "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", "longest-streak": "^3.0.0", "mdast-util-phrasing": "^4.0.0", "mdast-util-to-string": "^4.0.0", "micromark-util-classify-character": "^2.0.0", "micromark-util-decode-string": "^2.0.0", "unist-util-visit": "^5.0.0", "zwitch": "^2.0.0" } }, "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA=="], + + "mdast-util-to-string": ["mdast-util-to-string@4.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0" } }, "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg=="], + + "mensch": ["mensch@0.3.4", "", {}, "sha512-IAeFvcOnV9V0Yk+bFhYR07O3yNina9ANIN5MoXBKYJ/RLYPurd2d0yw14MDhpr9/momp0WofT1bPUh3hkzdi/g=="], + + "micromark": ["micromark@4.0.2", "", { "dependencies": { "@types/debug": "^4.0.0", "debug": "^4.0.0", "decode-named-character-reference": "^1.0.0", "devlop": "^1.0.0", "micromark-core-commonmark": "^2.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-chunked": "^2.0.0", "micromark-util-combine-extensions": "^2.0.0", "micromark-util-decode-numeric-character-reference": "^2.0.0", "micromark-util-encode": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-resolve-all": "^2.0.0", "micromark-util-sanitize-uri": "^2.0.0", "micromark-util-subtokenize": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA=="], + + "micromark-core-commonmark": ["micromark-core-commonmark@2.0.3", "", { "dependencies": { "decode-named-character-reference": "^1.0.0", "devlop": "^1.0.0", "micromark-factory-destination": "^2.0.0", "micromark-factory-label": "^2.0.0", "micromark-factory-space": "^2.0.0", "micromark-factory-title": "^2.0.0", "micromark-factory-whitespace": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-chunked": "^2.0.0", "micromark-util-classify-character": "^2.0.0", "micromark-util-html-tag-name": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-resolve-all": "^2.0.0", "micromark-util-subtokenize": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg=="], + + "micromark-extension-cjk-friendly": ["micromark-extension-cjk-friendly@1.2.3", "", { "dependencies": { "devlop": "^1.1.0", "micromark-extension-cjk-friendly-util": "2.1.1", "micromark-util-chunked": "^2.0.1", "micromark-util-resolve-all": "^2.0.1", "micromark-util-symbol": "^2.0.1" }, "peerDependencies": { "micromark": "^4.0.0", "micromark-util-types": "^2.0.0" }, "optionalPeers": ["micromark-util-types"] }, "sha512-gRzVLUdjXBLX6zNPSnHGDoo+ZTp5zy+MZm0g3sv+3chPXY7l9gW+DnrcHcZh/jiPR6MjPKO4AEJNp4Aw6V9z5Q=="], + + "micromark-extension-cjk-friendly-util": ["micromark-extension-cjk-friendly-util@2.1.1", "", { "dependencies": { "get-east-asian-width": "^1.3.0", "micromark-util-character": "^2.1.1", "micromark-util-symbol": "^2.0.1" } }, "sha512-egs6+12JU2yutskHY55FyR48ZiEcFOJFyk9rsiyIhcJ6IvWB6ABBqVrBw8IobqJTDZ/wdSr9eoXDPb5S2nW1bg=="], + + "micromark-factory-destination": ["micromark-factory-destination@2.0.1", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA=="], + + "micromark-factory-label": ["micromark-factory-label@2.0.1", "", { "dependencies": { "devlop": "^1.0.0", "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg=="], + + "micromark-factory-space": ["micromark-factory-space@2.0.1", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg=="], + + "micromark-factory-title": ["micromark-factory-title@2.0.1", "", { "dependencies": { "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw=="], + + "micromark-factory-whitespace": ["micromark-factory-whitespace@2.0.1", "", { "dependencies": { "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ=="], + + "micromark-util-character": ["micromark-util-character@2.1.1", "", { "dependencies": { "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q=="], + + "micromark-util-chunked": ["micromark-util-chunked@2.0.1", "", { "dependencies": { "micromark-util-symbol": "^2.0.0" } }, "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA=="], + + "micromark-util-classify-character": ["micromark-util-classify-character@2.0.1", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q=="], + + "micromark-util-combine-extensions": ["micromark-util-combine-extensions@2.0.1", "", { "dependencies": { "micromark-util-chunked": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg=="], + + "micromark-util-decode-numeric-character-reference": ["micromark-util-decode-numeric-character-reference@2.0.2", "", { "dependencies": { "micromark-util-symbol": "^2.0.0" } }, "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw=="], + + "micromark-util-decode-string": ["micromark-util-decode-string@2.0.1", "", { "dependencies": { "decode-named-character-reference": "^1.0.0", "micromark-util-character": "^2.0.0", "micromark-util-decode-numeric-character-reference": "^2.0.0", "micromark-util-symbol": "^2.0.0" } }, "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ=="], + + "micromark-util-encode": ["micromark-util-encode@2.0.1", "", {}, "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw=="], + + "micromark-util-html-tag-name": ["micromark-util-html-tag-name@2.0.1", "", {}, "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA=="], + + "micromark-util-normalize-identifier": ["micromark-util-normalize-identifier@2.0.1", "", { "dependencies": { "micromark-util-symbol": "^2.0.0" } }, "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q=="], + + "micromark-util-resolve-all": ["micromark-util-resolve-all@2.0.1", "", { "dependencies": { "micromark-util-types": "^2.0.0" } }, "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg=="], + + "micromark-util-sanitize-uri": ["micromark-util-sanitize-uri@2.0.1", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-encode": "^2.0.0", "micromark-util-symbol": "^2.0.0" } }, "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ=="], + + "micromark-util-subtokenize": ["micromark-util-subtokenize@2.1.0", "", { "dependencies": { "devlop": "^1.0.0", "micromark-util-chunked": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA=="], + + "micromark-util-symbol": ["micromark-util-symbol@2.0.1", "", {}, "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q=="], + + "micromark-util-types": ["micromark-util-types@2.0.2", "", {}, "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA=="], + + "mime": ["mime@2.6.0", "", { "bin": { "mime": "cli.js" } }, "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg=="], + + "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], + + "nth-check": ["nth-check@2.1.1", "", { "dependencies": { "boolbase": "^1.0.0" } }, "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w=="], + + "parse5": ["parse5@7.3.0", "", { "dependencies": { "entities": "^6.0.0" } }, "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw=="], + + "parse5-htmlparser2-tree-adapter": ["parse5-htmlparser2-tree-adapter@7.1.0", "", { "dependencies": { "domhandler": "^5.0.3", "parse5": "^7.0.0" } }, "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g=="], + + "parse5-parser-stream": ["parse5-parser-stream@7.1.2", "", { "dependencies": { "parse5": "^7.0.0" } }, "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow=="], + + "reading-time": ["reading-time@1.5.0", "", {}, "sha512-onYyVhBNr4CmAxFsKS7bz+uTLRakypIe4R+5A824vBSkQy/hB3fZepoVEf8OVAxzLvK+H/jm9TzpI3ETSm64Kg=="], + + "remark-cjk-friendly": ["remark-cjk-friendly@1.2.3", "", { "dependencies": { "micromark-extension-cjk-friendly": "1.2.3" }, "peerDependencies": { "@types/mdast": "^4.0.0", "unified": "^11.0.0" }, "optionalPeers": ["@types/mdast"] }, "sha512-UvAgxwlNk+l9Oqgl/9MWK2eWRS7zgBW/nXX9AthV7nd/3lNejF138E7Xbmk9Zs4WjTJGs721r7fAEc7tNFoH7g=="], + + "remark-parse": ["remark-parse@11.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-from-markdown": "^2.0.0", "micromark-util-types": "^2.0.0", "unified": "^11.0.0" } }, "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA=="], + + "remark-stringify": ["remark-stringify@11.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-to-markdown": "^2.0.0", "unified": "^11.0.0" } }, "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw=="], + + "safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="], + + "slick": ["slick@1.12.2", "", {}, "sha512-4qdtOGcBjral6YIBCWJ0ljFSKNLz9KkhbWtuGvUyRowl1kxfuE1x/Z/aJcaiilpb3do9bl5K7/1h9XC5wWpY/A=="], + + "sprintf-js": ["sprintf-js@1.0.3", "", {}, "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g=="], + + "trough": ["trough@2.2.0", "", {}, "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw=="], + + "undici": ["undici@6.24.0", "", {}, "sha512-lVLNosgqo5EkGqh5XUDhGfsMSoO8K0BAN0TyJLvwNRSl4xWGZlCVYsAIpa/OpA3TvmnM01GWcoKmc3ZWo5wKKA=="], + + "unified": ["unified@11.0.5", "", { "dependencies": { "@types/unist": "^3.0.0", "bail": "^2.0.0", "devlop": "^1.0.0", "extend": "^3.0.0", "is-plain-obj": "^4.0.0", "trough": "^2.0.0", "vfile": "^6.0.0" } }, "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA=="], + + "unist-util-is": ["unist-util-is@6.0.1", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g=="], + + "unist-util-stringify-position": ["unist-util-stringify-position@4.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ=="], + + "unist-util-visit": ["unist-util-visit@5.1.0", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0", "unist-util-visit-parents": "^6.0.0" } }, "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg=="], + + "unist-util-visit-parents": ["unist-util-visit-parents@6.0.2", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0" } }, "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ=="], + + "valid-data-url": ["valid-data-url@3.0.1", "", {}, "sha512-jOWVmzVceKlVVdwjNSenT4PbGghU0SBIizAev8ofZVgivk/TVHXSbNL8LP6M3spZvkR9/QolkyJavGSX5Cs0UA=="], + + "vfile": ["vfile@6.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "vfile-message": "^4.0.0" } }, "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q=="], + + "vfile-message": ["vfile-message@4.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw=="], + + "web-resource-inliner": ["web-resource-inliner@8.0.0", "", { "dependencies": { "ansi-colors": "^4.1.1", "escape-goat": "^3.0.0", "htmlparser2": "^9.1.0", "mime": "^2.4.6", "valid-data-url": "^3.0.0" } }, "sha512-Ezr98sqXW/+OCGoUEXuOKVR+oVFlSdn1tIySEEJdiSAw4IjrW8hQkwARSSBJTSB5Us5dnytDgL0ZDliAYBhaNA=="], + + "whatwg-encoding": ["whatwg-encoding@3.1.1", "", { "dependencies": { "iconv-lite": "0.6.3" } }, "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ=="], + + "whatwg-mimetype": ["whatwg-mimetype@4.0.0", "", {}, "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg=="], + + "zwitch": ["zwitch@2.0.4", "", {}, "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A=="], + + "dom-serializer/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="], + + "htmlparser2/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="], + + "parse5/entities": ["entities@6.0.1", "", {}, "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="], } } diff --git a/skills/baoyu-post-to-wechat/scripts/md-to-wechat.ts b/skills/baoyu-post-to-wechat/scripts/md-to-wechat.ts index c57a355..ffec0ae 100644 --- a/skills/baoyu-post-to-wechat/scripts/md-to-wechat.ts +++ b/skills/baoyu-post-to-wechat/scripts/md-to-wechat.ts @@ -1,13 +1,19 @@ -import fs from 'node:fs'; -import path from 'node:path'; -import { mkdir, writeFile } from 'node:fs/promises'; -import os from 'node:os'; -import { createHash } from 'node:crypto'; -import { fileURLToPath } from 'node:url'; -import https from 'node:https'; -import http from 'node:http'; -import { spawnSync } from 'node:child_process'; -import process from 'node:process'; +import fs from "node:fs"; +import os from "node:os"; +import path from "node:path"; +import process from "node:process"; + +import { + extractSummaryFromBody, + extractTitleFromMarkdown, + parseFrontmatter, + renderMarkdownDocument, + replaceMarkdownImagesWithPlaceholders, + resolveColorToken, + resolveContentImages, + serializeFrontmatter, + stripWrappingQuotes, +} from "baoyu-md"; interface ImageInfo { placeholder: string; @@ -23,200 +29,53 @@ interface ParsedResult { contentImages: ImageInfo[]; } -function downloadFile(url: string, destPath: string): Promise { - return new Promise((resolve, reject) => { - const protocol = url.startsWith('https') ? https : http; - const file = fs.createWriteStream(destPath); - - const request = protocol.get(url, { headers: { 'User-Agent': 'Mozilla/5.0' } }, (response) => { - if (response.statusCode === 301 || response.statusCode === 302) { - const redirectUrl = response.headers.location; - if (redirectUrl) { - file.close(); - fs.unlinkSync(destPath); - downloadFile(redirectUrl, destPath).then(resolve).catch(reject); - return; - } - } - - if (response.statusCode !== 200) { - file.close(); - fs.unlinkSync(destPath); - reject(new Error(`Failed to download: ${response.statusCode}`)); - return; - } - - response.pipe(file); - file.on('finish', () => { - file.close(); - resolve(); - }); - }); - - request.on('error', (err) => { - file.close(); - fs.unlink(destPath, () => {}); - reject(err); - }); - - request.setTimeout(30000, () => { - request.destroy(); - reject(new Error('Download timeout')); - }); - }); -} - -function getImageExtension(urlOrPath: string): string { - const match = urlOrPath.match(/\.(jpg|jpeg|png|gif|webp)(\?|$)/i); - return match ? match[1]!.toLowerCase() : 'png'; -} - -async function resolveImagePath(imagePath: string, baseDir: string, tempDir: string): Promise { - if (imagePath.startsWith('http://') || imagePath.startsWith('https://')) { - const hash = createHash('md5').update(imagePath).digest('hex').slice(0, 8); - const ext = getImageExtension(imagePath); - const localPath = path.join(tempDir, `remote_${hash}.${ext}`); - - if (!fs.existsSync(localPath)) { - console.error(`[md-to-wechat] Downloading: ${imagePath}`); - await downloadFile(imagePath, localPath); - } - return localPath; - } - - if (path.isAbsolute(imagePath)) { - return imagePath; - } - - return path.resolve(baseDir, imagePath); -} - -function parseFrontmatter(content: string): { frontmatter: Record; body: string } { - const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/); - if (!match) return { frontmatter: {}, body: content }; - - const frontmatter: Record = {}; - const lines = match[1]!.split('\n'); - for (const line of lines) { - const colonIdx = line.indexOf(':'); - if (colonIdx > 0) { - const key = line.slice(0, colonIdx).trim(); - let value = line.slice(colonIdx + 1).trim(); - if ((value.startsWith('"') && value.endsWith('"')) || (value.startsWith("'") && value.endsWith("'"))) { - value = value.slice(1, -1); - } - frontmatter[key] = value; - } - } - - return { frontmatter, body: match[2]! }; -} - export async function convertMarkdown( markdownPath: string, - options?: { title?: string; theme?: string; color?: string; citeStatus?: boolean } + options?: { title?: string; theme?: string; color?: string; citeStatus?: boolean }, ): Promise { const baseDir = path.dirname(markdownPath); - const content = fs.readFileSync(markdownPath, 'utf-8'); - const theme = options?.theme ?? 'default'; + const content = fs.readFileSync(markdownPath, "utf-8"); const citeStatus = options?.citeStatus ?? true; const { frontmatter, body } = parseFrontmatter(content); - let title = options?.title ?? frontmatter.title ?? ''; - let bodyWithoutTitle = body; + let title = stripWrappingQuotes(options?.title ?? "") + || stripWrappingQuotes(frontmatter.title ?? "") + || extractTitleFromMarkdown(body); if (!title) { - const lines = body.split('\n'); - for (const line of lines) { - const trimmed = line.trim(); - if (!trimmed) continue; - const headingMatch = trimmed.match(/^#{1,2}\s+(.+)$/); - if (headingMatch) { - title = headingMatch[1]!; - bodyWithoutTitle = body.replace(/^#{1,2}\s+.+\r?\n?/, ''); - } - break; - } - } else { - bodyWithoutTitle = body.replace(/^#{1,2}\s+.+\r?\n?/, ''); + title = path.basename(markdownPath, path.extname(markdownPath)); } - if (!title) title = path.basename(markdownPath, path.extname(markdownPath)); - const author = frontmatter.author || ''; - let summary = frontmatter.description || frontmatter.summary || ''; + const author = stripWrappingQuotes(frontmatter.author ?? ""); + let summary = stripWrappingQuotes(frontmatter.description ?? "") + || stripWrappingQuotes(frontmatter.summary ?? ""); if (!summary) { - const lines = bodyWithoutTitle.split('\n'); - for (const line of lines) { - const trimmed = line.trim(); - if (!trimmed) continue; - if (trimmed.startsWith('#')) continue; - if (trimmed.startsWith('![')) continue; - if (trimmed.startsWith('>')) continue; - if (trimmed.startsWith('-') || trimmed.startsWith('*')) continue; - if (/^\d+\./.test(trimmed)) continue; - - const cleanText = trimmed - .replace(/\*\*(.+?)\*\*/g, '$1') - .replace(/\*(.+?)\*/g, '$1') - .replace(/\[([^\]]+)\]\([^)]+\)/g, '$1') - .replace(/`([^`]+)`/g, '$1'); - - if (cleanText.length > 20) { - summary = cleanText.length > 120 ? cleanText.slice(0, 117) + '...' : cleanText; - break; - } - } + summary = extractSummaryFromBody(body, 120); } - const images: Array<{ src: string; placeholder: string }> = []; - let imageCounter = 0; + const { images, markdown: rewrittenBody } = replaceMarkdownImagesWithPlaceholders( + body, + "WECHATIMGPH_", + ); + const rewrittenMarkdown = `${serializeFrontmatter(frontmatter)}${rewrittenBody}`; - const modifiedBody = bodyWithoutTitle.replace(/!\[([^\]]*)\]\(([^)]+)\)/g, (match, alt, src) => { - const placeholder = `WECHATIMGPH_${++imageCounter}`; - images.push({ src, placeholder }); - return placeholder; + const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "wechat-article-images-")); + const htmlPath = path.join(tempDir, "temp-article.html"); + + console.error( + `[md-to-wechat] Rendering markdown with theme: ${options?.theme ?? "default"}${options?.color ? `, color: ${options.color}` : ""}, citeStatus: ${citeStatus}`, + ); + + const { html } = await renderMarkdownDocument(rewrittenMarkdown, { + citeStatus, + defaultTitle: title, + keepTitle: false, + primaryColor: resolveColorToken(options?.color), + theme: options?.theme, }); + fs.writeFileSync(htmlPath, html, "utf-8"); - const modifiedMarkdown = `---\n${Object.entries(frontmatter).map(([k, v]) => `${k}: ${v}`).join('\n')}\n---\n${modifiedBody}`; - - const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'wechat-article-images-')); - const tempMdPath = path.join(tempDir, 'temp-article.md'); - await writeFile(tempMdPath, modifiedMarkdown, 'utf-8'); - - const __filename = fileURLToPath(import.meta.url); - const __dirname = path.dirname(__filename); - const renderScript = path.join(__dirname, 'md', 'render.ts'); - - const renderArgs = ['-y', 'bun', renderScript, tempMdPath, '--theme', theme]; - if (options?.color) renderArgs.push('--color', options.color); - if (citeStatus) renderArgs.push('--cite'); - - console.error(`[md-to-wechat] Rendering markdown with theme: ${theme}${options?.color ? `, color: ${options.color}` : ''}, citeStatus: ${citeStatus}`); - - const result = spawnSync('npx', renderArgs, { - stdio: ['inherit', 'pipe', 'pipe'], - cwd: baseDir, - }); - - if (result.status !== 0) { - const stderr = result.stderr?.toString() || ''; - throw new Error(`Render failed: ${stderr}`); - } - - const htmlPath = tempMdPath.replace(/\.md$/i, '.html'); - if (!fs.existsSync(htmlPath)) { - throw new Error(`HTML file not generated: ${htmlPath}`); - } - - const contentImages: ImageInfo[] = []; - for (const img of images) { - const localPath = await resolveImagePath(img.src, baseDir, tempDir); - contentImages.push({ - placeholder: img.placeholder, - localPath, - originalPath: img.src, - }); - } + const contentImages = await resolveContentImages(images, baseDir, tempDir, "md-to-wechat"); return { title, @@ -264,7 +123,7 @@ Example: async function main(): Promise { const args = process.argv.slice(2); - if (args.length === 0 || args.includes('--help') || args.includes('-h')) { + if (args.length === 0 || args.includes("--help") || args.includes("-h")) { printUsage(); } @@ -276,23 +135,23 @@ async function main(): Promise { for (let i = 0; i < args.length; i++) { const arg = args[i]!; - if (arg === '--title' && args[i + 1]) { + if (arg === "--title" && args[i + 1]) { title = args[++i]; - } else if (arg === '--theme' && args[i + 1]) { + } else if (arg === "--theme" && args[i + 1]) { theme = args[++i]; - } else if (arg === '--color' && args[i + 1]) { + } else if (arg === "--color" && args[i + 1]) { color = args[++i]; - } else if (arg === '--cite') { + } else if (arg === "--cite") { citeStatus = true; - } else if (arg === '--no-cite') { + } else if (arg === "--no-cite") { citeStatus = false; - } else if (!arg.startsWith('-')) { + } else if (!arg.startsWith("-")) { markdownPath = arg; } } if (!markdownPath) { - console.error('Error: Markdown file path is required'); + console.error("Error: Markdown file path is required"); process.exit(1); } @@ -305,7 +164,7 @@ async function main(): Promise { console.log(JSON.stringify(result, null, 2)); } -await main().catch((err) => { - console.error(`Error: ${err instanceof Error ? err.message : String(err)}`); +await main().catch((error) => { + console.error(`Error: ${error instanceof Error ? error.message : String(error)}`); process.exit(1); }); diff --git a/skills/baoyu-post-to-wechat/scripts/md/package-lock.json b/skills/baoyu-post-to-wechat/scripts/md/package-lock.json deleted file mode 100644 index 1b47630..0000000 --- a/skills/baoyu-post-to-wechat/scripts/md/package-lock.json +++ /dev/null @@ -1,1395 +0,0 @@ -{ - "name": "md", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "dependencies": { - "fflate": "^0.8.2", - "front-matter": "^4.0.2", - "highlight.js": "^11.11.1", - "juice": "^11.0.1", - "marked": "^15.0.6", - "reading-time": "^1.5.0", - "remark-cjk-friendly": "^1.1.0", - "remark-parse": "^11.0.0", - "remark-stringify": "^11.0.0", - "unified": "^11.0.5" - } - }, - "node_modules/@types/debug": { - "version": "4.1.12", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", - "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", - "license": "MIT", - "dependencies": { - "@types/ms": "*" - } - }, - "node_modules/@types/mdast": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", - "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", - "license": "MIT", - "dependencies": { - "@types/unist": "*" - } - }, - "node_modules/@types/ms": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", - "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", - "license": "MIT" - }, - "node_modules/@types/unist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", - "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", - "license": "MIT" - }, - "node_modules/ansi-colors": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", - "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "license": "MIT", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/bail": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", - "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", - "license": "ISC" - }, - "node_modules/character-entities": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", - "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/cheerio": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0.tgz", - "integrity": "sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww==", - "license": "MIT", - "dependencies": { - "cheerio-select": "^2.1.0", - "dom-serializer": "^2.0.0", - "domhandler": "^5.0.3", - "domutils": "^3.1.0", - "encoding-sniffer": "^0.2.0", - "htmlparser2": "^9.1.0", - "parse5": "^7.1.2", - "parse5-htmlparser2-tree-adapter": "^7.0.0", - "parse5-parser-stream": "^7.1.2", - "undici": "^6.19.5", - "whatwg-mimetype": "^4.0.0" - }, - "engines": { - "node": ">=18.17" - }, - "funding": { - "url": "https://github.com/cheeriojs/cheerio?sponsor=1" - } - }, - "node_modules/cheerio-select": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", - "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0", - "css-select": "^5.1.0", - "css-what": "^6.1.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/commander": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", - "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/css-select": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", - "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==", - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.1.0", - "domhandler": "^5.0.2", - "domutils": "^3.0.1", - "nth-check": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/css-what": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz", - "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==", - "license": "BSD-2-Clause", - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decode-named-character-reference": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.3.0.tgz", - "integrity": "sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==", - "license": "MIT", - "dependencies": { - "character-entities": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/dequal": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", - "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/devlop": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", - "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", - "license": "MIT", - "dependencies": { - "dequal": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/dom-serializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", - "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", - "license": "MIT", - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.2", - "entities": "^4.2.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "node_modules/dom-serializer/node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/domelementtype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "license": "BSD-2-Clause" - }, - "node_modules/domhandler": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", - "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", - "license": "BSD-2-Clause", - "dependencies": { - "domelementtype": "^2.3.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/domutils": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", - "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", - "license": "BSD-2-Clause", - "dependencies": { - "dom-serializer": "^2.0.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, - "node_modules/encoding-sniffer": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.1.tgz", - "integrity": "sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==", - "license": "MIT", - "dependencies": { - "iconv-lite": "^0.6.3", - "whatwg-encoding": "^3.1.1" - }, - "funding": { - "url": "https://github.com/fb55/encoding-sniffer?sponsor=1" - } - }, - "node_modules/entities": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz", - "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/escape-goat": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-3.0.0.tgz", - "integrity": "sha512-w3PwNZJwRxlp47QGzhuEBldEqVHHhh8/tIPcl6ecf2Bou99cdAt0knihBV0Ecc7CGxYduXVBDheH1K2oADRlvw==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "license": "BSD-2-Clause", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "license": "MIT" - }, - "node_modules/fflate": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", - "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==", - "license": "MIT" - }, - "node_modules/front-matter": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/front-matter/-/front-matter-4.0.2.tgz", - "integrity": "sha512-I8ZuJ/qG92NWX8i5x1Y8qyj3vizhXS31OxjKDu3LKP+7/qBgfIKValiZIEwoVoJKUHlhWtYrktkxV1XsX+pPlg==", - "license": "MIT", - "dependencies": { - "js-yaml": "^3.13.1" - } - }, - "node_modules/get-east-asian-width": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.5.0.tgz", - "integrity": "sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/highlight.js": { - "version": "11.11.1", - "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.11.1.tgz", - "integrity": "sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/htmlparser2": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz", - "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==", - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "license": "MIT", - "dependencies": { - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3", - "domutils": "^3.1.0", - "entities": "^4.5.0" - } - }, - "node_modules/htmlparser2/node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-plain-obj": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", - "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/js-yaml": { - "version": "3.14.2", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", - "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", - "license": "MIT", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/juice": { - "version": "11.1.1", - "resolved": "https://registry.npmjs.org/juice/-/juice-11.1.1.tgz", - "integrity": "sha512-4SBfZqKcc6DrIS+5b/WiGoWaZsdUPBH+e6SbRlNjJpaIRtfoBhYReAtobIEW6mcLeFFDXLBJMuZwkJLkBJjs2w==", - "license": "MIT", - "dependencies": { - "cheerio": "1.0.0", - "commander": "^12.1.0", - "entities": "^7.0.0", - "mensch": "^0.3.4", - "slick": "^1.12.2", - "web-resource-inliner": "^8.0.0" - }, - "bin": { - "juice": "bin/juice" - }, - "engines": { - "node": ">=18.17" - } - }, - "node_modules/longest-streak": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", - "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/marked": { - "version": "15.0.12", - "resolved": "https://registry.npmjs.org/marked/-/marked-15.0.12.tgz", - "integrity": "sha512-8dD6FusOQSrpv9Z1rdNMdlSgQOIP880DHqnohobOmYLElGEqAL/JvxvuxZO16r4HtjTlfPRDC1hbvxC9dPN2nA==", - "license": "MIT", - "bin": { - "marked": "bin/marked.js" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/mdast-util-from-markdown": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.3.tgz", - "integrity": "sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "mdast-util-to-string": "^4.0.0", - "micromark": "^4.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-decode-string": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-phrasing": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", - "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-markdown": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz", - "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "@types/unist": "^3.0.0", - "longest-streak": "^3.0.0", - "mdast-util-phrasing": "^4.0.0", - "mdast-util-to-string": "^4.0.0", - "micromark-util-classify-character": "^2.0.0", - "micromark-util-decode-string": "^2.0.0", - "unist-util-visit": "^5.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", - "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mensch": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/mensch/-/mensch-0.3.4.tgz", - "integrity": "sha512-IAeFvcOnV9V0Yk+bFhYR07O3yNina9ANIN5MoXBKYJ/RLYPurd2d0yw14MDhpr9/momp0WofT1bPUh3hkzdi/g==", - "license": "MIT" - }, - "node_modules/micromark": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", - "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "@types/debug": "^4.0.0", - "debug": "^4.0.0", - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-core-commonmark": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-combine-extensions": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-sanitize-uri": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-core-commonmark": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz", - "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "devlop": "^1.0.0", - "micromark-factory-destination": "^2.0.0", - "micromark-factory-label": "^2.0.0", - "micromark-factory-space": "^2.0.0", - "micromark-factory-title": "^2.0.0", - "micromark-factory-whitespace": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-classify-character": "^2.0.0", - "micromark-util-html-tag-name": "^2.0.0", - "micromark-util-normalize-identifier": "^2.0.0", - "micromark-util-resolve-all": "^2.0.0", - "micromark-util-subtokenize": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-extension-cjk-friendly": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/micromark-extension-cjk-friendly/-/micromark-extension-cjk-friendly-1.2.3.tgz", - "integrity": "sha512-gRzVLUdjXBLX6zNPSnHGDoo+ZTp5zy+MZm0g3sv+3chPXY7l9gW+DnrcHcZh/jiPR6MjPKO4AEJNp4Aw6V9z5Q==", - "license": "MIT", - "dependencies": { - "devlop": "^1.1.0", - "micromark-extension-cjk-friendly-util": "2.1.1", - "micromark-util-chunked": "^2.0.1", - "micromark-util-resolve-all": "^2.0.1", - "micromark-util-symbol": "^2.0.1" - }, - "engines": { - "node": ">=16" - }, - "peerDependencies": { - "micromark": "^4.0.0", - "micromark-util-types": "^2.0.0" - }, - "peerDependenciesMeta": { - "micromark-util-types": { - "optional": true - } - } - }, - "node_modules/micromark-extension-cjk-friendly-util": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-extension-cjk-friendly-util/-/micromark-extension-cjk-friendly-util-2.1.1.tgz", - "integrity": "sha512-egs6+12JU2yutskHY55FyR48ZiEcFOJFyk9rsiyIhcJ6IvWB6ABBqVrBw8IobqJTDZ/wdSr9eoXDPb5S2nW1bg==", - "license": "MIT", - "dependencies": { - "get-east-asian-width": "^1.3.0", - "micromark-util-character": "^2.1.1", - "micromark-util-symbol": "^2.0.1" - }, - "engines": { - "node": ">=16" - }, - "peerDependenciesMeta": { - "micromark-util-types": { - "optional": true - } - } - }, - "node_modules/micromark-factory-destination": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", - "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-label": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", - "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-space": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", - "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-title": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", - "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-factory-whitespace": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", - "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-factory-space": "^2.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-character": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", - "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-chunked": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", - "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-classify-character": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", - "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-combine-extensions": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", - "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-chunked": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-decode-numeric-character-reference": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", - "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-decode-string": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz", - "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "micromark-util-character": "^2.0.0", - "micromark-util-decode-numeric-character-reference": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-encode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", - "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-html-tag-name": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", - "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-normalize-identifier": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", - "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-resolve-all": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", - "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-sanitize-uri": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", - "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "micromark-util-character": "^2.0.0", - "micromark-util-encode": "^2.0.0", - "micromark-util-symbol": "^2.0.0" - } - }, - "node_modules/micromark-util-subtokenize": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz", - "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT", - "dependencies": { - "devlop": "^1.0.0", - "micromark-util-chunked": "^2.0.0", - "micromark-util-symbol": "^2.0.0", - "micromark-util-types": "^2.0.0" - } - }, - "node_modules/micromark-util-symbol": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/micromark-util-types": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", - "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "license": "MIT" - }, - "node_modules/mime": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", - "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", - "license": "MIT", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/nth-check": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", - "license": "BSD-2-Clause", - "dependencies": { - "boolbase": "^1.0.0" - }, - "funding": { - "url": "https://github.com/fb55/nth-check?sponsor=1" - } - }, - "node_modules/parse5": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", - "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", - "license": "MIT", - "dependencies": { - "entities": "^6.0.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/parse5-htmlparser2-tree-adapter": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz", - "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==", - "license": "MIT", - "dependencies": { - "domhandler": "^5.0.3", - "parse5": "^7.0.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/parse5-parser-stream": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz", - "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==", - "license": "MIT", - "dependencies": { - "parse5": "^7.0.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/parse5/node_modules/entities": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", - "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/reading-time": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/reading-time/-/reading-time-1.5.0.tgz", - "integrity": "sha512-onYyVhBNr4CmAxFsKS7bz+uTLRakypIe4R+5A824vBSkQy/hB3fZepoVEf8OVAxzLvK+H/jm9TzpI3ETSm64Kg==", - "license": "MIT" - }, - "node_modules/remark-cjk-friendly": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/remark-cjk-friendly/-/remark-cjk-friendly-1.2.3.tgz", - "integrity": "sha512-UvAgxwlNk+l9Oqgl/9MWK2eWRS7zgBW/nXX9AthV7nd/3lNejF138E7Xbmk9Zs4WjTJGs721r7fAEc7tNFoH7g==", - "license": "MIT", - "dependencies": { - "micromark-extension-cjk-friendly": "1.2.3" - }, - "engines": { - "node": ">=16" - }, - "peerDependencies": { - "@types/mdast": "^4.0.0", - "unified": "^11.0.0" - }, - "peerDependenciesMeta": { - "@types/mdast": { - "optional": true - } - } - }, - "node_modules/remark-parse": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", - "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-from-markdown": "^2.0.0", - "micromark-util-types": "^2.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-stringify": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", - "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", - "license": "MIT", - "dependencies": { - "@types/mdast": "^4.0.0", - "mdast-util-to-markdown": "^2.0.0", - "unified": "^11.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "license": "MIT" - }, - "node_modules/slick": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/slick/-/slick-1.12.2.tgz", - "integrity": "sha512-4qdtOGcBjral6YIBCWJ0ljFSKNLz9KkhbWtuGvUyRowl1kxfuE1x/Z/aJcaiilpb3do9bl5K7/1h9XC5wWpY/A==", - "license": "MIT (http://mootools.net/license.txt)", - "engines": { - "node": "*" - } - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "license": "BSD-3-Clause" - }, - "node_modules/trough": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", - "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/undici": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.23.0.tgz", - "integrity": "sha512-VfQPToRA5FZs/qJxLIinmU59u0r7LXqoJkCzinq3ckNJp3vKEh7jTWN589YQ5+aoAC/TGRLyJLCPKcLQbM8r9g==", - "license": "MIT", - "engines": { - "node": ">=18.17" - } - }, - "node_modules/unified": { - "version": "11.0.5", - "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", - "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "bail": "^2.0.0", - "devlop": "^1.0.0", - "extend": "^3.0.0", - "is-plain-obj": "^4.0.0", - "trough": "^2.0.0", - "vfile": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-is": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.1.tgz", - "integrity": "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-stringify-position": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-visit": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.1.0.tgz", - "integrity": "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0", - "unist-util-visit-parents": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-visit-parents": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.2.tgz", - "integrity": "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-is": "^6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/valid-data-url": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/valid-data-url/-/valid-data-url-3.0.1.tgz", - "integrity": "sha512-jOWVmzVceKlVVdwjNSenT4PbGghU0SBIizAev8ofZVgivk/TVHXSbNL8LP6M3spZvkR9/QolkyJavGSX5Cs0UA==", - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/vfile": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", - "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "vfile-message": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/vfile-message": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz", - "integrity": "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==", - "license": "MIT", - "dependencies": { - "@types/unist": "^3.0.0", - "unist-util-stringify-position": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/web-resource-inliner": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/web-resource-inliner/-/web-resource-inliner-8.0.0.tgz", - "integrity": "sha512-Ezr98sqXW/+OCGoUEXuOKVR+oVFlSdn1tIySEEJdiSAw4IjrW8hQkwARSSBJTSB5Us5dnytDgL0ZDliAYBhaNA==", - "license": "MIT", - "dependencies": { - "ansi-colors": "^4.1.1", - "escape-goat": "^3.0.0", - "htmlparser2": "^9.1.0", - "mime": "^2.4.6", - "valid-data-url": "^3.0.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/whatwg-encoding": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", - "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", - "deprecated": "Use @exodus/bytes instead for a more spec-conformant and faster implementation", - "license": "MIT", - "dependencies": { - "iconv-lite": "0.6.3" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/whatwg-mimetype": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", - "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/zwitch": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", - "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - } - } -} diff --git a/skills/baoyu-post-to-wechat/scripts/md/render.ts b/skills/baoyu-post-to-wechat/scripts/md/render.ts deleted file mode 100644 index 840dc3e..0000000 --- a/skills/baoyu-post-to-wechat/scripts/md/render.ts +++ /dev/null @@ -1,119 +0,0 @@ -#!/usr/bin/env npx tsx - -import fs from "node:fs"; -import path from "node:path"; -import type { StyleConfig, HtmlDocumentMeta } from "./types.js"; -import { DEFAULT_STYLE, THEME_STYLE_DEFAULTS } from "./constants.js"; -import { loadThemeCss, normalizeThemeCss } from "./themes.js"; -import { parseArgs, printUsage } from "./cli.js"; -import { initRenderer, renderMarkdown, postProcessHtml } from "./renderer.js"; -import { - buildCss, - loadCodeThemeCss, - buildHtmlDocument, - inlineCss, - normalizeInlineCss, - modifyHtmlStructure, - removeFirstHeading, -} from "./html-builder.js"; - -function formatTimestamp(date = new Date()): string { - const pad = (value: number) => String(value).padStart(2, "0"); - return `${date.getFullYear()}${pad(date.getMonth() + 1)}${pad( - date.getDate() - )}${pad(date.getHours())}${pad(date.getMinutes())}${pad(date.getSeconds())}`; -} - -async function main(): Promise { - const options = parseArgs(process.argv.slice(2)); - if (!options) { - printUsage(); - process.exit(1); - } - - const inputPath = path.resolve(process.cwd(), options.inputPath); - if (!inputPath.toLowerCase().endsWith(".md")) { - console.error("Input file must end with .md"); - process.exit(1); - } - - if (!fs.existsSync(inputPath)) { - console.error(`File not found: ${inputPath}`); - process.exit(1); - } - - const outputPath = path.resolve( - process.cwd(), - options.inputPath.replace(/\.md$/i, ".html") - ); - - const themeDefaults = THEME_STYLE_DEFAULTS[options.theme] ?? {}; - const style: StyleConfig = { - ...DEFAULT_STYLE, - ...themeDefaults, - ...(options.primaryColor !== undefined ? { primaryColor: options.primaryColor } : {}), - ...(options.fontFamily !== undefined ? { fontFamily: options.fontFamily } : {}), - ...(options.fontSize !== undefined ? { fontSize: options.fontSize } : {}), - }; - - const { baseCss, themeCss } = loadThemeCss(options.theme); - const css = normalizeThemeCss(buildCss(baseCss, themeCss, style)); - const codeThemeCss = loadCodeThemeCss(options.codeTheme); - - const markdown = fs.readFileSync(inputPath, "utf-8"); - - const renderer = initRenderer({ - legend: options.legend, - citeStatus: options.citeStatus, - countStatus: options.countStatus, - isMacCodeBlock: options.isMacCodeBlock, - isShowLineNumber: options.isShowLineNumber, - }); - const { yamlData } = renderer.parseFrontMatterAndContent(markdown); - const { html: baseHtml, readingTime: readingTimeResult } = renderMarkdown( - markdown, - renderer - ); - let content = postProcessHtml(baseHtml, readingTimeResult, renderer); - if (!options.keepTitle) { - content = removeFirstHeading(content); - } - - const stripQuotes = (s?: string): string | undefined => { - if (!s) return s; - if ((s.startsWith('"') && s.endsWith('"')) || (s.startsWith("'") && s.endsWith("'"))) { - return s.slice(1, -1); - } - if ((s.startsWith('\u201c') && s.endsWith('\u201d')) || (s.startsWith('\u2018') && s.endsWith('\u2019'))) { - return s.slice(1, -1); - } - return s; - }; - - const meta: HtmlDocumentMeta = { - title: stripQuotes(yamlData.title) || path.basename(outputPath, ".html"), - author: stripQuotes(yamlData.author), - description: stripQuotes(yamlData.description) || stripQuotes(yamlData.summary), - }; - const html = buildHtmlDocument(meta, css, content, codeThemeCss); - const inlinedHtml = normalizeInlineCss(await inlineCss(html), style); - const finalHtml = modifyHtmlStructure(inlinedHtml); - - let backupPath = ""; - if (fs.existsSync(outputPath)) { - backupPath = `${outputPath}.bak-${formatTimestamp()}`; - fs.renameSync(outputPath, backupPath); - } - - fs.writeFileSync(outputPath, finalHtml, "utf-8"); - - if (backupPath) { - console.log(`Backup created: ${backupPath}`); - } - console.log(`HTML written: ${outputPath}`); -} - -main().catch((error) => { - console.error(error); - process.exit(1); -}); diff --git a/skills/baoyu-post-to-wechat/scripts/package.json b/skills/baoyu-post-to-wechat/scripts/package.json index b0c15ca..84da8d2 100644 --- a/skills/baoyu-post-to-wechat/scripts/package.json +++ b/skills/baoyu-post-to-wechat/scripts/package.json @@ -3,6 +3,7 @@ "private": true, "type": "module", "dependencies": { - "baoyu-chrome-cdp": "file:./vendor/baoyu-chrome-cdp" + "baoyu-chrome-cdp": "file:./vendor/baoyu-chrome-cdp", + "baoyu-md": "file:./vendor/baoyu-md" } } diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/package.json b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/package.json new file mode 100644 index 0000000..a6f7086 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/package.json @@ -0,0 +1,21 @@ +{ + "name": "baoyu-md", + "private": true, + "version": "0.1.0", + "type": "module", + "exports": { + ".": "./src/index.ts" + }, + "dependencies": { + "fflate": "^0.8.2", + "front-matter": "^4.0.2", + "highlight.js": "^11.11.1", + "juice": "^11.0.1", + "marked": "^15.0.6", + "reading-time": "^1.5.0", + "remark-cjk-friendly": "^1.1.0", + "remark-parse": "^11.0.0", + "remark-stringify": "^11.0.0", + "unified": "^11.0.5" + } +} diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/LICENSE b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/LICENSE new file mode 100644 index 0000000..245b7fe --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/LICENSE @@ -0,0 +1,18 @@ +This directory contains code adapted from the doocs/md project. + +Original project: https://github.com/doocs/md +License: WTFPL (Do What The Fuck You Want To Public License) + + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + Version 2, December 2004 + + Copyright (C) 2025 Doocs + + Everyone is permitted to copy and distribute verbatim or modified + copies of this license document, and changing it is allowed as long + as the name is changed. + + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. You just DO WHAT THE FUCK YOU WANT TO. diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/cli.ts b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/cli.ts new file mode 100644 index 0000000..5a7861b --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/cli.ts @@ -0,0 +1,163 @@ +import type { CliOptions, ThemeName } from "./types.js"; +import { + FONT_FAMILY_MAP, + FONT_SIZE_OPTIONS, + COLOR_PRESETS, + CODE_BLOCK_THEMES, +} from "./constants.js"; +import { THEME_NAMES } from "./themes.js"; +import { loadExtendConfig } from "./extend-config.js"; + +export function printUsage(): void { + console.error( + [ + "Usage:", + " npx tsx render.ts [options]", + "", + "Options:", + ` --theme Theme (${THEME_NAMES.join(", ")})`, + ` --color Primary color: ${Object.keys(COLOR_PRESETS).join(", ")}, or hex`, + ` --font-family Font: ${Object.keys(FONT_FAMILY_MAP).join(", ")}, or CSS value`, + ` --font-size Font size: ${FONT_SIZE_OPTIONS.join(", ")} (default: 16px)`, + ` --code-theme Code highlight theme (default: github)`, + ` --mac-code-block Show Mac-style code block header`, + ` --line-number Show line numbers in code blocks`, + ` --cite Enable footnote citations`, + ` --count Show reading time / word count`, + ` --legend Image caption: title-alt, alt-title, title, alt, none`, + ` --keep-title Keep the first heading in output`, + ].join("\n") + ); +} + +function parseArgValue(argv: string[], i: number, flag: string): string | null { + const arg = argv[i]!; + if (arg.includes("=")) { + return arg.slice(flag.length + 1); + } + const next = argv[i + 1]; + return next ?? null; +} + +function resolveFontFamily(value: string): string { + return FONT_FAMILY_MAP[value] ?? value; +} + +function resolveColor(value: string): string { + return COLOR_PRESETS[value] ?? value; +} + +export function parseArgs(argv: string[]): CliOptions | null { + const ext = loadExtendConfig(); + + let inputPath = ""; + let theme: ThemeName = ext.default_theme ?? "default"; + let keepTitle = ext.keep_title ?? false; + let primaryColor: string | undefined = ext.default_color ? resolveColor(ext.default_color) : undefined; + let fontFamily: string | undefined = ext.default_font_family ? resolveFontFamily(ext.default_font_family) : undefined; + let fontSize: string | undefined = ext.default_font_size ?? undefined; + let codeTheme = ext.default_code_theme ?? "github"; + let isMacCodeBlock = ext.mac_code_block ?? true; + let isShowLineNumber = ext.show_line_number ?? false; + let citeStatus = ext.cite ?? false; + let countStatus = ext.count ?? false; + let legend = ext.legend ?? "alt"; + + for (let i = 0; i < argv.length; i += 1) { + const arg = argv[i]!; + + if (!arg.startsWith("--") && !inputPath) { + inputPath = arg; + continue; + } + + if (arg === "--help" || arg === "-h") { + return null; + } + + if (arg === "--keep-title") { keepTitle = true; continue; } + if (arg === "--mac-code-block") { isMacCodeBlock = true; continue; } + if (arg === "--no-mac-code-block") { isMacCodeBlock = false; continue; } + if (arg === "--line-number") { isShowLineNumber = true; continue; } + if (arg === "--cite") { citeStatus = true; continue; } + if (arg === "--count") { countStatus = true; continue; } + + if (arg === "--theme" || arg.startsWith("--theme=")) { + const val = parseArgValue(argv, i, "--theme"); + if (!val) { console.error("Missing value for --theme"); return null; } + theme = val as ThemeName; + if (!arg.includes("=")) i += 1; + continue; + } + + if (arg === "--color" || arg.startsWith("--color=")) { + const val = parseArgValue(argv, i, "--color"); + if (!val) { console.error("Missing value for --color"); return null; } + primaryColor = resolveColor(val); + if (!arg.includes("=")) i += 1; + continue; + } + + if (arg === "--font-family" || arg.startsWith("--font-family=")) { + const val = parseArgValue(argv, i, "--font-family"); + if (!val) { console.error("Missing value for --font-family"); return null; } + fontFamily = resolveFontFamily(val); + if (!arg.includes("=")) i += 1; + continue; + } + + if (arg === "--font-size" || arg.startsWith("--font-size=")) { + const val = parseArgValue(argv, i, "--font-size"); + if (!val) { console.error("Missing value for --font-size"); return null; } + fontSize = val.endsWith("px") ? val : `${val}px`; + if (!FONT_SIZE_OPTIONS.includes(fontSize)) { + console.error(`Invalid font size: ${fontSize}. Valid: ${FONT_SIZE_OPTIONS.join(", ")}`); + return null; + } + if (!arg.includes("=")) i += 1; + continue; + } + + if (arg === "--code-theme" || arg.startsWith("--code-theme=")) { + const val = parseArgValue(argv, i, "--code-theme"); + if (!val) { console.error("Missing value for --code-theme"); return null; } + codeTheme = val; + if (!CODE_BLOCK_THEMES.includes(codeTheme)) { + console.error(`Unknown code theme: ${codeTheme}`); + return null; + } + if (!arg.includes("=")) i += 1; + continue; + } + + if (arg === "--legend" || arg.startsWith("--legend=")) { + const val = parseArgValue(argv, i, "--legend"); + if (!val) { console.error("Missing value for --legend"); return null; } + const valid = ["title-alt", "alt-title", "title", "alt", "none"]; + if (!valid.includes(val)) { + console.error(`Invalid legend: ${val}. Valid: ${valid.join(", ")}`); + return null; + } + legend = val; + if (!arg.includes("=")) i += 1; + continue; + } + + console.error(`Unknown argument: ${arg}`); + return null; + } + + if (!inputPath) { + return null; + } + + if (!THEME_NAMES.includes(theme)) { + console.error(`Unknown theme: ${theme}`); + return null; + } + + return { + inputPath, theme, keepTitle, primaryColor, fontFamily, fontSize, + codeTheme, isMacCodeBlock, isShowLineNumber, citeStatus, countStatus, legend, + }; +} diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/1c-light.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/1c-light.min.css new file mode 100644 index 0000000..a9d9bf9 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/1c-light.min.css @@ -0,0 +1,9 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*! + Theme: 1c-light + Description: Style IDE 1C:Enterprise 8 + Author: (c) Barilko Vitaliy + Maintainer: @Diversus23 + Website: https://softonit.ru/ + License: see project LICENSE + Touched: 2023 +*/.hljs{color:#00f;background:#fff}.hljs-comment{color:green}.hljs-tag{color:#444a}.hljs-tag .hljs-attr,.hljs-tag .hljs-name{color:#444}.hljs-attribute,.hljs-doctag,.hljs-function,.hljs-keyword,.hljs-name,.hljs-punctuation,.hljs-selector-tag{color:red}.hljs-params,.hljs-type{color:#00f}.hljs-deletion,.hljs-number,.hljs-quote,.hljs-selector-class,.hljs-selector-id,.hljs-string,.hljs-symbol,.hljs-template-tag{color:#000}.hljs-section,.hljs-title{color:#00f}.hljs-link,.hljs-operator,.hljs-regexp,.hljs-selector-attr,.hljs-selector-pseudo,.hljs-template-variable,.hljs-variable{color:#ab5656}.hljs-literal{color:red}.hljs-addition,.hljs-built_in,.hljs-bullet,.hljs-code{color:#00f}.hljs-meta,.hljs-meta .hljs-keyword,.hljs-meta .hljs-string{color:#963200}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/a11y-dark.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/a11y-dark.min.css new file mode 100644 index 0000000..7820d7d --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/a11y-dark.min.css @@ -0,0 +1,7 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*! + Theme: a11y-dark + Author: @ericwbailey + Maintainer: @ericwbailey + + Based on the Tomorrow Night Eighties theme: https://github.com/isagalaev/highlight.js/blob/master/src/styles/tomorrow-night-eighties.css +*/.hljs{background:#2b2b2b;color:#f8f8f2}.hljs-comment,.hljs-quote{color:#d4d0ab}.hljs-deletion,.hljs-name,.hljs-regexp,.hljs-selector-class,.hljs-selector-id,.hljs-tag,.hljs-template-variable,.hljs-variable{color:#ffa07a}.hljs-built_in,.hljs-link,.hljs-literal,.hljs-meta,.hljs-number,.hljs-params,.hljs-type{color:#f5ab35}.hljs-attribute{color:gold}.hljs-addition,.hljs-bullet,.hljs-string,.hljs-symbol{color:#abe338}.hljs-section,.hljs-title{color:#00e0e0}.hljs-keyword,.hljs-selector-tag{color:#dcc6e0}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}@media screen and (-ms-high-contrast:active){.hljs-addition,.hljs-attribute,.hljs-built_in,.hljs-bullet,.hljs-comment,.hljs-link,.hljs-literal,.hljs-meta,.hljs-number,.hljs-params,.hljs-quote,.hljs-string,.hljs-symbol,.hljs-type{color:highlight}.hljs-keyword,.hljs-selector-tag{font-weight:700}} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/a11y-light.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/a11y-light.min.css new file mode 100644 index 0000000..8b5ab90 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/a11y-light.min.css @@ -0,0 +1,7 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*! + Theme: a11y-light + Author: @ericwbailey + Maintainer: @ericwbailey + + Based on the Tomorrow Night Eighties theme: https://github.com/isagalaev/highlight.js/blob/master/src/styles/tomorrow-night-eighties.css +*/.hljs{background:#fefefe;color:#545454}.hljs-comment,.hljs-quote{color:#696969}.hljs-deletion,.hljs-name,.hljs-regexp,.hljs-selector-class,.hljs-selector-id,.hljs-tag,.hljs-template-variable,.hljs-variable{color:#d91e18}.hljs-attribute,.hljs-built_in,.hljs-link,.hljs-literal,.hljs-meta,.hljs-number,.hljs-params,.hljs-type{color:#aa5d00}.hljs-addition,.hljs-bullet,.hljs-string,.hljs-symbol{color:green}.hljs-section,.hljs-title{color:#007faa}.hljs-keyword,.hljs-selector-tag{color:#7928a1}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}@media screen and (-ms-high-contrast:active){.hljs-addition,.hljs-attribute,.hljs-built_in,.hljs-bullet,.hljs-comment,.hljs-link,.hljs-literal,.hljs-meta,.hljs-number,.hljs-params,.hljs-quote,.hljs-string,.hljs-symbol,.hljs-type{color:highlight}.hljs-keyword,.hljs-selector-tag{font-weight:700}} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/agate.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/agate.min.css new file mode 100644 index 0000000..bdbeed4 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/agate.min.css @@ -0,0 +1,20 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*! + Theme: Agate + Author: (c) Taufik Nurrohman + Maintainer: @taufik-nurrohman + Updated: 2021-04-24 + + #333 + #62c8f3 + #7bd694 + #888 + #a2fca2 + #ade5fc + #b8d8a2 + #c6b4f0 + #d36363 + #fc9b9b + #fcc28c + #ffa + #fff +*/.hljs{background:#333;color:#fff}.hljs-doctag,.hljs-meta-keyword,.hljs-name,.hljs-strong{font-weight:700}.hljs-code,.hljs-emphasis{font-style:italic}.hljs-section,.hljs-tag{color:#62c8f3}.hljs-selector-class,.hljs-selector-id,.hljs-template-variable,.hljs-variable{color:#ade5fc}.hljs-meta-string,.hljs-string{color:#a2fca2}.hljs-attr,.hljs-quote,.hljs-selector-attr{color:#7bd694}.hljs-tag .hljs-attr{color:inherit}.hljs-attribute,.hljs-title,.hljs-type{color:#ffa}.hljs-number,.hljs-symbol{color:#d36363}.hljs-bullet,.hljs-template-tag{color:#b8d8a2}.hljs-built_in,.hljs-keyword,.hljs-literal,.hljs-selector-tag{color:#fcc28c}.hljs-code,.hljs-comment,.hljs-formula{color:#888}.hljs-link,.hljs-regexp,.hljs-selector-pseudo{color:#c6b4f0}.hljs-meta{color:#fc9b9b}.hljs-deletion{background:#fc9b9b;color:#333}.hljs-addition{background:#a2fca2;color:#333}.hljs-subst{color:#fff}.hljs a{color:inherit}.hljs a:focus,.hljs a:hover{color:inherit;text-decoration:underline}.hljs mark{background:#555;color:inherit} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/an-old-hope.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/an-old-hope.min.css new file mode 100644 index 0000000..ffc7f8c --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/an-old-hope.min.css @@ -0,0 +1,9 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*! + Theme: An Old Hope – Star Wars Syntax + Author: (c) Gustavo Costa + Maintainer: @gusbemacbe + + Original theme - Ocean Dark Theme – by https://github.com/gavsiu + Based on Jesse Leite's Atom syntax theme 'An Old Hope' + https://github.com/JesseLeite/an-old-hope-syntax-atom +*/.hljs{background:#1c1d21;color:#c0c5ce}.hljs-comment,.hljs-quote{color:#b6b18b}.hljs-deletion,.hljs-name,.hljs-regexp,.hljs-selector-class,.hljs-selector-id,.hljs-tag,.hljs-template-variable,.hljs-variable{color:#eb3c54}.hljs-built_in,.hljs-link,.hljs-literal,.hljs-meta,.hljs-number,.hljs-params,.hljs-type{color:#e7ce56}.hljs-attribute{color:#ee7c2b}.hljs-addition,.hljs-bullet,.hljs-string,.hljs-symbol{color:#4fb4d7}.hljs-section,.hljs-title{color:#78bb65}.hljs-keyword,.hljs-selector-tag{color:#b45ea4}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/androidstudio.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/androidstudio.min.css new file mode 100644 index 0000000..7fbe783 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/androidstudio.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#a9b7c6;background:#282b2e}.hljs-bullet,.hljs-literal,.hljs-number,.hljs-symbol{color:#6897bb}.hljs-deletion,.hljs-keyword,.hljs-selector-tag{color:#cc7832}.hljs-link,.hljs-template-variable,.hljs-variable{color:#629755}.hljs-comment,.hljs-quote{color:grey}.hljs-meta{color:#bbb529}.hljs-addition,.hljs-attribute,.hljs-string{color:#6a8759}.hljs-section,.hljs-title,.hljs-type{color:#ffc66d}.hljs-name,.hljs-selector-class,.hljs-selector-id{color:#e8bf6a}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/arduino-light.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/arduino-light.min.css new file mode 100644 index 0000000..cadb130 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/arduino-light.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#fff;color:#434f54}.hljs-subst{color:#434f54}.hljs-attribute,.hljs-doctag,.hljs-keyword,.hljs-name,.hljs-selector-tag{color:#00979d}.hljs-addition,.hljs-built_in,.hljs-bullet,.hljs-code,.hljs-literal{color:#d35400}.hljs-link,.hljs-regexp,.hljs-selector-attr,.hljs-selector-pseudo,.hljs-symbol,.hljs-template-variable,.hljs-variable{color:#00979d}.hljs-deletion,.hljs-quote,.hljs-selector-class,.hljs-selector-id,.hljs-string,.hljs-template-tag,.hljs-type{color:#005c5f}.hljs-comment{color:rgba(149,165,166,.8)}.hljs-meta .hljs-keyword{color:#728e00}.hljs-meta{color:#434f54}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}.hljs-function{color:#728e00}.hljs-section,.hljs-title{color:#800;font-weight:700}.hljs-number{color:#8a7b52} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/arta.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/arta.min.css new file mode 100644 index 0000000..8dcdc74 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/arta.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#222;color:#aaa}.hljs-subst{color:#aaa}.hljs-section{color:#fff}.hljs-comment,.hljs-meta,.hljs-quote{color:#444}.hljs-bullet,.hljs-regexp,.hljs-string,.hljs-symbol{color:#fc3}.hljs-addition,.hljs-number{color:#0c6}.hljs-attribute,.hljs-built_in,.hljs-link,.hljs-literal,.hljs-template-variable,.hljs-type{color:#32aaee}.hljs-keyword,.hljs-name,.hljs-selector-class,.hljs-selector-id,.hljs-selector-tag{color:#64a}.hljs-deletion,.hljs-template-tag,.hljs-title,.hljs-variable{color:#b16}.hljs-doctag,.hljs-section,.hljs-strong{font-weight:700}.hljs-emphasis{font-style:italic} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/ascetic.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/ascetic.min.css new file mode 100644 index 0000000..3c9fe03 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/ascetic.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#fff;color:#000}.hljs-addition,.hljs-attribute,.hljs-bullet,.hljs-link,.hljs-section,.hljs-string,.hljs-symbol,.hljs-template-variable,.hljs-variable{color:#888}.hljs-comment,.hljs-deletion,.hljs-meta,.hljs-quote{color:#ccc}.hljs-keyword,.hljs-name,.hljs-section,.hljs-selector-tag,.hljs-strong,.hljs-type{font-weight:700}.hljs-emphasis{font-style:italic} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/atom-one-dark-reasonable.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/atom-one-dark-reasonable.min.css new file mode 100644 index 0000000..9296216 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/atom-one-dark-reasonable.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#abb2bf;background:#282c34}.hljs-keyword,.hljs-operator,.hljs-pattern-match{color:#f92672}.hljs-function,.hljs-pattern-match .hljs-constructor{color:#61aeee}.hljs-function .hljs-params{color:#a6e22e}.hljs-function .hljs-params .hljs-typing{color:#fd971f}.hljs-module-access .hljs-module{color:#7e57c2}.hljs-constructor{color:#e2b93d}.hljs-constructor .hljs-string{color:#9ccc65}.hljs-comment,.hljs-quote{color:#b18eb1;font-style:italic}.hljs-doctag,.hljs-formula{color:#c678dd}.hljs-deletion,.hljs-name,.hljs-section,.hljs-selector-tag,.hljs-subst{color:#e06c75}.hljs-literal{color:#56b6c2}.hljs-addition,.hljs-attribute,.hljs-meta .hljs-string,.hljs-regexp,.hljs-string{color:#98c379}.hljs-built_in,.hljs-class .hljs-title,.hljs-title.class_{color:#e6c07b}.hljs-attr,.hljs-number,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-pseudo,.hljs-template-variable,.hljs-type,.hljs-variable{color:#d19a66}.hljs-bullet,.hljs-link,.hljs-meta,.hljs-selector-id,.hljs-symbol,.hljs-title{color:#61aeee}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}.hljs-link{text-decoration:underline} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/atom-one-dark.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/atom-one-dark.min.css new file mode 100644 index 0000000..5344ee3 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/atom-one-dark.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#abb2bf;background:#282c34}.hljs-comment,.hljs-quote{color:#5c6370;font-style:italic}.hljs-doctag,.hljs-formula,.hljs-keyword{color:#c678dd}.hljs-deletion,.hljs-name,.hljs-section,.hljs-selector-tag,.hljs-subst{color:#e06c75}.hljs-literal{color:#56b6c2}.hljs-addition,.hljs-attribute,.hljs-meta .hljs-string,.hljs-regexp,.hljs-string{color:#98c379}.hljs-attr,.hljs-number,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-pseudo,.hljs-template-variable,.hljs-type,.hljs-variable{color:#d19a66}.hljs-bullet,.hljs-link,.hljs-meta,.hljs-selector-id,.hljs-symbol,.hljs-title{color:#61aeee}.hljs-built_in,.hljs-class .hljs-title,.hljs-title.class_{color:#e6c07b}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}.hljs-link{text-decoration:underline} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/atom-one-light.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/atom-one-light.min.css new file mode 100644 index 0000000..df0268a --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/atom-one-light.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#383a42;background:#fafafa}.hljs-comment,.hljs-quote{color:#a0a1a7;font-style:italic}.hljs-doctag,.hljs-formula,.hljs-keyword{color:#a626a4}.hljs-deletion,.hljs-name,.hljs-section,.hljs-selector-tag,.hljs-subst{color:#e45649}.hljs-literal{color:#0184bb}.hljs-addition,.hljs-attribute,.hljs-meta .hljs-string,.hljs-regexp,.hljs-string{color:#50a14f}.hljs-attr,.hljs-number,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-pseudo,.hljs-template-variable,.hljs-type,.hljs-variable{color:#986801}.hljs-bullet,.hljs-link,.hljs-meta,.hljs-selector-id,.hljs-symbol,.hljs-title{color:#4078f2}.hljs-built_in,.hljs-class .hljs-title,.hljs-title.class_{color:#c18401}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}.hljs-link{text-decoration:underline} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/brown-paper.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/brown-paper.min.css new file mode 100644 index 0000000..6231e8a --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/brown-paper.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#363c69;background:url(./brown-papersq.png) #b7a68e}.hljs-keyword,.hljs-literal,.hljs-selector-tag{color:#059}.hljs-addition,.hljs-attribute,.hljs-built_in,.hljs-bullet,.hljs-link,.hljs-name,.hljs-section,.hljs-string,.hljs-symbol,.hljs-template-tag,.hljs-template-variable,.hljs-title,.hljs-type,.hljs-variable{color:#2c009f}.hljs-comment,.hljs-deletion,.hljs-meta,.hljs-quote{color:#802022}.hljs-doctag,.hljs-keyword,.hljs-literal,.hljs-name,.hljs-section,.hljs-selector-tag,.hljs-strong,.hljs-title,.hljs-type{font-weight:700}.hljs-emphasis{font-style:italic} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/codepen-embed.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/codepen-embed.min.css new file mode 100644 index 0000000..0d7dff6 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/codepen-embed.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#222;color:#fff}.hljs-comment,.hljs-quote{color:#777}.hljs-built_in,.hljs-bullet,.hljs-deletion,.hljs-link,.hljs-literal,.hljs-meta,.hljs-number,.hljs-params,.hljs-regexp,.hljs-symbol,.hljs-tag,.hljs-template-variable,.hljs-variable{color:#ab875d}.hljs-attribute,.hljs-name,.hljs-section,.hljs-selector-class,.hljs-selector-id,.hljs-title,.hljs-type{color:#9b869b}.hljs-addition,.hljs-keyword,.hljs-selector-tag,.hljs-string{color:#8f9c6c}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/color-brewer.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/color-brewer.min.css new file mode 100644 index 0000000..1c677e3 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/color-brewer.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#000;background:#fff}.hljs-addition,.hljs-meta,.hljs-string,.hljs-symbol,.hljs-template-tag,.hljs-template-variable{color:#756bb1}.hljs-comment,.hljs-quote{color:#636363}.hljs-bullet,.hljs-link,.hljs-literal,.hljs-number,.hljs-regexp{color:#31a354}.hljs-deletion,.hljs-variable{color:#88f}.hljs-built_in,.hljs-doctag,.hljs-keyword,.hljs-name,.hljs-section,.hljs-selector-class,.hljs-selector-id,.hljs-selector-tag,.hljs-strong,.hljs-tag,.hljs-title,.hljs-type{color:#3182bd}.hljs-emphasis{font-style:italic}.hljs-attribute{color:#e6550d} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/dark.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/dark.min.css new file mode 100644 index 0000000..9ed546b --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/dark.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#ddd;background:#303030}.hljs-keyword,.hljs-link,.hljs-literal,.hljs-section,.hljs-selector-tag{color:#fff}.hljs-addition,.hljs-attribute,.hljs-built_in,.hljs-bullet,.hljs-name,.hljs-string,.hljs-symbol,.hljs-template-tag,.hljs-template-variable,.hljs-title,.hljs-type,.hljs-variable{color:#d88}.hljs-comment,.hljs-deletion,.hljs-meta,.hljs-quote{color:#979797}.hljs-doctag,.hljs-keyword,.hljs-literal,.hljs-name,.hljs-section,.hljs-selector-tag,.hljs-strong,.hljs-title,.hljs-type{font-weight:700}.hljs-emphasis{font-style:italic} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/default.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/default.min.css new file mode 100644 index 0000000..a75ea91 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/default.min.css @@ -0,0 +1,9 @@ +/*! + Theme: Default + Description: Original highlight.js style + Author: (c) Ivan Sagalaev + Maintainer: @highlightjs/core-team + Website: https://highlightjs.org/ + License: see project LICENSE + Touched: 2021 +*/pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#f3f3f3;color:#444}.hljs-comment{color:#697070}.hljs-punctuation,.hljs-tag{color:#444a}.hljs-tag .hljs-attr,.hljs-tag .hljs-name{color:#444}.hljs-attribute,.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-name,.hljs-selector-tag{font-weight:700}.hljs-deletion,.hljs-number,.hljs-quote,.hljs-selector-class,.hljs-selector-id,.hljs-string,.hljs-template-tag,.hljs-type{color:#800}.hljs-section,.hljs-title{color:#800;font-weight:700}.hljs-link,.hljs-operator,.hljs-regexp,.hljs-selector-attr,.hljs-selector-pseudo,.hljs-symbol,.hljs-template-variable,.hljs-variable{color:#ab5656}.hljs-literal{color:#695}.hljs-addition,.hljs-built_in,.hljs-bullet,.hljs-code{color:#397300}.hljs-meta{color:#1f7199}.hljs-meta .hljs-string{color:#38a}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/devibeans.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/devibeans.min.css new file mode 100644 index 0000000..d8c4c0f --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/devibeans.min.css @@ -0,0 +1,7 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*! + Theme: devibeans (dark) + Author: @terminaldweller + Maintainer: @terminaldweller + + Inspired by vim's jellybeans theme (https://github.com/nanotech/jellybeans.vim) +*/.hljs{background:#000;color:#a39e9b}.hljs-attr,.hljs-template-tag{color:#8787d7}.hljs-comment,.hljs-doctag,.hljs-quote{color:#396}.hljs-params{color:#a39e9b}.hljs-regexp{color:#d700ff}.hljs-literal,.hljs-number,.hljs-selector-id,.hljs-tag{color:#ef5350}.hljs-meta,.hljs-meta .hljs-keyword{color:#0087ff}.hljs-code,.hljs-formula,.hljs-keyword,.hljs-link,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-pseudo,.hljs-template-variable,.hljs-variable{color:#64b5f6}.hljs-built_in,.hljs-deletion,.hljs-title{color:#ff8700}.hljs-attribute,.hljs-function,.hljs-name,.hljs-property,.hljs-section,.hljs-type{color:#ffd75f}.hljs-addition,.hljs-bullet,.hljs-meta .hljs-string,.hljs-string,.hljs-subst,.hljs-symbol{color:#558b2f}.hljs-selector-tag{color:#96f}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/docco.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/docco.min.css new file mode 100644 index 0000000..382ecbb --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/docco.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#000;background:#f8f8ff}.hljs-comment,.hljs-quote{color:#408080;font-style:italic}.hljs-keyword,.hljs-literal,.hljs-selector-tag,.hljs-subst{color:#954121}.hljs-number{color:#40a070}.hljs-doctag,.hljs-string{color:#219161}.hljs-section,.hljs-selector-class,.hljs-selector-id,.hljs-type{color:#19469d}.hljs-params{color:#00f}.hljs-title{color:#458;font-weight:700}.hljs-attribute,.hljs-name,.hljs-tag{color:navy;font-weight:400}.hljs-template-variable,.hljs-variable{color:teal}.hljs-link,.hljs-regexp{color:#b68}.hljs-bullet,.hljs-symbol{color:#990073}.hljs-built_in{color:#0086b3}.hljs-meta{color:#999;font-weight:700}.hljs-deletion{background:#fdd}.hljs-addition{background:#dfd}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/far.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/far.min.css new file mode 100644 index 0000000..c338ef6 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/far.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#0ff;background:navy}.hljs-addition,.hljs-attribute,.hljs-built_in,.hljs-bullet,.hljs-string,.hljs-symbol,.hljs-template-tag,.hljs-template-variable{color:#ff0}.hljs-keyword,.hljs-name,.hljs-section,.hljs-selector-class,.hljs-selector-id,.hljs-selector-tag,.hljs-type,.hljs-variable{color:#fff}.hljs-comment,.hljs-deletion,.hljs-doctag,.hljs-quote{color:#888}.hljs-link,.hljs-literal,.hljs-number,.hljs-regexp{color:#0f0}.hljs-meta{color:teal}.hljs-keyword,.hljs-name,.hljs-section,.hljs-selector-tag,.hljs-strong,.hljs-title{font-weight:700}.hljs-emphasis{font-style:italic} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/felipec.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/felipec.min.css new file mode 100644 index 0000000..7f76cd0 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/felipec.min.css @@ -0,0 +1,7 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*! + * Theme: FelipeC + * Author: (c) 2021 Felipe Contreras + * Website: https://github.com/felipec/vim-felipec + * + * Autogenerated with vim-felipec's generator. +*/.hljs{color:#dedde4;background-color:#1d1c21}.hljs ::selection,.hljs::selection{color:#1d1c21;background-color:#ba9cef}.hljs-code,.hljs-comment,.hljs-quote{color:#9e9da4}.hljs-deletion,.hljs-literal,.hljs-number{color:#f09080}.hljs-doctag,.hljs-meta,.hljs-operator,.hljs-punctuation,.hljs-selector-attr,.hljs-subst,.hljs-template-variable{color:#ffbb7b}.hljs-type{color:#fddb7c}.hljs-selector-class,.hljs-selector-id,.hljs-tag,.hljs-title{color:#c4da7d}.hljs-addition,.hljs-regexp,.hljs-string{color:#93e4a4}.hljs-class,.hljs-property{color:#65e7d1}.hljs-name,.hljs-selector-tag{color:#30c2d8}.hljs-built_in,.hljs-keyword{color:#5fb8f2}.hljs-bullet,.hljs-section{color:#90aafa}.hljs-selector-pseudo{color:#ba9cef}.hljs-attr,.hljs-attribute,.hljs-params,.hljs-variable{color:#d991d2}.hljs-link,.hljs-symbol{color:#ec8dab}.hljs-literal,.hljs-strong,.hljs-title{font-weight:700}.hljs-emphasis{font-style:italic} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/foundation.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/foundation.min.css new file mode 100644 index 0000000..1ddcfa6 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/foundation.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#eee;color:#000}.hljs-addition,.hljs-attribute,.hljs-emphasis,.hljs-link{color:#070}.hljs-emphasis{font-style:italic}.hljs-deletion,.hljs-string,.hljs-strong{color:#d14}.hljs-strong{font-weight:700}.hljs-comment,.hljs-quote{color:#998;font-style:italic}.hljs-section,.hljs-title{color:#900}.hljs-class .hljs-title,.hljs-title.class_,.hljs-type{color:#458}.hljs-template-variable,.hljs-variable{color:#369}.hljs-bullet{color:#970}.hljs-meta{color:#34b}.hljs-code,.hljs-keyword,.hljs-literal,.hljs-number,.hljs-selector-tag{color:#099}.hljs-regexp{background-color:#fff0ff;color:#808}.hljs-symbol{color:#990073}.hljs-name,.hljs-selector-class,.hljs-selector-id,.hljs-tag{color:#070} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/github-dark-dimmed.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/github-dark-dimmed.min.css new file mode 100644 index 0000000..e266dfc --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/github-dark-dimmed.min.css @@ -0,0 +1,9 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*! + Theme: GitHub Dark Dimmed + Description: Dark dimmed theme as seen on github.com + Author: github.com + Maintainer: @Hirse + Updated: 2021-05-15 + + Colors taken from GitHub's CSS +*/.hljs{color:#adbac7;background:#22272e}.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language_{color:#f47067}.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-title.function_{color:#dcbdfb}.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-variable{color:#6cb6ff}.hljs-meta .hljs-string,.hljs-regexp,.hljs-string{color:#96d0ff}.hljs-built_in,.hljs-symbol{color:#f69d50}.hljs-code,.hljs-comment,.hljs-formula{color:#768390}.hljs-name,.hljs-quote,.hljs-selector-pseudo,.hljs-selector-tag{color:#8ddb8c}.hljs-subst{color:#adbac7}.hljs-section{color:#316dca;font-weight:700}.hljs-bullet{color:#eac55f}.hljs-emphasis{color:#adbac7;font-style:italic}.hljs-strong{color:#adbac7;font-weight:700}.hljs-addition{color:#b4f1b4;background-color:#1b4721}.hljs-deletion{color:#ffd8d3;background-color:#78191b} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/github-dark.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/github-dark.min.css new file mode 100644 index 0000000..03b6da8 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/github-dark.min.css @@ -0,0 +1,10 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*! + Theme: GitHub Dark + Description: Dark theme as seen on github.com + Author: github.com + Maintainer: @Hirse + Updated: 2021-05-15 + + Outdated base version: https://github.com/primer/github-syntax-dark + Current colors taken from GitHub's CSS +*/.hljs{color:#c9d1d9;background:#0d1117}.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language_{color:#ff7b72}.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-title.function_{color:#d2a8ff}.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-variable{color:#79c0ff}.hljs-meta .hljs-string,.hljs-regexp,.hljs-string{color:#a5d6ff}.hljs-built_in,.hljs-symbol{color:#ffa657}.hljs-code,.hljs-comment,.hljs-formula{color:#8b949e}.hljs-name,.hljs-quote,.hljs-selector-pseudo,.hljs-selector-tag{color:#7ee787}.hljs-subst{color:#c9d1d9}.hljs-section{color:#1f6feb;font-weight:700}.hljs-bullet{color:#f2cc60}.hljs-emphasis{color:#c9d1d9;font-style:italic}.hljs-strong{color:#c9d1d9;font-weight:700}.hljs-addition{color:#aff5b4;background-color:#033a16}.hljs-deletion{color:#ffdcd7;background-color:#67060c} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/github.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/github.min.css new file mode 100644 index 0000000..275239a --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/github.min.css @@ -0,0 +1,10 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*! + Theme: GitHub + Description: Light theme as seen on github.com + Author: github.com + Maintainer: @Hirse + Updated: 2021-05-15 + + Outdated base version: https://github.com/primer/github-syntax-light + Current colors taken from GitHub's CSS +*/.hljs{color:#24292e;background:#fff}.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language_{color:#d73a49}.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-title.function_{color:#6f42c1}.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-variable{color:#005cc5}.hljs-meta .hljs-string,.hljs-regexp,.hljs-string{color:#032f62}.hljs-built_in,.hljs-symbol{color:#e36209}.hljs-code,.hljs-comment,.hljs-formula{color:#6a737d}.hljs-name,.hljs-quote,.hljs-selector-pseudo,.hljs-selector-tag{color:#22863a}.hljs-subst{color:#24292e}.hljs-section{color:#005cc5;font-weight:700}.hljs-bullet{color:#735c0f}.hljs-emphasis{color:#24292e;font-style:italic}.hljs-strong{color:#24292e;font-weight:700}.hljs-addition{color:#22863a;background-color:#f0fff4}.hljs-deletion{color:#b31d28;background-color:#ffeef0} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/gml.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/gml.min.css new file mode 100644 index 0000000..89455fe --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/gml.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#222;color:silver}.hljs-keyword{color:#ffb871;font-weight:700}.hljs-built_in{color:#ffb871}.hljs-literal{color:#ff8080}.hljs-symbol{color:#58e55a}.hljs-comment{color:#5b995b}.hljs-string{color:#ff0}.hljs-number{color:#ff8080}.hljs-addition,.hljs-attribute,.hljs-bullet,.hljs-code,.hljs-deletion,.hljs-doctag,.hljs-function,.hljs-link,.hljs-meta,.hljs-meta .hljs-keyword,.hljs-name,.hljs-quote,.hljs-regexp,.hljs-section,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-selector-pseudo,.hljs-selector-tag,.hljs-subst,.hljs-template-tag,.hljs-template-variable,.hljs-title,.hljs-type,.hljs-variable{color:silver}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/googlecode.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/googlecode.min.css new file mode 100644 index 0000000..0140b89 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/googlecode.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#fff;color:#000}.hljs-comment,.hljs-quote{color:#800}.hljs-keyword,.hljs-name,.hljs-section,.hljs-selector-tag,.hljs-title{color:#008}.hljs-template-variable,.hljs-variable{color:#660}.hljs-regexp,.hljs-selector-attr,.hljs-selector-pseudo,.hljs-string{color:#080}.hljs-bullet,.hljs-link,.hljs-literal,.hljs-meta,.hljs-number,.hljs-symbol{color:#066}.hljs-attr,.hljs-built_in,.hljs-doctag,.hljs-params,.hljs-title,.hljs-type{color:#606}.hljs-attribute,.hljs-subst{color:#000}.hljs-formula{background-color:#eee;font-style:italic}.hljs-selector-class,.hljs-selector-id{color:#9b703f}.hljs-addition{background-color:#baeeba}.hljs-deletion{background-color:#ffc8bd}.hljs-doctag,.hljs-strong{font-weight:700}.hljs-emphasis{font-style:italic} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/gradient-dark.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/gradient-dark.min.css new file mode 100644 index 0000000..4aba928 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/gradient-dark.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background-color:#652487;background-image:linear-gradient(160deg,#652487 0,#443ac3 35%,#0174b7 68%,#04988e 100%);color:#e7e4eb}.hljs-subtr{color:#e7e4eb}.hljs-comment,.hljs-doctag,.hljs-meta,.hljs-quote{color:#af8dd9}.hljs-attr,.hljs-regexp,.hljs-selector-id,.hljs-selector-tag,.hljs-tag,.hljs-template-tag{color:#aefbff}.hljs-bullet,.hljs-params,.hljs-selector-class{color:#f19fff}.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-section,.hljs-symbol,.hljs-type{color:#17fc95}.hljs-addition,.hljs-link,.hljs-number{color:#c5fe00}.hljs-string{color:#38c0ff}.hljs-addition,.hljs-attribute{color:#e7ff9f}.hljs-template-variable,.hljs-variable{color:#e447ff}.hljs-built_in,.hljs-class,.hljs-formula,.hljs-function,.hljs-name,.hljs-title{color:#ffc800}.hljs-deletion,.hljs-literal,.hljs-selector-pseudo{color:#ff9e44}.hljs-emphasis,.hljs-quote{font-style:italic}.hljs-keyword,.hljs-params,.hljs-section,.hljs-selector-class,.hljs-selector-id,.hljs-selector-tag,.hljs-strong,.hljs-template-tag{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/gradient-light.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/gradient-light.min.css new file mode 100644 index 0000000..c5db6fd --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/gradient-light.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background-color:#f9ccff;background-image:linear-gradient(295deg,#f9ccff 0,#e6bbf9 11%,#9ec6f9 32%,#55e6ee 60%,#91f5d1 74%,#f9ffbf 98%);color:#250482}.hljs-subtr{color:#01958b}.hljs-comment,.hljs-doctag,.hljs-meta,.hljs-quote{color:#cb7200}.hljs-attr,.hljs-regexp,.hljs-selector-id,.hljs-selector-tag,.hljs-tag,.hljs-template-tag{color:#07bd5f}.hljs-bullet,.hljs-params,.hljs-selector-class{color:#43449f}.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-section,.hljs-symbol,.hljs-type{color:#7d2801}.hljs-addition,.hljs-link,.hljs-number{color:#7f0096}.hljs-string{color:#2681ab}.hljs-addition,.hljs-attribute{color:#296562}.hljs-template-variable,.hljs-variable{color:#025c8f}.hljs-built_in,.hljs-class,.hljs-formula,.hljs-function,.hljs-name,.hljs-title{color:#529117}.hljs-deletion,.hljs-literal,.hljs-selector-pseudo{color:#ad13ff}.hljs-emphasis,.hljs-quote{font-style:italic}.hljs-keyword,.hljs-params,.hljs-section,.hljs-selector-class,.hljs-selector-id,.hljs-selector-tag,.hljs-strong,.hljs-template-tag{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/grayscale.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/grayscale.min.css new file mode 100644 index 0000000..5eefdaa --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/grayscale.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#333;background:#fff}.hljs-comment,.hljs-quote{color:#777;font-style:italic}.hljs-keyword,.hljs-selector-tag,.hljs-subst{color:#333;font-weight:700}.hljs-literal,.hljs-number{color:#777}.hljs-doctag,.hljs-formula,.hljs-string{color:#333;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAYAAACp8Z5+AAAAJ0lEQVQIW2O8e/fufwYGBgZBQUEQxcCIIfDu3Tuwivfv30NUoAsAALHpFMMLqZlPAAAAAElFTkSuQmCC)}.hljs-section,.hljs-selector-id,.hljs-title{color:#000;font-weight:700}.hljs-subst{font-weight:400}.hljs-class .hljs-title,.hljs-name,.hljs-title.class_,.hljs-type{color:#333;font-weight:700}.hljs-tag{color:#333}.hljs-regexp{color:#333;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAICAYAAADA+m62AAAAPUlEQVQYV2NkQAN37979r6yszIgujiIAU4RNMVwhuiQ6H6wQl3XI4oy4FMHcCJPHcDS6J2A2EqUQpJhohQDexSef15DBCwAAAABJRU5ErkJggg==)}.hljs-bullet,.hljs-link,.hljs-symbol{color:#000;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAKElEQVQIW2NkQAO7d+/+z4gsBhJwdXVlhAvCBECKwIIwAbhKZBUwBQA6hBpm5efZsgAAAABJRU5ErkJggg==)}.hljs-built_in{color:#000;text-decoration:underline}.hljs-meta{color:#999;font-weight:700}.hljs-deletion{color:#fff;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAADCAYAAABS3WWCAAAAE0lEQVQIW2MMDQ39zzhz5kwIAQAyxweWgUHd1AAAAABJRU5ErkJggg==)}.hljs-addition{color:#000;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAYAAADgkQYQAAAALUlEQVQYV2N89+7dfwYk8P79ewZBQUFkIQZGOiu6e/cuiptQHAPl0NtNxAQBAM97Oejj3Dg7AAAAAElFTkSuQmCC)}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/hybrid.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/hybrid.min.css new file mode 100644 index 0000000..52489b6 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/hybrid.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#1d1f21;color:#c5c8c6}.hljs span::selection,.hljs::selection{background:#373b41}.hljs span::-moz-selection,.hljs::-moz-selection{background:#373b41}.hljs-name,.hljs-title{color:#f0c674}.hljs-comment,.hljs-meta,.hljs-meta .hljs-keyword{color:#707880}.hljs-deletion,.hljs-link,.hljs-literal,.hljs-number,.hljs-symbol{color:#c66}.hljs-addition,.hljs-doctag,.hljs-regexp,.hljs-selector-attr,.hljs-selector-pseudo,.hljs-string{color:#b5bd68}.hljs-attribute,.hljs-code,.hljs-selector-id{color:#b294bb}.hljs-bullet,.hljs-keyword,.hljs-selector-tag,.hljs-tag{color:#81a2be}.hljs-subst,.hljs-template-tag,.hljs-template-variable,.hljs-variable{color:#8abeb7}.hljs-built_in,.hljs-quote,.hljs-section,.hljs-selector-class,.hljs-type{color:#de935f}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/idea.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/idea.min.css new file mode 100644 index 0000000..7cc62ff --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/idea.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#000;background:#fff}.hljs-subst,.hljs-title{font-weight:400;color:#000}.hljs-comment,.hljs-quote{color:grey;font-style:italic}.hljs-meta{color:olive}.hljs-tag{background:#efefef}.hljs-keyword,.hljs-literal,.hljs-name,.hljs-section,.hljs-selector-class,.hljs-selector-id,.hljs-selector-tag,.hljs-type{font-weight:700;color:navy}.hljs-attribute,.hljs-link,.hljs-number,.hljs-regexp{font-weight:700;color:#00f}.hljs-link,.hljs-number,.hljs-regexp{font-weight:400}.hljs-string{color:green;font-weight:700}.hljs-bullet,.hljs-formula,.hljs-symbol{color:#000;background:#d0eded;font-style:italic}.hljs-doctag{text-decoration:underline}.hljs-template-variable,.hljs-variable{color:#660e7a}.hljs-addition{background:#baeeba}.hljs-deletion{background:#ffc8bd}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/intellij-light.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/intellij-light.min.css new file mode 100644 index 0000000..97fc3e2 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/intellij-light.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#000;background:#fff}.hljs-subst,.hljs-title{font-weight:400;color:#000}.hljs-title.function_{color:#7a7a43}.hljs-code,.hljs-comment,.hljs-quote{color:#8c8c8c;font-style:italic}.hljs-meta{color:#9e880d}.hljs-section{color:#871094}.hljs-built_in,.hljs-keyword,.hljs-literal,.hljs-meta .hljs-keyword,.hljs-name,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-selector-pseudo,.hljs-selector-tag,.hljs-symbol,.hljs-template-tag,.hljs-type,.hljs-variable.language_{color:#0033b3}.hljs-attr,.hljs-property{color:#871094}.hljs-attribute{color:#174ad4}.hljs-number{color:#1750eb}.hljs-regexp{color:#264eff}.hljs-link{text-decoration:underline;color:#006dcc}.hljs-meta .hljs-string,.hljs-string{color:#067d17}.hljs-char.escape_{color:#0037a6}.hljs-doctag{text-decoration:underline}.hljs-template-variable{color:#248f8f}.hljs-addition{background:#bee6be}.hljs-deletion{background:#d6d6d6}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/ir-black.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/ir-black.min.css new file mode 100644 index 0000000..e78fd08 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/ir-black.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#000;color:#f8f8f8}.hljs-comment,.hljs-meta,.hljs-quote{color:#7c7c7c}.hljs-keyword,.hljs-name,.hljs-selector-tag,.hljs-tag{color:#96cbfe}.hljs-attribute,.hljs-selector-id{color:#ffffb6}.hljs-addition,.hljs-selector-attr,.hljs-selector-pseudo,.hljs-string{color:#a8ff60}.hljs-subst{color:#daefa3}.hljs-link,.hljs-regexp{color:#e9c062}.hljs-doctag,.hljs-section,.hljs-title,.hljs-type{color:#ffffb6}.hljs-bullet,.hljs-literal,.hljs-symbol,.hljs-template-variable,.hljs-variable{color:#c6c5fe}.hljs-deletion,.hljs-number{color:#ff73fd}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/isbl-editor-dark.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/isbl-editor-dark.min.css new file mode 100644 index 0000000..535ef87 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/isbl-editor-dark.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#404040}.hljs,.hljs-subst{color:#f0f0f0}.hljs-comment{color:#b5b5b5;font-style:italic}.hljs-attribute,.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-name,.hljs-selector-tag{color:#f0f0f0;font-weight:700}.hljs-string{color:#97bf0d}.hljs-deletion,.hljs-number,.hljs-quote,.hljs-selector-class,.hljs-selector-id,.hljs-template-tag,.hljs-type{color:#f0f0f0}.hljs-link,.hljs-regexp,.hljs-selector-attr,.hljs-selector-pseudo,.hljs-symbol,.hljs-template-variable,.hljs-variable{color:#e2c696}.hljs-built_in,.hljs-literal{color:#97bf0d;font-weight:700}.hljs-addition,.hljs-bullet,.hljs-code{color:#397300}.hljs-class{color:#ce9d4d;font-weight:700}.hljs-section,.hljs-title{color:#df471e}.hljs-title>.hljs-built_in{color:#81bce9;font-weight:400}.hljs-meta{color:#1f7199}.hljs-meta .hljs-string{color:#4d99bf}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/isbl-editor-light.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/isbl-editor-light.min.css new file mode 100644 index 0000000..f008c74 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/isbl-editor-light.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#fff;color:#000}.hljs-subst{color:#000}.hljs-comment{color:#555;font-style:italic}.hljs-attribute,.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-name,.hljs-selector-tag{color:#000;font-weight:700}.hljs-string{color:navy}.hljs-deletion,.hljs-number,.hljs-quote,.hljs-selector-class,.hljs-selector-id,.hljs-template-tag,.hljs-type{color:#000}.hljs-link,.hljs-regexp,.hljs-selector-attr,.hljs-selector-pseudo,.hljs-symbol,.hljs-template-variable,.hljs-variable{color:#5e1700}.hljs-built_in,.hljs-literal{color:navy;font-weight:700}.hljs-addition,.hljs-bullet,.hljs-code{color:#397300}.hljs-class{color:#6f1c00;font-weight:700}.hljs-section,.hljs-title{color:#fb2c00}.hljs-title>.hljs-built_in{color:teal;font-weight:400}.hljs-meta{color:#1f7199}.hljs-meta .hljs-string{color:#4d99bf}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/kimbie-dark.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/kimbie-dark.min.css new file mode 100644 index 0000000..cf56cea --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/kimbie-dark.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#221a0f;color:#d3af86}.hljs-comment,.hljs-quote{color:#d6baad}.hljs-meta,.hljs-name,.hljs-regexp,.hljs-selector-class,.hljs-selector-id,.hljs-tag,.hljs-template-variable,.hljs-variable{color:#dc3958}.hljs-built_in,.hljs-deletion,.hljs-link,.hljs-literal,.hljs-number,.hljs-params,.hljs-type{color:#f79a32}.hljs-addition,.hljs-bullet,.hljs-string,.hljs-symbol{color:#889b4a}.hljs-function,.hljs-keyword,.hljs-selector-tag{color:#98676a}.hljs-attribute,.hljs-section,.hljs-title{color:#f06431}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/kimbie-light.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/kimbie-light.min.css new file mode 100644 index 0000000..b9d0ea4 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/kimbie-light.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#fbebd4;color:#84613d}.hljs-comment,.hljs-quote{color:#a57a4c}.hljs-meta,.hljs-name,.hljs-regexp,.hljs-selector-class,.hljs-selector-id,.hljs-tag,.hljs-template-variable,.hljs-variable{color:#dc3958}.hljs-built_in,.hljs-deletion,.hljs-link,.hljs-literal,.hljs-number,.hljs-params,.hljs-type{color:#f79a32}.hljs-addition,.hljs-bullet,.hljs-string,.hljs-symbol{color:#889b4a}.hljs-function,.hljs-keyword,.hljs-selector-tag{color:#98676a}.hljs-attribute,.hljs-section,.hljs-title{color:#f06431}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/lightfair.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/lightfair.min.css new file mode 100644 index 0000000..b6c3791 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/lightfair.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#444;background:#fff}.hljs-name{color:#01a3a3}.hljs-meta,.hljs-tag{color:#789}.hljs-comment{color:#888}.hljs-attribute,.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-name,.hljs-selector-tag{font-weight:700}.hljs-deletion,.hljs-number,.hljs-quote,.hljs-selector-class,.hljs-selector-id,.hljs-string,.hljs-template-tag,.hljs-type{color:#4286f4}.hljs-section,.hljs-title{color:#4286f4;font-weight:700}.hljs-link,.hljs-regexp,.hljs-selector-attr,.hljs-selector-pseudo,.hljs-symbol,.hljs-template-variable,.hljs-variable{color:#bc6060}.hljs-literal{color:#62bcbc}.hljs-addition,.hljs-built_in,.hljs-bullet,.hljs-code{color:#25c6c6}.hljs-meta .hljs-string{color:#4d99bf}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/lioshi.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/lioshi.min.css new file mode 100644 index 0000000..3d6a92f --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/lioshi.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#303030;color:#c5c8c6}.hljs-comment{color:#8d8d8d}.hljs-quote{color:#b3c7d8}.hljs-deletion,.hljs-name,.hljs-regexp,.hljs-selector-class,.hljs-selector-id,.hljs-tag,.hljs-template-variable,.hljs-variable{color:#c66}.hljs-built_in,.hljs-literal,.hljs-number,.hljs-subst .hljs-link,.hljs-type{color:#de935f}.hljs-attribute{color:#f0c674}.hljs-addition,.hljs-bullet,.hljs-params,.hljs-string{color:#b5bd68}.hljs-class,.hljs-function,.hljs-keyword,.hljs-selector-tag{color:#be94bb}.hljs-meta,.hljs-section,.hljs-title{color:#81a2be}.hljs-symbol{color:#dbc4d9}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/magula.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/magula.min.css new file mode 100644 index 0000000..e024387 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/magula.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background-color:#f4f4f4;color:#000}.hljs-subst{color:#000}.hljs-addition,.hljs-attribute,.hljs-bullet,.hljs-string,.hljs-symbol,.hljs-template-tag,.hljs-template-variable,.hljs-title,.hljs-variable{color:#050}.hljs-comment,.hljs-quote{color:#777}.hljs-link,.hljs-literal,.hljs-number,.hljs-regexp,.hljs-type{color:#800}.hljs-deletion,.hljs-meta{color:#00e}.hljs-built_in,.hljs-doctag,.hljs-keyword,.hljs-name,.hljs-section,.hljs-selector-tag,.hljs-tag,.hljs-title{font-weight:700;color:navy}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/mono-blue.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/mono-blue.min.css new file mode 100644 index 0000000..fb74d40 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/mono-blue.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#eaeef3;color:#00193a}.hljs-doctag,.hljs-keyword,.hljs-name,.hljs-section,.hljs-selector-tag,.hljs-strong,.hljs-title{font-weight:700}.hljs-comment{color:#738191}.hljs-addition,.hljs-built_in,.hljs-literal,.hljs-name,.hljs-quote,.hljs-section,.hljs-selector-class,.hljs-selector-id,.hljs-string,.hljs-tag,.hljs-title,.hljs-type{color:#0048ab}.hljs-attribute,.hljs-bullet,.hljs-deletion,.hljs-link,.hljs-meta,.hljs-regexp,.hljs-subst,.hljs-symbol,.hljs-template-variable,.hljs-variable{color:#4c81c9}.hljs-emphasis{font-style:italic} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/monokai-sublime.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/monokai-sublime.min.css new file mode 100644 index 0000000..247e2e9 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/monokai-sublime.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#23241f;color:#f8f8f2}.hljs-subst,.hljs-tag{color:#f8f8f2}.hljs-emphasis,.hljs-strong{color:#a8a8a2}.hljs-bullet,.hljs-link,.hljs-literal,.hljs-number,.hljs-quote,.hljs-regexp{color:#ae81ff}.hljs-code,.hljs-section,.hljs-selector-class,.hljs-title{color:#a6e22e}.hljs-strong{font-weight:700}.hljs-emphasis{font-style:italic}.hljs-attr,.hljs-keyword,.hljs-name,.hljs-selector-tag{color:#f92672}.hljs-attribute,.hljs-symbol{color:#66d9ef}.hljs-class .hljs-title,.hljs-params,.hljs-title.class_{color:#f8f8f2}.hljs-addition,.hljs-built_in,.hljs-selector-attr,.hljs-selector-id,.hljs-selector-pseudo,.hljs-string,.hljs-template-variable,.hljs-type,.hljs-variable{color:#e6db74}.hljs-comment,.hljs-deletion,.hljs-meta{color:#75715e} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/monokai.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/monokai.min.css new file mode 100644 index 0000000..d289f63 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/monokai.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#272822;color:#ddd}.hljs-keyword,.hljs-literal,.hljs-name,.hljs-number,.hljs-selector-tag,.hljs-strong,.hljs-tag{color:#f92672}.hljs-code{color:#66d9ef}.hljs-attr,.hljs-attribute,.hljs-link,.hljs-regexp,.hljs-symbol{color:#bf79db}.hljs-addition,.hljs-built_in,.hljs-bullet,.hljs-emphasis,.hljs-section,.hljs-selector-attr,.hljs-selector-pseudo,.hljs-string,.hljs-subst,.hljs-template-tag,.hljs-template-variable,.hljs-title,.hljs-type,.hljs-variable{color:#a6e22e}.hljs-class .hljs-title,.hljs-title.class_{color:#fff}.hljs-comment,.hljs-deletion,.hljs-meta,.hljs-quote{color:#75715e}.hljs-doctag,.hljs-keyword,.hljs-literal,.hljs-section,.hljs-selector-id,.hljs-selector-tag,.hljs-title,.hljs-type{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/night-owl.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/night-owl.min.css new file mode 100644 index 0000000..ed94590 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/night-owl.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#011627;color:#d6deeb}.hljs-keyword{color:#c792ea;font-style:italic}.hljs-built_in{color:#addb67;font-style:italic}.hljs-type{color:#82aaff}.hljs-literal{color:#ff5874}.hljs-number{color:#f78c6c}.hljs-regexp{color:#5ca7e4}.hljs-string{color:#ecc48d}.hljs-subst{color:#d3423e}.hljs-symbol{color:#82aaff}.hljs-class{color:#ffcb8b}.hljs-function{color:#82aaff}.hljs-title{color:#dcdcaa;font-style:italic}.hljs-params{color:#7fdbca}.hljs-comment{color:#637777;font-style:italic}.hljs-doctag{color:#7fdbca}.hljs-meta,.hljs-meta .hljs-keyword{color:#82aaff}.hljs-meta .hljs-string{color:#ecc48d}.hljs-section{color:#82b1ff}.hljs-attr,.hljs-name,.hljs-tag{color:#7fdbca}.hljs-attribute{color:#80cbc4}.hljs-variable{color:#addb67}.hljs-bullet{color:#d9f5dd}.hljs-code{color:#80cbc4}.hljs-emphasis{color:#c792ea;font-style:italic}.hljs-strong{color:#addb67;font-weight:700}.hljs-formula{color:#c792ea}.hljs-link{color:#ff869a}.hljs-quote{color:#697098;font-style:italic}.hljs-selector-tag{color:#ff6363}.hljs-selector-id{color:#fad430}.hljs-selector-class{color:#addb67;font-style:italic}.hljs-selector-attr,.hljs-selector-pseudo{color:#c792ea;font-style:italic}.hljs-template-tag{color:#c792ea}.hljs-template-variable{color:#addb67}.hljs-addition{color:#addb67ff;font-style:italic}.hljs-deletion{color:#ef535090;font-style:italic} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/nnfx-dark.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/nnfx-dark.min.css new file mode 100644 index 0000000..4e6403d --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/nnfx-dark.min.css @@ -0,0 +1,10 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*! + Theme: nnfx dark + Description: a theme inspired by Netscape Navigator/Firefox + Author: (c) 2020-2021 Jim Mason + Maintainer: @RocketMan + License: https://creativecommons.org/licenses/by-sa/4.0 CC BY-SA 4.0 + Updated: 2021-05-17 + + @version 1.1.0 +*/.hljs{background:#333;color:#fff}.language-xml .hljs-meta,.language-xml .hljs-meta-string{font-weight:700;font-style:italic;color:#69f}.hljs-comment,.hljs-quote{font-style:italic;color:#9c6}.hljs-built_in,.hljs-keyword,.hljs-name{color:#a7a}.hljs-attr,.hljs-name{font-weight:700}.hljs-string{font-weight:400}.hljs-code,.hljs-link,.hljs-meta .hljs-string,.hljs-number,.hljs-regexp,.hljs-string{color:#bce}.hljs-bullet,.hljs-symbol,.hljs-template-variable,.hljs-title,.hljs-variable{color:#d40}.hljs-class .hljs-title,.hljs-title.class_,.hljs-type{font-weight:700;color:#96c}.hljs-attr,.hljs-function .hljs-title,.hljs-subst,.hljs-tag,.hljs-title.function_{color:#fff}.hljs-formula{background-color:#eee;font-style:italic}.hljs-addition{background-color:#797}.hljs-deletion{background-color:#c99}.hljs-meta{color:#69f}.hljs-section,.hljs-selector-class,.hljs-selector-id,.hljs-selector-pseudo,.hljs-selector-tag{font-weight:700;color:#69f}.hljs-selector-pseudo{font-style:italic}.hljs-doctag,.hljs-strong{font-weight:700}.hljs-emphasis{font-style:italic} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/nnfx-light.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/nnfx-light.min.css new file mode 100644 index 0000000..469223a --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/nnfx-light.min.css @@ -0,0 +1,10 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*! + Theme: nnfx light + Description: a theme inspired by Netscape Navigator/Firefox + Author: (c) 2020-2021 Jim Mason + Maintainer: @RocketMan + License: https://creativecommons.org/licenses/by-sa/4.0 CC BY-SA 4.0 + Updated: 2021-05-17 + + @version 1.1.0 +*/.hljs{background:#fff;color:#000}.language-xml .hljs-meta,.language-xml .hljs-meta-string{font-weight:700;font-style:italic;color:#48b}.hljs-comment,.hljs-quote{font-style:italic;color:#070}.hljs-built_in,.hljs-keyword,.hljs-name{color:#808}.hljs-attr,.hljs-name{font-weight:700}.hljs-string{font-weight:400}.hljs-code,.hljs-link,.hljs-meta .hljs-string,.hljs-number,.hljs-regexp,.hljs-string{color:#00f}.hljs-bullet,.hljs-symbol,.hljs-template-variable,.hljs-title,.hljs-variable{color:#f40}.hljs-class .hljs-title,.hljs-title.class_,.hljs-type{font-weight:700;color:#639}.hljs-attr,.hljs-function .hljs-title,.hljs-subst,.hljs-tag,.hljs-title.function_{color:#000}.hljs-formula{background-color:#eee;font-style:italic}.hljs-addition{background-color:#beb}.hljs-deletion{background-color:#fbb}.hljs-meta{color:#269}.hljs-section,.hljs-selector-class,.hljs-selector-id,.hljs-selector-pseudo,.hljs-selector-tag{font-weight:700;color:#48b}.hljs-selector-pseudo{font-style:italic}.hljs-doctag,.hljs-strong{font-weight:700}.hljs-emphasis{font-style:italic} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/nord.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/nord.min.css new file mode 100644 index 0000000..efbb0c1 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/nord.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#2e3440}.hljs,.hljs-subst{color:#d8dee9}.hljs-selector-tag{color:#81a1c1}.hljs-selector-id{color:#8fbcbb;font-weight:700}.hljs-selector-attr,.hljs-selector-class{color:#8fbcbb}.hljs-property,.hljs-selector-pseudo{color:#88c0d0}.hljs-addition{background-color:rgba(163,190,140,.5)}.hljs-deletion{background-color:rgba(191,97,106,.5)}.hljs-built_in,.hljs-class,.hljs-type{color:#8fbcbb}.hljs-function,.hljs-function>.hljs-title,.hljs-title.hljs-function{color:#88c0d0}.hljs-keyword,.hljs-literal,.hljs-symbol{color:#81a1c1}.hljs-number{color:#b48ead}.hljs-regexp{color:#ebcb8b}.hljs-string{color:#a3be8c}.hljs-title{color:#8fbcbb}.hljs-params{color:#d8dee9}.hljs-bullet{color:#81a1c1}.hljs-code{color:#8fbcbb}.hljs-emphasis{font-style:italic}.hljs-formula{color:#8fbcbb}.hljs-strong{font-weight:700}.hljs-link:hover{text-decoration:underline}.hljs-comment,.hljs-quote{color:#4c566a}.hljs-doctag{color:#8fbcbb}.hljs-meta,.hljs-meta .hljs-keyword{color:#5e81ac}.hljs-meta .hljs-string{color:#a3be8c}.hljs-attr{color:#8fbcbb}.hljs-attribute{color:#d8dee9}.hljs-name{color:#81a1c1}.hljs-section{color:#88c0d0}.hljs-tag{color:#81a1c1}.hljs-template-variable,.hljs-variable{color:#d8dee9}.hljs-template-tag{color:#5e81ac}.language-abnf .hljs-attribute{color:#88c0d0}.language-abnf .hljs-symbol{color:#ebcb8b}.language-apache .hljs-attribute{color:#88c0d0}.language-apache .hljs-section{color:#81a1c1}.language-arduino .hljs-built_in{color:#88c0d0}.language-aspectj .hljs-meta{color:#d08770}.language-aspectj>.hljs-title{color:#88c0d0}.language-bnf .hljs-attribute{color:#8fbcbb}.language-clojure .hljs-name{color:#88c0d0}.language-clojure .hljs-symbol{color:#ebcb8b}.language-coq .hljs-built_in{color:#88c0d0}.language-cpp .hljs-meta .hljs-string{color:#8fbcbb}.language-css .hljs-built_in{color:#88c0d0}.language-css .hljs-keyword{color:#d08770}.language-diff .hljs-meta,.language-ebnf .hljs-attribute{color:#8fbcbb}.language-glsl .hljs-built_in{color:#88c0d0}.language-groovy .hljs-meta:not(:first-child),.language-haxe .hljs-meta,.language-java .hljs-meta{color:#d08770}.language-ldif .hljs-attribute{color:#8fbcbb}.language-lisp .hljs-name,.language-lua .hljs-built_in,.language-moonscript .hljs-built_in,.language-nginx .hljs-attribute{color:#88c0d0}.language-nginx .hljs-section{color:#5e81ac}.language-pf .hljs-built_in,.language-processing .hljs-built_in{color:#88c0d0}.language-scss .hljs-keyword,.language-stylus .hljs-keyword{color:#81a1c1}.language-swift .hljs-meta{color:#d08770}.language-vim .hljs-built_in{color:#88c0d0;font-style:italic}.language-yaml .hljs-meta{color:#d08770} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/obsidian.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/obsidian.min.css new file mode 100644 index 0000000..c2a0786 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/obsidian.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#e0e2e4;background:#282b2e}.hljs-keyword,.hljs-literal,.hljs-selector-id,.hljs-selector-tag{color:#93c763}.hljs-number{color:#ffcd22}.hljs-attribute{color:#668bb0}.hljs-link,.hljs-regexp{color:#d39745}.hljs-meta{color:#557182}.hljs-addition,.hljs-built_in,.hljs-bullet,.hljs-emphasis,.hljs-name,.hljs-selector-attr,.hljs-selector-pseudo,.hljs-subst,.hljs-tag,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable{color:#8cbbad}.hljs-string,.hljs-symbol{color:#ec7600}.hljs-comment,.hljs-deletion,.hljs-quote{color:#818e96}.hljs-selector-class{color:#a082bd}.hljs-doctag,.hljs-keyword,.hljs-literal,.hljs-name,.hljs-section,.hljs-selector-tag,.hljs-strong,.hljs-title,.hljs-type{font-weight:700}.hljs-class .hljs-title,.hljs-code,.hljs-section,.hljs-title.class_{color:#fff} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/panda-syntax-dark.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/panda-syntax-dark.min.css new file mode 100644 index 0000000..55e26c6 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/panda-syntax-dark.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#e6e6e6;background:#2a2c2d}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}.hljs-link{text-decoration:underline}.hljs-comment,.hljs-quote{color:#bbb;font-style:italic}.hljs-params{color:#bbb}.hljs-attr,.hljs-punctuation{color:#e6e6e6}.hljs-meta,.hljs-name,.hljs-selector-tag{color:#ff4b82}.hljs-char.escape_,.hljs-operator{color:#b084eb}.hljs-deletion,.hljs-keyword{color:#ff75b5}.hljs-regexp,.hljs-selector-attr,.hljs-selector-pseudo,.hljs-variable.language_{color:#ff9ac1}.hljs-code,.hljs-formula,.hljs-property,.hljs-section,.hljs-subst,.hljs-title.function_{color:#45a9f9}.hljs-addition,.hljs-bullet,.hljs-meta .hljs-string,.hljs-selector-class,.hljs-string,.hljs-symbol,.hljs-title.class_,.hljs-title.class_.inherited__{color:#19f9d8}.hljs-attribute,.hljs-built_in,.hljs-doctag,.hljs-link,.hljs-literal,.hljs-meta .hljs-keyword,.hljs-number,.hljs-punctuation,.hljs-selector-id,.hljs-tag,.hljs-template-tag,.hljs-template-variable,.hljs-title,.hljs-type,.hljs-variable{color:#ffb86c} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/panda-syntax-light.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/panda-syntax-light.min.css new file mode 100644 index 0000000..6710dbd --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/panda-syntax-light.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#2a2c2d;background:#e6e6e6}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}.hljs-link{text-decoration:underline}.hljs-comment,.hljs-quote{color:#676b79;font-style:italic}.hljs-params{color:#676b79}.hljs-attr,.hljs-punctuation{color:#2a2c2d}.hljs-char.escape_,.hljs-meta,.hljs-name,.hljs-operator,.hljs-selector-tag{color:#c56200}.hljs-deletion,.hljs-keyword{color:#d92792}.hljs-regexp,.hljs-selector-attr,.hljs-selector-pseudo,.hljs-variable.language_{color:#cc5e91}.hljs-code,.hljs-formula,.hljs-property,.hljs-section,.hljs-subst,.hljs-title.function_{color:#3787c7}.hljs-addition,.hljs-bullet,.hljs-meta .hljs-string,.hljs-selector-class,.hljs-string,.hljs-symbol,.hljs-title.class_,.hljs-title.class_.inherited__{color:#0d7d6c}.hljs-attribute,.hljs-built_in,.hljs-doctag,.hljs-link,.hljs-literal,.hljs-meta .hljs-keyword,.hljs-number,.hljs-selector-id,.hljs-tag,.hljs-template-tag,.hljs-template-variable,.hljs-title,.hljs-type,.hljs-variable{color:#7641bb} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/paraiso-dark.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/paraiso-dark.min.css new file mode 100644 index 0000000..d51dd18 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/paraiso-dark.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#2f1e2e;color:#a39e9b}.hljs-comment,.hljs-quote{color:#8d8687}.hljs-link,.hljs-meta,.hljs-name,.hljs-regexp,.hljs-selector-class,.hljs-selector-id,.hljs-tag,.hljs-template-variable,.hljs-variable{color:#ef6155}.hljs-built_in,.hljs-deletion,.hljs-literal,.hljs-number,.hljs-params,.hljs-type{color:#f99b15}.hljs-attribute,.hljs-section,.hljs-title{color:#fec418}.hljs-addition,.hljs-bullet,.hljs-string,.hljs-symbol{color:#48b685}.hljs-keyword,.hljs-selector-tag{color:#815ba4}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/paraiso-light.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/paraiso-light.min.css new file mode 100644 index 0000000..3a17c3f --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/paraiso-light.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#e7e9db;color:#4f424c}.hljs-comment,.hljs-quote{color:#776e71}.hljs-link,.hljs-meta,.hljs-name,.hljs-regexp,.hljs-selector-class,.hljs-selector-id,.hljs-tag,.hljs-template-variable,.hljs-variable{color:#ef6155}.hljs-built_in,.hljs-deletion,.hljs-literal,.hljs-number,.hljs-params,.hljs-type{color:#f99b15}.hljs-attribute,.hljs-section,.hljs-title{color:#fec418}.hljs-addition,.hljs-bullet,.hljs-string,.hljs-symbol{color:#48b685}.hljs-keyword,.hljs-selector-tag{color:#815ba4}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/pojoaque.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/pojoaque.min.css new file mode 100644 index 0000000..71345a9 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/pojoaque.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#dccf8f;background:url(./pojoaque.jpg) left top #181914}.hljs-comment,.hljs-quote{color:#586e75;font-style:italic}.hljs-addition,.hljs-keyword,.hljs-literal,.hljs-selector-tag{color:#b64926}.hljs-doctag,.hljs-number,.hljs-regexp,.hljs-string{color:#468966}.hljs-built_in,.hljs-name,.hljs-section,.hljs-title{color:#ffb03b}.hljs-class .hljs-title,.hljs-tag,.hljs-template-variable,.hljs-title.class_,.hljs-type,.hljs-variable{color:#b58900}.hljs-attribute{color:#b89859}.hljs-bullet,.hljs-link,.hljs-meta,.hljs-subst,.hljs-symbol{color:#cb4b16}.hljs-deletion{color:#dc322f}.hljs-selector-class,.hljs-selector-id{color:#d3a60c}.hljs-formula{background:#073642}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/purebasic.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/purebasic.min.css new file mode 100644 index 0000000..e026c45 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/purebasic.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#ffffdf}.hljs,.hljs-attr,.hljs-function,.hljs-name,.hljs-number,.hljs-params,.hljs-subst,.hljs-type{color:#000}.hljs-addition,.hljs-comment,.hljs-regexp,.hljs-section,.hljs-selector-pseudo{color:#0aa}.hljs-built_in,.hljs-class,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-selector-class{color:#066;font-weight:700}.hljs-code,.hljs-tag,.hljs-title,.hljs-variable{color:#066}.hljs-selector-attr,.hljs-string{color:#0080ff}.hljs-attribute,.hljs-deletion,.hljs-link,.hljs-symbol{color:#924b72}.hljs-literal,.hljs-meta,.hljs-selector-id{color:#924b72;font-weight:700}.hljs-name,.hljs-strong{font-weight:700}.hljs-emphasis{font-style:italic} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/qtcreator-dark.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/qtcreator-dark.min.css new file mode 100644 index 0000000..976e519 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/qtcreator-dark.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#aaa;background:#000}.hljs-emphasis,.hljs-strong{color:#a8a8a2}.hljs-bullet,.hljs-literal,.hljs-number,.hljs-quote,.hljs-regexp{color:#f5f}.hljs-code .hljs-selector-class{color:#aaf}.hljs-emphasis,.hljs-stronge,.hljs-type{font-style:italic}.hljs-function,.hljs-keyword,.hljs-name,.hljs-section,.hljs-selector-tag,.hljs-symbol{color:#ff5}.hljs-subst,.hljs-tag,.hljs-title{color:#aaa}.hljs-attribute{color:#f55}.hljs-class .hljs-title,.hljs-params,.hljs-title.class_,.hljs-variable{color:#88f}.hljs-addition,.hljs-built_in,.hljs-link,.hljs-selector-attr,.hljs-selector-id,.hljs-selector-pseudo,.hljs-string,.hljs-template-tag,.hljs-template-variable,.hljs-type{color:#f5f}.hljs-comment,.hljs-deletion,.hljs-meta{color:#5ff} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/qtcreator-light.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/qtcreator-light.min.css new file mode 100644 index 0000000..7f1af8c --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/qtcreator-light.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#000;background:#fff}.hljs-emphasis,.hljs-strong{color:#000}.hljs-bullet,.hljs-literal,.hljs-number,.hljs-quote,.hljs-regexp{color:navy}.hljs-code .hljs-selector-class{color:purple}.hljs-emphasis,.hljs-stronge,.hljs-type{font-style:italic}.hljs-function,.hljs-keyword,.hljs-name,.hljs-section,.hljs-selector-tag,.hljs-symbol{color:olive}.hljs-subst,.hljs-tag,.hljs-title{color:#000}.hljs-attribute{color:maroon}.hljs-class .hljs-title,.hljs-params,.hljs-title.class_,.hljs-variable{color:#0055af}.hljs-addition,.hljs-built_in,.hljs-comment,.hljs-deletion,.hljs-link,.hljs-meta,.hljs-selector-attr,.hljs-selector-id,.hljs-selector-pseudo,.hljs-string,.hljs-template-tag,.hljs-template-variable,.hljs-type{color:green} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/rainbow.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/rainbow.min.css new file mode 100644 index 0000000..c8ca25f --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/rainbow.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#474949;color:#d1d9e1}.hljs-comment,.hljs-quote{color:#969896;font-style:italic}.hljs-addition,.hljs-keyword,.hljs-literal,.hljs-selector-tag,.hljs-type{color:#c9c}.hljs-number,.hljs-selector-attr,.hljs-selector-pseudo{color:#f99157}.hljs-doctag,.hljs-regexp,.hljs-string{color:#8abeb7}.hljs-built_in,.hljs-name,.hljs-section,.hljs-title{color:#b5bd68}.hljs-class .hljs-title,.hljs-selector-id,.hljs-template-variable,.hljs-title.class_,.hljs-variable{color:#fc6}.hljs-name,.hljs-section,.hljs-strong{font-weight:700}.hljs-bullet,.hljs-link,.hljs-meta,.hljs-subst,.hljs-symbol{color:#f99157}.hljs-deletion{color:#dc322f}.hljs-formula{background:#eee8d5}.hljs-attr,.hljs-attribute{color:#81a2be}.hljs-emphasis{font-style:italic} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/routeros.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/routeros.min.css new file mode 100644 index 0000000..0378678 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/routeros.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#444;background:#f0f0f0}.hljs-subst{color:#444}.hljs-comment{color:#888}.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-name,.hljs-selector-tag{font-weight:700}.hljs-attribute{color:#0e9a00}.hljs-function{color:#99069a}.hljs-deletion,.hljs-number,.hljs-quote,.hljs-selector-class,.hljs-selector-id,.hljs-string,.hljs-template-tag,.hljs-type{color:#800}.hljs-section,.hljs-title{color:#800;font-weight:700}.hljs-link,.hljs-regexp,.hljs-selector-attr,.hljs-selector-pseudo,.hljs-symbol,.hljs-template-variable,.hljs-variable{color:#bc6060}.hljs-literal{color:#78a960}.hljs-addition,.hljs-built_in,.hljs-bullet,.hljs-code{color:#0c9a9a}.hljs-meta{color:#1f7199}.hljs-meta .hljs-string{color:#4d99bf}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/school-book.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/school-book.min.css new file mode 100644 index 0000000..843f268 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/school-book.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#3e5915;background:#f6f5b2}.hljs-keyword,.hljs-literal,.hljs-selector-tag{color:#059}.hljs-subst{color:#3e5915}.hljs-addition,.hljs-attribute,.hljs-built_in,.hljs-bullet,.hljs-link,.hljs-section,.hljs-string,.hljs-symbol,.hljs-template-tag,.hljs-template-variable,.hljs-title,.hljs-type,.hljs-variable{color:#2c009f}.hljs-comment,.hljs-deletion,.hljs-meta,.hljs-quote{color:#e60415}.hljs-doctag,.hljs-keyword,.hljs-literal,.hljs-name,.hljs-section,.hljs-selector-id,.hljs-selector-tag,.hljs-strong,.hljs-title,.hljs-type{font-weight:700}.hljs-emphasis{font-style:italic} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/shades-of-purple.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/shades-of-purple.min.css new file mode 100644 index 0000000..3dd25b4 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/shades-of-purple.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#2d2b57;color:#e3dfff;font-weight:400}.hljs-subst{color:#e3dfff}.hljs-title{color:#fad000;font-weight:400}.hljs-name{color:#a1feff}.hljs-tag{color:#fff}.hljs-attr{color:#f8d000;font-style:italic}.hljs-built_in,.hljs-keyword,.hljs-section,.hljs-selector-tag{color:#fb9e00}.hljs-addition,.hljs-attribute,.hljs-bullet,.hljs-code,.hljs-deletion,.hljs-quote,.hljs-regexp,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-pseudo,.hljs-string,.hljs-symbol,.hljs-template-tag{color:#4cd213}.hljs-meta,.hljs-meta .hljs-string{color:#fb9e00}.hljs-comment{color:#ac65ff}.hljs-keyword,.hljs-literal,.hljs-name,.hljs-selector-tag,.hljs-strong{font-weight:400}.hljs-literal,.hljs-number{color:#fa658d}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/srcery.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/srcery.min.css new file mode 100644 index 0000000..377d61a --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/srcery.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#1c1b19;color:#fce8c3}.hljs-literal,.hljs-quote,.hljs-subst{color:#fce8c3}.hljs-symbol,.hljs-type{color:#68a8e4}.hljs-deletion,.hljs-keyword{color:#ef2f27}.hljs-attribute,.hljs-function,.hljs-name,.hljs-section,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-selector-pseudo,.hljs-title{color:#fbb829}.hljs-class,.hljs-code,.hljs-property,.hljs-template-variable,.hljs-variable{color:#0aaeb3}.hljs-addition,.hljs-bullet,.hljs-regexp,.hljs-string{color:#98bc37}.hljs-built_in,.hljs-params{color:#ff5c8f}.hljs-selector-tag,.hljs-template-tag{color:#2c78bf}.hljs-comment,.hljs-link,.hljs-meta,.hljs-number{color:#918175}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/stackoverflow-dark.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/stackoverflow-dark.min.css new file mode 100644 index 0000000..33cea55 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/stackoverflow-dark.min.css @@ -0,0 +1,13 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*! + Theme: StackOverflow Dark + Description: Dark theme as used on stackoverflow.com + Author: stackoverflow.com + Maintainer: @Hirse + Website: https://github.com/StackExchange/Stacks + License: MIT + Updated: 2021-05-15 + + Updated for @stackoverflow/stacks v0.64.0 + Code Blocks: /blob/v0.64.0/lib/css/components/_stacks-code-blocks.less + Colors: /blob/v0.64.0/lib/css/exports/_stacks-constants-colors.less +*/.hljs{color:#fff;background:#1c1b1b}.hljs-subst{color:#fff}.hljs-comment{color:#999}.hljs-attr,.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-section,.hljs-selector-tag{color:#88aece}.hljs-attribute{color:#c59bc1}.hljs-name,.hljs-number,.hljs-quote,.hljs-selector-id,.hljs-template-tag,.hljs-type{color:#f08d49}.hljs-selector-class{color:#88aece}.hljs-link,.hljs-regexp,.hljs-selector-attr,.hljs-string,.hljs-symbol,.hljs-template-variable,.hljs-variable{color:#b5bd68}.hljs-meta,.hljs-selector-pseudo{color:#88aece}.hljs-built_in,.hljs-literal,.hljs-title{color:#f08d49}.hljs-bullet,.hljs-code{color:#ccc}.hljs-meta .hljs-string{color:#b5bd68}.hljs-deletion{color:#de7176}.hljs-addition{color:#76c490}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/stackoverflow-light.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/stackoverflow-light.min.css new file mode 100644 index 0000000..c36d63d --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/stackoverflow-light.min.css @@ -0,0 +1,13 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*! + Theme: StackOverflow Light + Description: Light theme as used on stackoverflow.com + Author: stackoverflow.com + Maintainer: @Hirse + Website: https://github.com/StackExchange/Stacks + License: MIT + Updated: 2021-05-15 + + Updated for @stackoverflow/stacks v0.64.0 + Code Blocks: /blob/v0.64.0/lib/css/components/_stacks-code-blocks.less + Colors: /blob/v0.64.0/lib/css/exports/_stacks-constants-colors.less +*/.hljs{color:#2f3337;background:#f6f6f6}.hljs-subst{color:#2f3337}.hljs-comment{color:#656e77}.hljs-attr,.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-section,.hljs-selector-tag{color:#015692}.hljs-attribute{color:#803378}.hljs-name,.hljs-number,.hljs-quote,.hljs-selector-id,.hljs-template-tag,.hljs-type{color:#b75501}.hljs-selector-class{color:#015692}.hljs-link,.hljs-regexp,.hljs-selector-attr,.hljs-string,.hljs-symbol,.hljs-template-variable,.hljs-variable{color:#54790d}.hljs-meta,.hljs-selector-pseudo{color:#015692}.hljs-built_in,.hljs-literal,.hljs-title{color:#b75501}.hljs-bullet,.hljs-code{color:#535a60}.hljs-meta .hljs-string{color:#54790d}.hljs-deletion{color:#c02d2e}.hljs-addition{color:#2f6f44}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/sunburst.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/sunburst.min.css new file mode 100644 index 0000000..9210ae6 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/sunburst.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#000;color:#f8f8f8}.hljs-comment,.hljs-quote{color:#aeaeae;font-style:italic}.hljs-keyword,.hljs-selector-tag,.hljs-type{color:#e28964}.hljs-string{color:#65b042}.hljs-subst{color:#daefa3}.hljs-link,.hljs-regexp{color:#e9c062}.hljs-name,.hljs-section,.hljs-tag,.hljs-title{color:#89bdff}.hljs-class .hljs-title,.hljs-doctag,.hljs-title.class_{text-decoration:underline}.hljs-bullet,.hljs-number,.hljs-symbol{color:#3387cc}.hljs-params,.hljs-template-variable,.hljs-variable{color:#3e87e3}.hljs-attribute{color:#cda869}.hljs-meta{color:#8996a8}.hljs-formula{background-color:#0e2231;color:#f8f8f8;font-style:italic}.hljs-addition{background-color:#253b22;color:#f8f8f8}.hljs-deletion{background-color:#420e09;color:#f8f8f8}.hljs-selector-class{color:#9b703f}.hljs-selector-id{color:#8b98ab}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/tokyo-night-dark.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/tokyo-night-dark.min.css new file mode 100644 index 0000000..dc63ad9 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/tokyo-night-dark.min.css @@ -0,0 +1,8 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*! + Theme: Tokyo-night-Dark + origin: https://github.com/enkia/tokyo-night-vscode-theme + Description: Original highlight.js style + Author: (c) Henri Vandersleyen + License: see project LICENSE + Touched: 2022 +*/.hljs-comment,.hljs-meta{color:#565f89}.hljs-deletion,.hljs-doctag,.hljs-regexp,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-selector-pseudo,.hljs-tag,.hljs-template-tag,.hljs-variable.language_{color:#f7768e}.hljs-link,.hljs-literal,.hljs-number,.hljs-params,.hljs-template-variable,.hljs-type,.hljs-variable{color:#ff9e64}.hljs-attribute,.hljs-built_in{color:#e0af68}.hljs-keyword,.hljs-property,.hljs-subst,.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-title.function_{color:#7dcfff}.hljs-selector-tag{color:#73daca}.hljs-addition,.hljs-bullet,.hljs-quote,.hljs-string,.hljs-symbol{color:#9ece6a}.hljs-code,.hljs-formula,.hljs-section{color:#7aa2f7}.hljs-attr,.hljs-char.escape_,.hljs-keyword,.hljs-name,.hljs-operator{color:#bb9af7}.hljs-punctuation{color:#c0caf5}.hljs{background:#1a1b26;color:#9aa5ce}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/tokyo-night-light.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/tokyo-night-light.min.css new file mode 100644 index 0000000..0096d4d --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/tokyo-night-light.min.css @@ -0,0 +1,8 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*! + Theme: Tokyo-night-light + origin: https://github.com/enkia/tokyo-night-vscode-theme + Description: Original highlight.js style + Author: (c) Henri Vandersleyen + License: see project LICENSE + Touched: 2022 +*/.hljs-comment,.hljs-meta{color:#9699a3}.hljs-deletion,.hljs-doctag,.hljs-regexp,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-selector-pseudo,.hljs-tag,.hljs-template-tag,.hljs-variable.language_{color:#8c4351}.hljs-link,.hljs-literal,.hljs-number,.hljs-params,.hljs-template-variable,.hljs-type,.hljs-variable{color:#965027}.hljs-attribute,.hljs-built_in{color:#8f5e15}.hljs-keyword,.hljs-property,.hljs-subst,.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-title.function_{color:#0f4b6e}.hljs-selector-tag{color:#33635c}.hljs-addition,.hljs-bullet,.hljs-quote,.hljs-string,.hljs-symbol{color:#485e30}.hljs-code,.hljs-formula,.hljs-section{color:#34548a}.hljs-attr,.hljs-char.escape_,.hljs-keyword,.hljs-name,.hljs-operator{color:#5a4a78}.hljs-punctuation{color:#343b58}.hljs{background:#d5d6db;color:#565a6e}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/tomorrow-night-blue.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/tomorrow-night-blue.min.css new file mode 100644 index 0000000..2f71b26 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/tomorrow-night-blue.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs-comment,.hljs-quote{color:#7285b7}.hljs-deletion,.hljs-name,.hljs-regexp,.hljs-selector-class,.hljs-selector-id,.hljs-tag,.hljs-template-variable,.hljs-variable{color:#ff9da4}.hljs-built_in,.hljs-link,.hljs-literal,.hljs-meta,.hljs-number,.hljs-params,.hljs-type{color:#ffc58f}.hljs-attribute{color:#ffeead}.hljs-addition,.hljs-bullet,.hljs-string,.hljs-symbol{color:#d1f1a9}.hljs-section,.hljs-title{color:#bbdaff}.hljs-keyword,.hljs-selector-tag{color:#ebbbff}.hljs{background:#002451;color:#fff}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/tomorrow-night-bright.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/tomorrow-night-bright.min.css new file mode 100644 index 0000000..d335629 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/tomorrow-night-bright.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs-comment,.hljs-quote{color:#969896}.hljs-deletion,.hljs-name,.hljs-regexp,.hljs-selector-class,.hljs-selector-id,.hljs-tag,.hljs-template-variable,.hljs-variable{color:#d54e53}.hljs-built_in,.hljs-link,.hljs-literal,.hljs-meta,.hljs-number,.hljs-params,.hljs-type{color:#e78c45}.hljs-attribute{color:#e7c547}.hljs-addition,.hljs-bullet,.hljs-string,.hljs-symbol{color:#b9ca4a}.hljs-section,.hljs-title{color:#7aa6da}.hljs-keyword,.hljs-selector-tag{color:#c397d8}.hljs{background:#000;color:#eaeaea}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/vs.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/vs.min.css new file mode 100644 index 0000000..fb695c1 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/vs.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#fff;color:#000}.hljs-comment,.hljs-quote,.hljs-variable{color:green}.hljs-built_in,.hljs-keyword,.hljs-name,.hljs-selector-tag,.hljs-tag{color:#00f}.hljs-addition,.hljs-attribute,.hljs-literal,.hljs-section,.hljs-string,.hljs-template-tag,.hljs-template-variable,.hljs-title,.hljs-type{color:#a31515}.hljs-deletion,.hljs-meta,.hljs-selector-attr,.hljs-selector-pseudo{color:#2b91af}.hljs-doctag{color:grey}.hljs-attr{color:red}.hljs-bullet,.hljs-link,.hljs-symbol{color:#00b0e8}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/vs2015.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/vs2015.min.css new file mode 100644 index 0000000..7f6fe11 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/vs2015.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#1e1e1e;color:#dcdcdc}.hljs-keyword,.hljs-literal,.hljs-name,.hljs-symbol{color:#569cd6}.hljs-link{color:#569cd6;text-decoration:underline}.hljs-built_in,.hljs-type{color:#4ec9b0}.hljs-class,.hljs-number{color:#b8d7a3}.hljs-meta .hljs-string,.hljs-string{color:#d69d85}.hljs-regexp,.hljs-template-tag{color:#9a5334}.hljs-formula,.hljs-function,.hljs-params,.hljs-subst,.hljs-title{color:#dcdcdc}.hljs-comment,.hljs-quote{color:#57a64a;font-style:italic}.hljs-doctag{color:#608b4e}.hljs-meta,.hljs-meta .hljs-keyword,.hljs-tag{color:#9b9b9b}.hljs-template-variable,.hljs-variable{color:#bd63c5}.hljs-attr,.hljs-attribute{color:#9cdcfe}.hljs-section{color:gold}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}.hljs-bullet,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-selector-pseudo,.hljs-selector-tag{color:#d7ba7d}.hljs-addition{background-color:#144212;display:inline-block;width:100%}.hljs-deletion{background-color:#600;display:inline-block;width:100%} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/xcode.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/xcode.min.css new file mode 100644 index 0000000..cda4adc --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/xcode.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#fff;color:#000}.xml .hljs-meta{color:silver}.hljs-comment,.hljs-quote{color:#007400}.hljs-attribute,.hljs-keyword,.hljs-literal,.hljs-name,.hljs-selector-tag,.hljs-tag{color:#aa0d91}.hljs-template-variable,.hljs-variable{color:#3f6e74}.hljs-code,.hljs-meta .hljs-string,.hljs-string{color:#c41a16}.hljs-link,.hljs-regexp{color:#0e0eff}.hljs-bullet,.hljs-number,.hljs-symbol,.hljs-title{color:#1c00cf}.hljs-meta,.hljs-section{color:#643820}.hljs-built_in,.hljs-class .hljs-title,.hljs-params,.hljs-title.class_,.hljs-type{color:#5c2699}.hljs-attr{color:#836c28}.hljs-subst{color:#000}.hljs-formula{background-color:#eee;font-style:italic}.hljs-addition{background-color:#baeeba}.hljs-deletion{background-color:#ffc8bd}.hljs-selector-class,.hljs-selector-id{color:#9b703f}.hljs-doctag,.hljs-strong{font-weight:700}.hljs-emphasis{font-style:italic} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/xt256.min.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/xt256.min.css new file mode 100644 index 0000000..ef34f0c --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/code-themes/xt256.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#eaeaea;background:#000}.hljs-subst{color:#eaeaea}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}.hljs-type{color:#eaeaea}.hljs-params{color:#da0000}.hljs-literal,.hljs-name,.hljs-number{color:red;font-weight:bolder}.hljs-comment{color:#969896}.hljs-quote,.hljs-selector-id{color:#0ff}.hljs-template-variable,.hljs-title,.hljs-variable{color:#0ff;font-weight:700}.hljs-keyword,.hljs-selector-class,.hljs-symbol{color:#fff000}.hljs-bullet,.hljs-string{color:#0f0}.hljs-section,.hljs-tag{color:#000fff}.hljs-selector-tag{color:#000fff;font-weight:700}.hljs-attribute,.hljs-built_in,.hljs-link,.hljs-regexp{color:#f0f}.hljs-meta{color:#fff;font-weight:bolder} \ No newline at end of file diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/constants.ts b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/constants.ts new file mode 100644 index 0000000..2edd803 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/constants.ts @@ -0,0 +1,84 @@ +import type { StyleConfig } from "./types.js"; + +export const FONT_FAMILY_MAP: Record = { + sans: `-apple-system-font,BlinkMacSystemFont, Helvetica Neue, PingFang SC, Hiragino Sans GB , Microsoft YaHei UI , Microsoft YaHei ,Arial,sans-serif`, + serif: `Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, 'PingFang SC', Cambria, Cochin, Georgia, Times, 'Times New Roman', serif`, + "serif-cjk": `"Source Han Serif SC", "Noto Serif CJK SC", "Source Han Serif CN", STSong, SimSun, serif`, + mono: `Menlo, Monaco, 'Courier New', monospace`, +}; + +export const FONT_SIZE_OPTIONS = ["14px", "15px", "16px", "17px", "18px"]; + +export const COLOR_PRESETS: Record = { + blue: "#0F4C81", + green: "#009874", + vermilion: "#FA5151", + yellow: "#FECE00", + purple: "#92617E", + sky: "#55C9EA", + rose: "#B76E79", + olive: "#556B2F", + black: "#333333", + gray: "#A9A9A9", + pink: "#FFB7C5", + red: "#A93226", + orange: "#D97757", +}; + +export const CODE_BLOCK_THEMES = [ + "1c-light", "a11y-dark", "a11y-light", "agate", "an-old-hope", + "androidstudio", "arduino-light", "arta", "ascetic", + "atom-one-dark-reasonable", "atom-one-dark", "atom-one-light", + "brown-paper", "codepen-embed", "color-brewer", "dark", "default", + "devibeans", "docco", "far", "felipec", "foundation", + "github-dark-dimmed", "github-dark", "github", "gml", "googlecode", + "gradient-dark", "gradient-light", "grayscale", "hybrid", "idea", + "intellij-light", "ir-black", "isbl-editor-dark", "isbl-editor-light", + "kimbie-dark", "kimbie-light", "lightfair", "lioshi", "magula", + "mono-blue", "monokai-sublime", "monokai", "night-owl", "nnfx-dark", + "nnfx-light", "nord", "obsidian", "panda-syntax-dark", + "panda-syntax-light", "paraiso-dark", "paraiso-light", "pojoaque", + "purebasic", "qtcreator-dark", "qtcreator-light", "rainbow", "routeros", + "school-book", "shades-of-purple", "srcery", "stackoverflow-dark", + "stackoverflow-light", "sunburst", "tokyo-night-dark", "tokyo-night-light", + "tomorrow-night-blue", "tomorrow-night-bright", "vs", "vs2015", "xcode", + "xt256", +]; + +export const DEFAULT_STYLE: StyleConfig = { + primaryColor: "#0F4C81", + fontFamily: FONT_FAMILY_MAP.sans!, + fontSize: "16px", + foreground: "0 0% 3.9%", + blockquoteBackground: "#f7f7f7", + accentColor: "#6B7280", + containerBg: "transparent", +}; + +export const THEME_STYLE_DEFAULTS: Record> = { + default: { + primaryColor: COLOR_PRESETS.blue, + }, + grace: { + primaryColor: COLOR_PRESETS.purple, + }, + simple: { + primaryColor: COLOR_PRESETS.green, + }, + modern: { + primaryColor: COLOR_PRESETS.orange, + accentColor: "#E4B1A0", + containerBg: "rgba(250, 249, 245, 1)", + fontFamily: FONT_FAMILY_MAP.sans, + fontSize: "15px", + blockquoteBackground: "rgba(255, 255, 255, 0.6)", + }, +}; + +export const macCodeSvg = ` + + + + + +`.trim(); diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/content.ts b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/content.ts new file mode 100644 index 0000000..6be2b51 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/content.ts @@ -0,0 +1,105 @@ +import { Lexer } from "marked"; + +export type FrontmatterFields = Record; + +export function parseFrontmatter(content: string): { + frontmatter: FrontmatterFields; + body: string; +} { + const match = content.match(/^\s*---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/); + if (!match) { + return { frontmatter: {}, body: content }; + } + + const frontmatter: FrontmatterFields = {}; + const lines = match[1]!.split("\n"); + for (const line of lines) { + const colonIdx = line.indexOf(":"); + if (colonIdx <= 0) continue; + + const key = line.slice(0, colonIdx).trim(); + const value = line.slice(colonIdx + 1).trim(); + frontmatter[key] = stripWrappingQuotes(value); + } + + return { frontmatter, body: match[2]! }; +} + +export function serializeFrontmatter(frontmatter: FrontmatterFields): string { + const entries = Object.entries(frontmatter); + if (entries.length === 0) return ""; + return `---\n${entries.map(([key, value]) => `${key}: ${value}`).join("\n")}\n---\n`; +} + +export function stripWrappingQuotes(value: string): string { + if (!value) return value; + + const doubleQuoted = value.startsWith('"') && value.endsWith('"'); + const singleQuoted = value.startsWith("'") && value.endsWith("'"); + const cjkDoubleQuoted = value.startsWith("\u201c") && value.endsWith("\u201d"); + const cjkSingleQuoted = value.startsWith("\u2018") && value.endsWith("\u2019"); + + if (doubleQuoted || singleQuoted || cjkDoubleQuoted || cjkSingleQuoted) { + return value.slice(1, -1).trim(); + } + + return value.trim(); +} + +export function toFrontmatterString(value: unknown): string | undefined { + if (typeof value === "string") { + return stripWrappingQuotes(value); + } + if (typeof value === "number" || typeof value === "boolean") { + return String(value); + } + return undefined; +} + +export function pickFirstString( + frontmatter: Record, + keys: string[], +): string | undefined { + for (const key of keys) { + const value = toFrontmatterString(frontmatter[key]); + if (value) return value; + } + return undefined; +} + +export function extractTitleFromMarkdown(markdown: string): string { + const tokens = Lexer.lex(markdown, { gfm: true, breaks: true }); + for (const token of tokens) { + if (token.type !== "heading" || (token.depth !== 1 && token.depth !== 2)) continue; + return stripWrappingQuotes(token.text); + } + return ""; +} + +export function extractSummaryFromBody(body: string, maxLen: number): string { + const lines = body.split("\n"); + + for (const line of lines) { + const trimmed = line.trim(); + if (!trimmed) continue; + if (trimmed.startsWith("#")) continue; + if (trimmed.startsWith("![")) continue; + if (trimmed.startsWith(">")) continue; + if (trimmed.startsWith("-") || trimmed.startsWith("*")) continue; + if (/^\d+\./.test(trimmed)) continue; + if (trimmed.startsWith("```")) continue; + + const cleanText = trimmed + .replace(/\*\*(.+?)\*\*/g, "$1") + .replace(/\*(.+?)\*/g, "$1") + .replace(/\[([^\]]+)\]\([^)]+\)/g, "$1") + .replace(/`([^`]+)`/g, "$1"); + + if (cleanText.length > 20) { + if (cleanText.length <= maxLen) return cleanText; + return `${cleanText.slice(0, maxLen - 3)}...`; + } + } + + return ""; +} diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/document.ts b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/document.ts new file mode 100644 index 0000000..e370740 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/document.ts @@ -0,0 +1,206 @@ +import fs from "node:fs"; +import path from "node:path"; + +import type { ReadTimeResults } from "reading-time"; + +import { + COLOR_PRESETS, + DEFAULT_STYLE, + FONT_FAMILY_MAP, + THEME_STYLE_DEFAULTS, +} from "./constants.js"; +import { + extractSummaryFromBody, + extractTitleFromMarkdown, + pickFirstString, + stripWrappingQuotes, +} from "./content.js"; +import { loadExtendConfig } from "./extend-config.js"; +import { + buildCss, + buildHtmlDocument, + inlineCss, + loadCodeThemeCss, + modifyHtmlStructure, + normalizeInlineCss, + removeFirstHeading, +} from "./html-builder.js"; +import { initRenderer, postProcessHtml, renderMarkdown } from "./renderer.js"; +import { loadThemeCss, normalizeThemeCss } from "./themes.js"; +import type { HtmlDocumentMeta, IOpts, StyleConfig, ThemeName } from "./types.js"; + +export interface RenderMarkdownDocumentOptions { + codeTheme?: string; + countStatus?: boolean; + citeStatus?: boolean; + defaultTitle?: string; + fontFamily?: string; + fontSize?: string; + isMacCodeBlock?: boolean; + isShowLineNumber?: boolean; + keepTitle?: boolean; + legend?: string; + primaryColor?: string; + theme?: ThemeName; + themeMode?: IOpts["themeMode"]; +} + +export interface RenderMarkdownDocumentResult { + contentHtml: string; + html: string; + meta: HtmlDocumentMeta; + readingTime: ReadTimeResults; + style: StyleConfig; + yamlData: Record; +} + +export function resolveColorToken(value?: string): string | undefined { + if (!value) return undefined; + return COLOR_PRESETS[value] ?? value; +} + +export function resolveFontFamilyToken(value?: string): string | undefined { + if (!value) return undefined; + return FONT_FAMILY_MAP[value] ?? value; +} + +export function formatTimestamp(date = new Date()): string { + const pad = (value: number) => String(value).padStart(2, "0"); + return `${date.getFullYear()}${pad(date.getMonth() + 1)}${pad( + date.getDate(), + )}${pad(date.getHours())}${pad(date.getMinutes())}${pad(date.getSeconds())}`; +} + +export function buildMarkdownDocumentMeta( + markdown: string, + yamlData: Record, + defaultTitle = "document", +): HtmlDocumentMeta { + const title = pickFirstString(yamlData, ["title"]) + || extractTitleFromMarkdown(markdown) + || defaultTitle; + const author = pickFirstString(yamlData, ["author"]); + const description = pickFirstString(yamlData, ["description", "summary"]) + || extractSummaryFromBody(markdown, 120); + + return { + title: stripWrappingQuotes(title), + author: author ? stripWrappingQuotes(author) : undefined, + description: description ? stripWrappingQuotes(description) : undefined, + }; +} + +export function resolveMarkdownStyle(options: RenderMarkdownDocumentOptions = {}): StyleConfig { + const theme = options.theme ?? "default"; + const themeDefaults = THEME_STYLE_DEFAULTS[theme] ?? {}; + + return { + ...DEFAULT_STYLE, + ...themeDefaults, + ...(options.primaryColor !== undefined ? { primaryColor: options.primaryColor } : {}), + ...(options.fontFamily !== undefined ? { fontFamily: options.fontFamily } : {}), + ...(options.fontSize !== undefined ? { fontSize: options.fontSize } : {}), + }; +} + +export function resolveRenderOptions( + options: RenderMarkdownDocumentOptions = {}, +): RenderMarkdownDocumentOptions { + const extendConfig = loadExtendConfig(); + + return { + codeTheme: options.codeTheme ?? extendConfig.default_code_theme ?? "github", + countStatus: options.countStatus ?? extendConfig.count ?? false, + citeStatus: options.citeStatus ?? extendConfig.cite ?? false, + defaultTitle: options.defaultTitle, + fontFamily: options.fontFamily ?? resolveFontFamilyToken(extendConfig.default_font_family ?? undefined), + fontSize: options.fontSize ?? extendConfig.default_font_size ?? undefined, + isMacCodeBlock: options.isMacCodeBlock ?? extendConfig.mac_code_block ?? true, + isShowLineNumber: options.isShowLineNumber ?? extendConfig.show_line_number ?? false, + keepTitle: options.keepTitle ?? extendConfig.keep_title ?? false, + legend: options.legend ?? extendConfig.legend ?? "alt", + primaryColor: options.primaryColor ?? resolveColorToken(extendConfig.default_color ?? undefined), + theme: options.theme ?? extendConfig.default_theme ?? "default", + themeMode: options.themeMode, + }; +} + +export async function renderMarkdownDocument( + markdown: string, + options: RenderMarkdownDocumentOptions = {}, +): Promise { + const resolvedOptions = resolveRenderOptions(options); + const theme = resolvedOptions.theme ?? "default"; + const codeTheme = resolvedOptions.codeTheme ?? "github"; + const style = resolveMarkdownStyle(resolvedOptions); + + const { baseCss, themeCss } = loadThemeCss(theme); + const css = normalizeThemeCss(buildCss(baseCss, themeCss, style)); + const codeThemeCss = loadCodeThemeCss(codeTheme); + + const renderer = initRenderer({ + citeStatus: resolvedOptions.citeStatus ?? false, + countStatus: resolvedOptions.countStatus ?? false, + isMacCodeBlock: resolvedOptions.isMacCodeBlock ?? true, + isShowLineNumber: resolvedOptions.isShowLineNumber ?? false, + legend: resolvedOptions.legend ?? "alt", + themeMode: resolvedOptions.themeMode, + }); + + const { yamlData, markdownContent, readingTime } = renderer.parseFrontMatterAndContent(markdown); + const { html: baseHtml, readingTime: readingTimeResult } = renderMarkdown(markdown, renderer); + + let contentHtml = postProcessHtml(baseHtml, readingTimeResult, renderer); + if (!(resolvedOptions.keepTitle ?? false)) { + contentHtml = removeFirstHeading(contentHtml); + } + + const meta = buildMarkdownDocumentMeta( + markdownContent, + yamlData as Record, + resolvedOptions.defaultTitle, + ); + const html = buildHtmlDocument(meta, css, contentHtml, codeThemeCss); + const inlinedHtml = normalizeInlineCss(await inlineCss(html), style); + + return { + contentHtml, + html: modifyHtmlStructure(inlinedHtml), + meta, + readingTime, + style, + yamlData: yamlData as Record, + }; +} + +export async function renderMarkdownFileToHtml( + inputPath: string, + options: RenderMarkdownDocumentOptions = {}, +): Promise { + const markdown = fs.readFileSync(inputPath, "utf-8"); + const outputPath = path.resolve( + path.dirname(inputPath), + `${path.basename(inputPath, path.extname(inputPath))}.html`, + ); + const result = await renderMarkdownDocument(markdown, { + ...options, + defaultTitle: options.defaultTitle ?? path.basename(outputPath, ".html"), + }); + + let backupPath: string | undefined; + if (fs.existsSync(outputPath)) { + backupPath = `${outputPath}.bak-${formatTimestamp()}`; + fs.renameSync(outputPath, backupPath); + } + + fs.writeFileSync(outputPath, result.html, "utf-8"); + + return { + ...result, + backupPath, + outputPath, + }; +} diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/extend-config.ts b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/extend-config.ts new file mode 100644 index 0000000..b4a0018 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/extend-config.ts @@ -0,0 +1,57 @@ +import fs from "node:fs"; +import { homedir } from "node:os"; +import path from "node:path"; +import type { ExtendConfig } from "./types.js"; + +function extractYamlFrontMatter(content: string): string | null { + const match = content.match(/^---\s*\n([\s\S]*?)\n---\s*$/m); + return match ? match[1]! : null; +} + +function parseExtendYaml(yaml: string): Partial { + const config: Partial = {}; + for (const line of yaml.split("\n")) { + const trimmed = line.trim(); + if (!trimmed || trimmed.startsWith("#")) continue; + const colonIdx = trimmed.indexOf(":"); + if (colonIdx < 0) continue; + const key = trimmed.slice(0, colonIdx).trim(); + let value = trimmed.slice(colonIdx + 1).trim().replace(/^['"]|['"]$/g, ""); + if (value === "null" || value === "") continue; + + if (key === "default_theme") config.default_theme = value; + else if (key === "default_color") config.default_color = value; + else if (key === "default_font_family") config.default_font_family = value; + else if (key === "default_font_size") config.default_font_size = value.endsWith("px") ? value : `${value}px`; + else if (key === "default_code_theme") config.default_code_theme = value; + else if (key === "mac_code_block") config.mac_code_block = value === "true"; + else if (key === "show_line_number") config.show_line_number = value === "true"; + else if (key === "cite") config.cite = value === "true"; + else if (key === "count") config.count = value === "true"; + else if (key === "legend") config.legend = value; + else if (key === "keep_title") config.keep_title = value === "true"; + } + return config; +} + +export function loadExtendConfig(): Partial { + const paths = [ + path.join(process.cwd(), ".baoyu-skills", "baoyu-markdown-to-html", "EXTEND.md"), + path.join( + process.env.XDG_CONFIG_HOME || path.join(homedir(), ".config"), + "baoyu-skills", "baoyu-markdown-to-html", "EXTEND.md" + ), + path.join(homedir(), ".baoyu-skills", "baoyu-markdown-to-html", "EXTEND.md"), + ]; + for (const p of paths) { + try { + const content = fs.readFileSync(p, "utf-8"); + const yaml = extractYamlFrontMatter(content); + if (!yaml) continue; + return parseExtendYaml(yaml); + } catch { + continue; + } + } + return {}; +} diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/extensions/alert.ts b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/extensions/alert.ts new file mode 100644 index 0000000..39785c4 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/extensions/alert.ts @@ -0,0 +1,284 @@ +import type { MarkedExtension, Tokens } from 'marked' + +export interface AlertOptions { + className?: string + variants?: AlertVariantItem[] + withoutStyle?: boolean +} + +export interface AlertVariantItem { + type: string + icon: string + title?: string + titleClassName?: string +} + +function ucfirst(str: string) { + return str.slice(0, 1).toUpperCase() + str.slice(1).toLowerCase() +} + +/** + * https://github.com/bent10/marked-extensions/tree/main/packages/alert + * To support theme, we need to modify the source code. + * A [marked](https://marked.js.org/) extension to support [GFM alerts](https://github.com/orgs/community/discussions/16925). + */ +export function markedAlert(options: AlertOptions = {}): MarkedExtension { + const { className = `markdown-alert`, variants = [], withoutStyle = false } = options + const resolvedVariants = resolveVariants(variants) + + // 提取公共的元数据构建逻辑 + function buildMeta(variantType: string, matchedVariant: AlertVariantItem, fromContainer = false) { + return { + className, + variant: variantType, + icon: matchedVariant.icon, + title: matchedVariant.title ?? ucfirst(variantType), + titleClassName: `${className}-title`, + fromContainer, + } + } + + // 提取公共的渲染逻辑 + function renderAlert(token: any) { + const { meta, tokens = [] } = token + // @ts-expect-error marked renderer context has parser property + const text = this.parser.parse(tokens) + // 新主题系统:使用 CSS 选择器而非内联样式 + let tmpl = `
\n` + tmpl += `

` + if (!withoutStyle) { + // 给 SVG 添加 class,通过 CSS 控制颜色 + tmpl += meta.icon.replace( + `\n` + tmpl += text + tmpl += `

\n` + + return tmpl + } + + return { + walkTokens(token) { + if (token.type !== `blockquote`) + return + + const matchedVariant = resolvedVariants.find(({ type }) => + new RegExp(createSyntaxPattern(type), `i`).test(token.text), + ) + + if (matchedVariant) { + const { type: variantType } = matchedVariant + const typeRegexp = new RegExp(createSyntaxPattern(variantType), `i`) + + Object.assign(token, { + type: `alert`, + meta: buildMeta(variantType, matchedVariant), + }) + + const firstLine = token.tokens?.[0] as Tokens.Paragraph + const firstLineText = firstLine.raw?.replace(typeRegexp, ``).trim() + + if (firstLineText) { + const patternToken = firstLine.tokens[0] as Tokens.Text + + Object.assign(patternToken, { + raw: patternToken.raw.replace(typeRegexp, ``), + text: patternToken.text.replace(typeRegexp, ``), + }) + + if (firstLine.tokens[1]?.type === `br`) { + firstLine.tokens.splice(1, 1) + } + } + else { + token.tokens?.shift() + } + } + }, + extensions: [ + { + name: `alert`, + level: `block`, + renderer: renderAlert, + }, + { + name: `alertContainer`, + level: `block`, + start(src) { + return src.match(/^:::/)?.index + }, + tokenizer(src, _tokens) { + // eslint-disable-next-line regexp/no-super-linear-backtracking + const match = /^:::\s*(\w+)\s*\n([\s\S]*?)\n:::/.exec(src) + + if (match) { + const [raw, variant, content] = match + const matchedVariant = resolvedVariants.find(v => v.type === variant) + if (!matchedVariant) + return + + return { + type: `alert`, + raw, + text: content.trim(), + tokens: this.lexer.blockTokens(content.trim()), + meta: buildMeta(variant, matchedVariant, true), + } + } + }, + renderer: renderAlert, + }, + ], + } +} + +/** + * The default configuration for alert variants. + */ +const defaultAlertVariant: AlertVariantItem[] = [ + { + type: `note`, + icon: ``, + }, + { + type: `info`, + icon: ``, + }, + { + type: `tip`, + icon: ``, + }, + { + type: `important`, + icon: ``, + }, + { + type: `warning`, + icon: ``, + }, + { + type: `caution`, + icon: ``, + }, + // Obsidian-style callouts + { + type: `abstract`, + title: `Abstract`, + icon: ``, + }, + { + type: `summary`, + title: `Summary`, + icon: ``, + }, + { + type: `tldr`, + title: `TL;DR`, + icon: ``, + }, + { + type: `todo`, + title: `Todo`, + icon: ``, + }, + { + type: `success`, + title: `Success`, + icon: ``, + }, + { + type: `done`, + title: `Done`, + icon: ``, + }, + { + type: `question`, + title: `Question`, + icon: ``, + }, + { + type: `help`, + title: `Help`, + icon: ``, + }, + { + type: `faq`, + title: `FAQ`, + icon: ``, + }, + { + type: `failure`, + title: `Failure`, + icon: ``, + }, + { + type: `fail`, + title: `Fail`, + icon: ``, + }, + { + type: `missing`, + title: `Missing`, + icon: ``, + }, + { + type: `danger`, + title: `Danger`, + icon: ``, + }, + { + type: `error`, + title: `Error`, + icon: ``, + }, + { + type: `bug`, + title: `Bug`, + icon: ``, + }, + { + type: `example`, + title: `Example`, + icon: ``, + }, + { + type: `quote`, + title: `Quote`, + icon: ``, + }, + { + type: `cite`, + title: `Cite`, + icon: ``, + }, +] + +/** + * Resolves the variants configuration, combining the provided variants with + * the default variants. + */ +export function resolveVariants(variants: AlertVariantItem[]) { + if (!variants.length) + return defaultAlertVariant + + return Object.values( + [...defaultAlertVariant, ...variants].reduce( + (map, item) => { + map[item.type] = item + return map + }, + {} as { [key: string]: AlertVariantItem }, + ), + ) +} + +/** + * Returns regex pattern to match alert syntax. + */ +export function createSyntaxPattern(type: string) { + return `^(?:\\[!${type}])\\s*?\n*` +} diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/extensions/footnotes.ts b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/extensions/footnotes.ts new file mode 100644 index 0000000..5660b64 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/extensions/footnotes.ts @@ -0,0 +1,89 @@ +import type { MarkedExtension, Tokens } from 'marked' +/** + * A marked extension to support footnotes syntax. + * Syntax: + * This is a footnote reference[^1][^2]. + * + * [^1]: ..... + * [^2]: ..... + */ + +interface MapContent { + index: number + text: string +} +const fnMap = new Map() + +export function markedFootnotes(): MarkedExtension { + return { + extensions: [ + { + name: `footnoteDef`, + level: `block`, + start(src: string) { + fnMap.clear() + return src.match(/^\[\^/)?.index + }, + tokenizer(src: string) { + const match = src.match(/^\[\^(.*)\]:(.*)/) + if (match) { + const [raw, fnId, text] = match + const index = fnMap.size + 1 + fnMap.set(fnId, { index, text }) + return { + type: `footnoteDef`, + raw, + fnId, + index, + text, + } + } + return undefined + }, + renderer(token: Tokens.Generic) { + const { index, text, fnId } = token + const fnInner = ` + ${index}. + ${text} + \u21A9\uFE0E +
` + if (index === 1) { + return ` +

${fnInner}` + } + if (index === fnMap.size) { + return `${fnInner}

` + } + return fnInner + }, + }, + { + name: `footnoteRef`, + level: `inline`, + start(src: string) { + return src.match(/\[\^/)?.index + }, + tokenizer(src: string) { + const match = src.match(/^\[\^(.*?)\]/) + if (match) { + const [raw, fnId] = match + if (fnMap.has(fnId)) { + return { + type: `footnoteRef`, + raw, + fnId, + } + } + } + }, + renderer(token: Tokens.Generic) { + const { fnId } = token + const { index } = fnMap.get(fnId) as MapContent + return ` + \[${index}\] + ` + }, + }, + ], + } +} diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/extensions/index.ts b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/extensions/index.ts new file mode 100644 index 0000000..dcf6c21 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/extensions/index.ts @@ -0,0 +1,10 @@ +// Markdown 扩展导出 +export * from './alert.js' +export * from './footnotes.js' +export * from './infographic.js' +export * from './katex.js' +export * from './markup.js' +export * from './plantuml.js' +export * from './ruby.js' +export * from './slider.js' +export * from './toc.js' diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/extensions/infographic.ts b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/extensions/infographic.ts new file mode 100644 index 0000000..47feedf --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/extensions/infographic.ts @@ -0,0 +1,119 @@ +import type { MarkedExtension } from 'marked' + +interface InfographicOptions { + themeMode?: 'dark' | 'light' +} + +async function renderInfographic(containerId: string, code: string, options?: InfographicOptions) { + if (typeof window === 'undefined') + return + + try { + const { Infographic, setDefaultFont, setFontExtendFactor, exportToSVG } = await import('@antv/infographic') + + setFontExtendFactor(1.1) + setDefaultFont('-apple-system-font, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif') + + const findContainer = (retries = 5, delay = 100) => { + const container = document.getElementById(containerId) + if (container) { + const isDark = options?.themeMode === 'dark' + + // 从 CSS 变量中读取主题颜色 + const root = document.documentElement + const computedStyle = getComputedStyle(root) + const primaryColor = computedStyle.getPropertyValue('--md-primary-color').trim() + const backgroundColor = computedStyle.getPropertyValue('--background').trim() + + // 转换 HSL 格式 + const toHSLString = (variant: string) => { + const vars = variant.split(' ') + if (vars.length === 3) + return `hsl(${vars.join(', ')})` + if (vars.length === 4) + return `hsla(${vars.join(', ')})` + return '' + } + + const instance = new Infographic({ + container, + svg: { + style: { + width: '100%', + height: '100%', + background: isDark ? '#000' : 'transparent', + }, + background: false, + }, + theme: isDark ? 'dark' : 'default', + themeConfig: { + colorPrimary: primaryColor || undefined, + colorBg: toHSLString(backgroundColor) || undefined, + }, + }) + + instance.on('loaded', ({ node }) => { + exportToSVG(node, { removeIds: true }).then((svg) => { + container.replaceChildren(svg) + }) + }) + + instance.render(code) + + return + } + + if (retries > 0) { + setTimeout(() => findContainer(retries - 1, delay), delay) + } + } + + findContainer() + } + catch (error) { + console.error('Failed to render Infographic:', error) + const container = document.getElementById(containerId) + if (container) { + container.innerHTML = `
Infographic 渲染失败: ${error instanceof Error ? error.message : String(error)}
` + } + } +} + +export function markedInfographic(options?: InfographicOptions): MarkedExtension { + const className = 'infographic-diagram' + + return { + extensions: [ + { + name: 'infographic', + level: 'block', + start(src: string) { + return src.match(/^```infographic/m)?.index + }, + tokenizer(src: string) { + const match = /^```infographic\r?\n([\s\S]*?)\r?\n```/.exec(src) + if (match) { + return { + type: 'infographic', + raw: match[0], + text: match[1].trim(), + } + } + }, + renderer(token: any) { + const id = `infographic-${Math.random().toString(36).slice(2, 11)}` + const code = token.text + + renderInfographic(id, code, options) + + return `
正在加载 Infographic...
` + }, + }, + ], + walkTokens(token: any) { + if (token.type === 'code' && token.lang === 'infographic') { + token.type = 'infographic' + } + }, + } +} diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/extensions/katex.ts b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/extensions/katex.ts new file mode 100644 index 0000000..be62590 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/extensions/katex.ts @@ -0,0 +1,162 @@ +import type { MarkedExtension } from 'marked' + +export interface MarkedKatexOptions { + nonStandard?: boolean +} + +const inlineRule = /^(\${1,2})(?!\$)((?:\\.|[^\\\n])*?(?:\\.|[^\\\n$]))\1(?=[\s?!.,:?!。,:]|$)/ +const inlineRuleNonStandard = /^(\${1,2})(?!\$)((?:\\.|[^\\\n])*?(?:\\.|[^\\\n$]))\1/ // Non-standard, even if there are no spaces before and after $ or $$, try to parse + +const blockRule = /^\s{0,3}(\${1,2})[ \t]*\n([\s\S]+?)\n\s{0,3}\1[ \t]*(?:\n|$)/ + +// LaTeX style rules for \( ... \) and \[ ... \] +const inlineLatexRule = /^\\\(([^\\]*(?:\\.[^\\]*)*?)\\\)/ +const blockLatexRule = /^\\\[([^\\]*(?:\\.[^\\]*)*?)\\\]/ + +function createRenderer(display: boolean, withStyle: boolean = true) { + return (token: any) => { + // @ts-expect-error MathJax is a global variable + window.MathJax.texReset() + // @ts-expect-error MathJax is a global variable + const mjxContainer = window.MathJax.tex2svg(token.text, { display }) + const svg = mjxContainer.firstChild + const width = svg.style[`min-width`] || svg.getAttribute(`width`) + svg.removeAttribute(`width`) + + // 行内公式对齐 https://groups.google.com/g/mathjax-users/c/zThKffrrCvE?pli=1 + // 直接覆盖 style 会覆盖 MathJax 的样式,需要手动设置 + // svg.style = `max-width: 300vw !important; display: initial; flex-shrink: 0;` + + if (withStyle) { + svg.style.display = `initial` + svg.style.setProperty(`max-width`, `300vw`, `important`) + svg.style.flexShrink = `0` + svg.style.width = width + } + + if (!display) { + // 新主题系统:使用 class 而非内联样式 + return `${svg.outerHTML}` + } + + return `
${svg.outerHTML}
` + } +} + +function inlineKatex(options: MarkedKatexOptions | undefined, renderer: any) { + const nonStandard = options && options.nonStandard + const ruleReg = nonStandard ? inlineRuleNonStandard : inlineRule + return { + name: `inlineKatex`, + level: `inline`, + start(src: string) { + let index + let indexSrc = src + + while (indexSrc) { + index = indexSrc.indexOf(`$`) + if (index === -1) { + return + } + const f = nonStandard ? index > -1 : index === 0 || indexSrc.charAt(index - 1) === ` ` + if (f) { + const possibleKatex = indexSrc.substring(index) + + if (possibleKatex.match(ruleReg)) { + return index + } + } + + indexSrc = indexSrc.substring(index + 1).replace(/^\$+/, ``) + } + }, + tokenizer(src: string) { + const match = src.match(ruleReg) + if (match) { + return { + type: `inlineKatex`, + raw: match[0], + text: match[2].trim(), + displayMode: match[1].length === 2, + } + } + }, + renderer, + } +} + +function blockKatex(_options: MarkedKatexOptions | undefined, renderer: any) { + return { + name: `blockKatex`, + level: `block`, + tokenizer(src: string) { + const match = src.match(blockRule) + if (match) { + return { + type: `blockKatex`, + raw: match[0], + text: match[2].trim(), + displayMode: match[1].length === 2, + } + } + }, + renderer, + } +} + +function inlineLatexKatex(_options: MarkedKatexOptions | undefined, renderer: any) { + return { + name: `inlineLatexKatex`, + level: `inline`, + start(src: string) { + const index = src.indexOf(`\\(`) + return index !== -1 ? index : undefined + }, + tokenizer(src: string) { + const match = src.match(inlineLatexRule) + if (match) { + return { + type: `inlineLatexKatex`, + raw: match[0], + text: match[1].trim(), + displayMode: false, + } + } + }, + renderer, + } +} + +function blockLatexKatex(_options: MarkedKatexOptions | undefined, renderer: any) { + return { + name: `blockLatexKatex`, + level: `block`, + start(src: string) { + const index = src.indexOf(`\\[`) + return index !== -1 ? index : undefined + }, + tokenizer(src: string) { + const match = src.match(blockLatexRule) + if (match) { + return { + type: `blockLatexKatex`, + raw: match[0], + text: match[1].trim(), + displayMode: true, + } + } + }, + renderer, + } +} + +export function MDKatex(options: MarkedKatexOptions | undefined, withStyle: boolean = true): MarkedExtension { + return { + extensions: [ + inlineKatex(options, createRenderer(false, withStyle)), + blockKatex(options, createRenderer(true, withStyle)), + inlineLatexKatex(options, createRenderer(false, withStyle)), + blockLatexKatex(options, createRenderer(true, withStyle)), + ], + } +} diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/extensions/markup.ts b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/extensions/markup.ts new file mode 100644 index 0000000..0aeac9b --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/extensions/markup.ts @@ -0,0 +1,87 @@ +import type { MarkedExtension } from 'marked' + +/** + * 扩展标记语法: + * - 高亮: ==文本== + * - 下划线: ++文本++ + * - 波浪线: ~文本~ + */ +export function markedMarkup(): MarkedExtension { + return { + extensions: [ + // 高亮语法 ==文本== + { + name: `markup_highlight`, + level: `inline`, + start(src: string) { + return src.match(/==(?!=)/)?.index + }, + tokenizer(src: string) { + const rule = /^==((?:[^=]|=(?!=))+)==/ + const match = rule.exec(src) + if (match) { + return { + type: `markup_highlight`, + raw: match[0], + text: match[1], + } + } + }, + renderer(token: any) { + // 新主题系统:使用 class 而非内联样式 + return `${token.text}` + }, + }, + + // 下划线语法 ++文本++ + { + name: `markup_underline`, + level: `inline`, + start(src: string) { + return src.match(/\+\+(?!\+)/)?.index + }, + tokenizer(src: string) { + const rule = /^\+\+((?:[^+]|\+(?!\+))+)\+\+/ + const match = rule.exec(src) + if (match) { + return { + type: `markup_underline`, + raw: match[0], + text: match[1], + } + } + }, + renderer(token: any) { + // 新主题系统:使用 class 而非内联样式 + return `${token.text}` + }, + }, + + // 波浪线语法 ~文本~ + { + name: `markup_wavyline`, + level: `inline`, + start(src: string) { + // 查找单个 ~ 但不是连续的 ~~ + return src.match(/~(?!~)/)?.index + }, + tokenizer(src: string) { + // 匹配 ~文本~ 但确保不是 ~~文本~~ + const rule = /^~([^~\n]+)~(?!~)/ + const match = rule.exec(src) + if (match) { + return { + type: `markup_wavyline`, + raw: match[0], + text: match[1], + } + } + }, + renderer(token: any) { + // 新主题系统:使用 class 而非内联样式 + return `${token.text}` + }, + }, + ], + } +} diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/extensions/plantuml.ts b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/extensions/plantuml.ts new file mode 100644 index 0000000..6b402f3 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/extensions/plantuml.ts @@ -0,0 +1,289 @@ +import type { MarkedExtension, Tokens } from 'marked' +import { deflateSync } from 'fflate' + +export interface PlantUMLOptions { + /** + * PlantUML 服务器地址 + * @default 'https://www.plantuml.com/plantuml' + */ + serverUrl?: string + /** + * 渲染格式 + * @default 'svg' + */ + format?: `svg` | `png` + /** + * CSS 类名 + * @default 'plantuml-diagram' + */ + className?: string + /** + * 是否内嵌SVG内容(用于微信公众号等不支持外链图片的环境) + * @default false + */ + inlineSvg?: boolean + /** + * 自定义样式 + */ + styles?: { + container?: Record + } +} + +/** + * PlantUML 专用的 6-bit 编码函数 + * 基于官方文档 https://plantuml.com/text-encoding + */ +function encode6bit(b: number): string { + if (b < 10) { + return String.fromCharCode(48 + b) + } + b -= 10 + if (b < 26) { + return String.fromCharCode(65 + b) + } + b -= 26 + if (b < 26) { + return String.fromCharCode(97 + b) + } + b -= 26 + if (b === 0) { + return `-` + } + if (b === 1) { + return `_` + } + return `?` +} + +/** + * 将 3 个字节附加到编码字符串中 + * 基于官方文档 https://plantuml.com/text-encoding + */ +function append3bytes(b1: number, b2: number, b3: number): string { + const c1 = b1 >> 2 + const c2 = ((b1 & 0x3) << 4) | (b2 >> 4) + const c3 = ((b2 & 0xF) << 2) | (b3 >> 6) + const c4 = b3 & 0x3F + let r = `` + r += encode6bit(c1 & 0x3F) + r += encode6bit(c2 & 0x3F) + r += encode6bit(c3 & 0x3F) + r += encode6bit(c4 & 0x3F) + return r +} + +/** + * PlantUML 专用的 base64 编码函数 + * 基于官方文档 https://plantuml.com/text-encoding + */ +function encode64(data: string): string { + let r = `` + for (let i = 0; i < data.length; i += 3) { + if (i + 2 === data.length) { + r += append3bytes(data.charCodeAt(i), data.charCodeAt(i + 1), 0) + } + else if (i + 1 === data.length) { + r += append3bytes(data.charCodeAt(i), 0, 0) + } + else { + r += append3bytes(data.charCodeAt(i), data.charCodeAt(i + 1), data.charCodeAt(i + 2)) + } + } + return r +} + +/** + * 使用 fflate 库进行 Deflate 压缩 + * 按照官方规范进行压缩 + */ +function performDeflate(input: string): string { + try { + // 将字符串转换为字节数组 + const inputBytes = new TextEncoder().encode(input) + + // 使用 fflate 进行 deflate 压缩(最高压缩级别 9) + const compressed = deflateSync(inputBytes, { level: 9 }) + + // 将压缩后的字节数组转换为二进制字符串 + return String.fromCharCode(...compressed) + } + catch (error) { + console.warn(`Deflate compression failed:`, error) + // 如果压缩失败,返回原始输入 + return input + } +} + +/** + * 编码 PlantUML 代码为服务器可识别的格式 + * 按照官方规范:UTF-8 编码 -> Deflate 压缩 -> PlantUML Base64 编码 + */ +function encodePlantUML(plantumlCode: string): string { + try { + // 步骤 1 & 2: UTF-8 编码 + Deflate 压缩 + const deflated = performDeflate(plantumlCode) + + // 步骤 3: PlantUML 专用的 base64 编码 + return encode64(deflated) + } + catch (error) { + // 如果编码失败,回退到简单方案 + console.warn(`PlantUML encoding failed, using fallback:`, error) + const utf8Bytes = new TextEncoder().encode(plantumlCode) + const base64 = btoa(String.fromCharCode(...utf8Bytes)) + return `~1${base64.replace(/\+/g, `-`).replace(/\//g, `_`).replace(/=/g, ``)}` + } +} + +/** + * 生成 PlantUML 图片 URL + */ +function generatePlantUMLUrl(code: string, options: Required): string { + const encoded = encodePlantUML(code) + const formatPath = options.format === `svg` ? `svg` : `png` + return `${options.serverUrl}/${formatPath}/${encoded}` +} + +/** + * 渲染 PlantUML 图表 + */ +function renderPlantUMLDiagram(token: Tokens.Code, options: Required): string { + const { text: code } = token + + // 检查代码是否包含 PlantUML 标记 + const finalCode = (!code.trim().includes(`@start`) || !code.trim().includes(`@end`)) + ? `@startuml\n${code.trim()}\n@enduml` + : code + + const imageUrl = generatePlantUMLUrl(finalCode, options) + + // 如果启用了内嵌SVG且格式是SVG + if (options.inlineSvg && options.format === `svg`) { + // 由于marked是同步的,我们需要返回一个占位符,然后异步替换 + const placeholder = `plantuml-placeholder-${Math.random().toString(36).slice(2, 11)}` + + // 异步获取SVG内容并替换 + fetchSvgContent(imageUrl).then((svgContent) => { + const placeholderElement = document.querySelector(`[data-placeholder="${placeholder}"]`) + if (placeholderElement) { + placeholderElement.outerHTML = createPlantUMLHTML(imageUrl, options, svgContent) + } + }) + + const containerStyles = options.styles.container + ? Object.entries(options.styles.container) + .map(([key, value]) => `${key.replace(/([A-Z])/g, `-$1`).toLowerCase()}: ${value}`) + .join(`; `) + : `` + + return `
+
正在加载PlantUML图表...
+
` + } + + return createPlantUMLHTML(imageUrl, options) +} + +/** + * 获取SVG内容 + */ +async function fetchSvgContent(svgUrl: string): Promise { + try { + const response = await fetch(svgUrl) + if (!response.ok) { + throw new Error(`HTTP ${response.status}`) + } + const svgContent = await response.text() + // 移除SVG根元素的固定尺寸,使其响应式 + return svgContent + // 移除width和height属性 + .replace(/(]*)\swidth="[^"]*"/g, `$1`) + .replace(/(]*)\sheight="[^"]*"/g, `$1`) + // 移除style中的width和height + .replace(/(]*style="[^"]*?)width:[^;]*;?/g, `$1`) + .replace(/(]*style="[^"]*?)height:[^;]*;?/g, `$1`) + } + catch (error) { + console.warn(`Failed to fetch SVG content from ${svgUrl}:`, error) + return `
PlantUML图表加载失败
` + } +} + +/** + * 创建 PlantUML HTML 元素 + */ +function createPlantUMLHTML(imageUrl: string, options: Required, svgContent?: string): string { + const containerStyles = options.styles.container + ? Object.entries(options.styles.container) + .map(([key, value]) => `${key.replace(/([A-Z])/g, `-$1`).toLowerCase()}: ${value}`) + .join(`; `) + : `` + + // 如果有SVG内容,直接嵌入 + if (svgContent) { + return `
+ ${svgContent} +
` + } + + // 否则使用图片链接 + return `
+ PlantUML Diagram +
` +} + +/** + * PlantUML marked 扩展 + */ +export function markedPlantUML(options: PlantUMLOptions = {}): MarkedExtension { + const resolvedOptions: Required = { + serverUrl: options.serverUrl || `https://www.plantuml.com/plantuml`, + format: options.format || `svg`, + className: options.className || `plantuml-diagram`, + inlineSvg: options.inlineSvg || false, + styles: { + container: { + textAlign: `center`, + margin: `16px 8px`, + overflowX: `auto`, + ...options.styles?.container, + }, + }, + } + + return { + extensions: [ + { + name: `plantuml`, + level: `block`, + start(src: string) { + // 匹配 ```plantuml 代码块 + return src.match(/^```plantuml/m)?.index + }, + tokenizer(src: string) { + // 匹配完整的 plantuml 代码块 + const match = /^```plantuml\r?\n([\s\S]*?)\r?\n```/.exec(src) + + if (match) { + const [raw, code] = match + return { + type: `plantuml`, + raw, + text: code.trim(), + } + } + }, + renderer(token: any) { + return renderPlantUMLDiagram(token, resolvedOptions) + }, + }, + ], + walkTokens(token: any) { + // 处理现有的代码块,如果语言是 plantuml 就转换类型 + if (token.type === `code` && token.lang === `plantuml`) { + token.type = `plantuml` + } + }, + } +} diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/extensions/ruby.ts b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/extensions/ruby.ts new file mode 100644 index 0000000..a064b0a --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/extensions/ruby.ts @@ -0,0 +1,125 @@ +import type { MarkedExtension } from 'marked' + +/** + * 注音/拼音标注扩展 + * https://talk.commonmark.org/t/proper-ruby-text-rb-syntax-support-in-markdown/2279 + * https://www.w3.org/TR/ruby/ + * + * 支持的格式: + * 1. [文字]{注音} + * 2. [文字]^(注音) + * + * 分隔符: + * - `・` (中点) + * - `.` (全角句点) + * - `。` (中文句号) + * - `-` (英文减号) + */ +export function markedRuby(): MarkedExtension { + return { + extensions: [ + { + name: `ruby`, + level: `inline`, + start(src: string) { + // 匹配以 [ 开头的格式 + return src.match(/\[/)?.index + }, + tokenizer(src: string) { + // 1. [文字]{注音} + const rule1 = /^\[([^\]]+)\]\{([^}]+)\}/ + let match = rule1.exec(src) + if (match) { + return { + type: `ruby`, + raw: match[0], + text: match[1].trim(), + ruby: match[2].trim(), + format: `basic`, + } + } + + // 2. [文字]^(注音) + const rule2 = /^\[([^\]]+)\]\^\(([^)]+)\)/ + match = rule2.exec(src) + if (match) { + return { + type: `ruby`, + raw: match[0], + text: match[1].trim(), + ruby: match[2].trim(), + format: `basic-hat`, + } + } + + return undefined + }, + renderer(token: any) { + const { text, ruby, format } = token + + // 检查是否有分隔符 + const separatorRegex = /[・.。-]/g + const hasSeparators = separatorRegex.test(ruby) + + if (hasSeparators) { + // 分割注音部分 + const rubyParts = ruby.split(separatorRegex).filter((part: string) => part.trim() !== ``) + + const textChars = text.split(``) + const result = [] + + if (textChars.length >= rubyParts.length) { + // 文字字符数量 >= 注音部分数量 + // 按注音部分数量分割文字 + let currentIndex = 0 + + for (let i = 0; i < rubyParts.length; i++) { + const rubyPart = rubyParts[i] + const remainingChars = textChars.length - currentIndex + const remainingParts = rubyParts.length - i + + // 计算当前部分应该包含多少个字符,默认为 1 + let charCount = 1 + if (remainingParts === 1) { + // 最后一个部分,包含所有剩余字符 + charCount = remainingChars + } + + // 提取当前部分的文字 + const currentText = textChars.slice(currentIndex, currentIndex + charCount).join(``) + + result.push(`${currentText}(${rubyPart})`) + + currentIndex += charCount + } + + // 处理剩余的字符 + if (currentIndex < textChars.length) { + result.push(textChars.slice(currentIndex).join(``)) + } + } + else { + // 文字字符数量 < 注音部分数量 + // 每个字符对应一个注音部分,多余的注音被忽略 + for (let i = 0; i < textChars.length; i++) { + const char = textChars[i] + const rubyPart = rubyParts[i] || `` + + if (rubyPart) { + result.push(`${char}(${rubyPart})`) + } + else { + result.push(char) + } + } + } + + return result.join(``) + } + + return `${text}(${ruby})` + }, + }, + ], + } +} diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/extensions/slider.ts b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/extensions/slider.ts new file mode 100644 index 0000000..f1f1a10 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/extensions/slider.ts @@ -0,0 +1,73 @@ +import type { MarkedExtension, Tokens } from 'marked' + +/** + * A marked extension to support horizontal sliding images. + * Syntax: + */ +export function markedSlider(): MarkedExtension { + return { + extensions: [ + { + name: `horizontalSlider`, + level: `block`, + start(src: string) { + return src.match(/^/ + const match = src.match(rule) + if (match) { + return { + type: `horizontalSlider`, + raw: match[0], + text: match[1], + } + } + return undefined + }, + renderer(token: Tokens.Generic) { + const { text } = token + const imageMatches = text.match(/!\[(.*?)\]\((.*?)\)/g) || [] + + if (imageMatches.length === 0) { + return `` + } + + const images = imageMatches.map((img: string) => { + const altMatch = img.match(/!\[(.*?)\]/) || [] + const srcMatch = img.match(/\]\((.*?)\)/) || [] + const alt = altMatch[1] || `` + const src = srcMatch[1] || `` + + // 新主题系统:不再需要内联样式 + return { src, alt } + }) + + // 使用微信公众号兼容的滑动容器布局 + // 使用微信支持的section标签和特殊样式组合 + + return ` +
+
+
+
+
+ +
+ ${images.map((img: { src: string, alt: string }, _index: number) => `
+ ${img.alt} +

${img.alt}

+
`).join(``)} +
+
+
+
+
+

<<< 左右滑动看更多 >>>

+
+ ` + }, + }, + ], + } +} diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/extensions/toc.ts b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/extensions/toc.ts new file mode 100644 index 0000000..85e44ff --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/extensions/toc.ts @@ -0,0 +1,74 @@ +import type { MarkedExtension } from 'marked' + +/** + * marked 插件:支持 [TOC] 语法,自动生成嵌套目录 + */ +export function markedToc(): MarkedExtension { + let headings: { text: string, depth: number, index: number }[] = [] + + let firstToken = true + + return { + walkTokens(token) { + if (firstToken) { + headings = [] + firstToken = false + } + if (token.type === `heading`) { + const text = token.text || `` + const depth = token.depth || 1 + const index = headings.length + headings.push({ text, depth, index }) + } + }, + extensions: [ + { + name: `toc`, + level: `block`, + start(src) { + // 只匹配独立一行的 [TOC],避免误伤 + const match = src.match(/^\s*\[TOC\]\s*$/m) + return match ? match.index : undefined + }, + tokenizer(src) { + const match = /^\[TOC\]/.exec(src) + if (match) { + return { + type: `toc`, + raw: match[0], + } + } + }, + renderer() { + if (!headings.length) + return `` + let html = `` + + firstToken = true + return html + }, + }, + ], + } +} diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/html-builder.ts b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/html-builder.ts new file mode 100644 index 0000000..3ca61a0 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/html-builder.ts @@ -0,0 +1,142 @@ +import fs from "node:fs"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import type { StyleConfig, HtmlDocumentMeta } from "./types.js"; +import { DEFAULT_STYLE } from "./constants.js"; + +const SCRIPT_DIR = path.dirname(fileURLToPath(import.meta.url)); +const CODE_THEMES_DIR = path.resolve(SCRIPT_DIR, "code-themes"); + +export function buildCss(baseCss: string, themeCss: string, style: StyleConfig = DEFAULT_STYLE): string { + const variables = ` +:root { + --md-primary-color: ${style.primaryColor}; + --md-font-family: ${style.fontFamily}; + --md-font-size: ${style.fontSize}; + --foreground: ${style.foreground}; + --blockquote-background: ${style.blockquoteBackground}; + --md-accent-color: ${style.accentColor}; + --md-container-bg: ${style.containerBg}; +} + +body { + margin: 0; + padding: 24px; + background: #ffffff; +} + +#output { + max-width: 860px; + margin: 0 auto; +} +`.trim(); + + return [variables, baseCss, themeCss].join("\n\n"); +} + +export function loadCodeThemeCss(themeName: string): string { + const filePath = path.join(CODE_THEMES_DIR, `${themeName}.min.css`); + try { + return fs.readFileSync(filePath, "utf-8"); + } catch { + console.error(`Code theme CSS not found: ${filePath}`); + return ""; + } +} + +export function buildHtmlDocument(meta: HtmlDocumentMeta, css: string, html: string, codeThemeCss?: string): string { + const lines = [ + "", + "", + "", + ' ', + ' ', + ` ${meta.title}`, + ]; + if (meta.author) { + lines.push(` `); + } + if (meta.description) { + lines.push(` `); + } + lines.push(` `); + if (codeThemeCss) { + lines.push(` `); + } + lines.push( + "", + "", + '
', + html, + "
", + "", + "" + ); + return lines.join("\n"); +} + +export async function inlineCss(html: string): Promise { + try { + const { default: juice } = await import("juice"); + return juice(html, { + inlinePseudoElements: true, + preserveImportant: true, + resolveCSSVariables: false, + }); + } catch (error) { + const detail = error instanceof Error ? error.message : String(error); + throw new Error( + `Missing dependency "juice" for CSS inlining. Install it first (e.g. "bun add juice" or "npm add juice"). Original error: ${detail}` + ); + } +} + +export function normalizeCssText(cssText: string, style: StyleConfig = DEFAULT_STYLE): string { + return cssText + .replace(/var\(--md-primary-color\)/g, style.primaryColor) + .replace(/var\(--md-font-family\)/g, style.fontFamily) + .replace(/var\(--md-font-size\)/g, style.fontSize) + .replace(/var\(--blockquote-background\)/g, style.blockquoteBackground) + .replace(/var\(--md-accent-color\)/g, style.accentColor) + .replace(/var\(--md-container-bg\)/g, style.containerBg) + .replace(/hsl\(var\(--foreground\)\)/g, "#3f3f3f") + .replace(/--md-primary-color:\s*[^;"']+;?/g, "") + .replace(/--md-font-family:\s*[^;"']+;?/g, "") + .replace(/--md-font-size:\s*[^;"']+;?/g, "") + .replace(/--blockquote-background:\s*[^;"']+;?/g, "") + .replace(/--md-accent-color:\s*[^;"']+;?/g, "") + .replace(/--md-container-bg:\s*[^;"']+;?/g, "") + .replace(/--foreground:\s*[^;"']+;?/g, ""); +} + +export function normalizeInlineCss(html: string, style: StyleConfig = DEFAULT_STYLE): string { + let output = html; + output = output.replace( + /]*)>([\s\S]*?)<\/style>/gi, + (_match, attrs: string, cssText: string) => + `${normalizeCssText(cssText, style)}` + ); + output = output.replace( + /style="([^"]*)"/gi, + (_match, cssText: string) => `style="${normalizeCssText(cssText, style)}"` + ); + output = output.replace( + /style='([^']*)'/gi, + (_match, cssText: string) => `style='${normalizeCssText(cssText, style)}'` + ); + return output; +} + +export function modifyHtmlStructure(htmlString: string): string { + let output = htmlString; + const pattern = + /]*)>([\s\S]*?)(|)<\/li>/i; + while (pattern.test(output)) { + output = output.replace(pattern, "$2$3"); + } + return output; +} + +export function removeFirstHeading(html: string): string { + return html.replace(/]*>[\s\S]*?<\/h[12]>/, ""); +} diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/images.ts b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/images.ts new file mode 100644 index 0000000..f0a3f00 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/images.ts @@ -0,0 +1,127 @@ +import { createHash } from "node:crypto"; +import fs from "node:fs"; +import http from "node:http"; +import https from "node:https"; +import path from "node:path"; + +export interface ImagePlaceholder { + originalPath: string; + placeholder: string; +} + +export interface ResolvedImageInfo extends ImagePlaceholder { + localPath: string; +} + +export function replaceMarkdownImagesWithPlaceholders( + markdown: string, + placeholderPrefix: string, +): { + images: ImagePlaceholder[]; + markdown: string; +} { + const images: ImagePlaceholder[] = []; + let imageCounter = 0; + + const rewritten = markdown.replace(/!\[([^\]]*)\]\(([^)]+)\)/g, (_match, _alt, src) => { + const placeholder = `${placeholderPrefix}${++imageCounter}`; + images.push({ + originalPath: src, + placeholder, + }); + return placeholder; + }); + + return { images, markdown: rewritten }; +} + +export function getImageExtension(urlOrPath: string): string { + const match = urlOrPath.match(/\.(jpg|jpeg|png|gif|webp)(\?|$)/i); + return match ? match[1]!.toLowerCase() : "png"; +} + +export async function downloadFile(url: string, destPath: string): Promise { + return await new Promise((resolve, reject) => { + const protocol = url.startsWith("https://") ? https : http; + const file = fs.createWriteStream(destPath); + + const request = protocol.get(url, { headers: { "User-Agent": "Mozilla/5.0" } }, (response) => { + if (response.statusCode === 301 || response.statusCode === 302) { + const redirectUrl = response.headers.location; + if (redirectUrl) { + file.close(); + fs.unlinkSync(destPath); + void downloadFile(redirectUrl, destPath).then(resolve).catch(reject); + return; + } + } + + if (response.statusCode !== 200) { + file.close(); + fs.unlinkSync(destPath); + reject(new Error(`Failed to download: ${response.statusCode}`)); + return; + } + + response.pipe(file); + file.on("finish", () => { + file.close(); + resolve(); + }); + }); + + request.on("error", (error) => { + file.close(); + fs.unlink(destPath, () => {}); + reject(error); + }); + + request.setTimeout(30_000, () => { + request.destroy(); + reject(new Error("Download timeout")); + }); + }); +} + +export async function resolveImagePath( + imagePath: string, + baseDir: string, + tempDir: string, + logLabel = "baoyu-md", +): Promise { + if (imagePath.startsWith("http://") || imagePath.startsWith("https://")) { + const hash = createHash("md5").update(imagePath).digest("hex").slice(0, 8); + const ext = getImageExtension(imagePath); + const localPath = path.join(tempDir, `remote_${hash}.${ext}`); + + if (!fs.existsSync(localPath)) { + console.error(`[${logLabel}] Downloading: ${imagePath}`); + await downloadFile(imagePath, localPath); + } + return localPath; + } + + if (path.isAbsolute(imagePath)) { + return imagePath; + } + + return path.resolve(baseDir, imagePath); +} + +export async function resolveContentImages( + images: ImagePlaceholder[], + baseDir: string, + tempDir: string, + logLabel = "baoyu-md", +): Promise { + const resolved: ResolvedImageInfo[] = []; + + for (const image of images) { + resolved.push({ + ...image, + localPath: await resolveImagePath(image.originalPath, baseDir, tempDir, logLabel), + }); + } + + return resolved; +} diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/index.ts b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/index.ts new file mode 100644 index 0000000..eeec395 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/index.ts @@ -0,0 +1,10 @@ +export * from "./cli.js"; +export * from "./constants.js"; +export * from "./content.js"; +export * from "./document.js"; +export * from "./extend-config.js"; +export * from "./html-builder.js"; +export * from "./images.js"; +export * from "./renderer.js"; +export * from "./themes.js"; +export * from "./types.js"; diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/render.ts b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/render.ts new file mode 100644 index 0000000..85415d6 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/render.ts @@ -0,0 +1,43 @@ +#!/usr/bin/env npx tsx + +import path from "node:path"; +import { parseArgs, printUsage } from "./cli.js"; +import { renderMarkdownFileToHtml } from "./document.js"; + +async function main(): Promise { + const options = parseArgs(process.argv.slice(2)); + if (!options) { + printUsage(); + process.exit(1); + } + + const inputPath = path.resolve(process.cwd(), options.inputPath); + if (!inputPath.toLowerCase().endsWith(".md")) { + console.error("Input file must end with .md"); + process.exit(1); + } + + const result = await renderMarkdownFileToHtml(inputPath, { + codeTheme: options.codeTheme, + countStatus: options.countStatus, + citeStatus: options.citeStatus, + fontFamily: options.fontFamily, + fontSize: options.fontSize, + isMacCodeBlock: options.isMacCodeBlock, + isShowLineNumber: options.isShowLineNumber, + keepTitle: options.keepTitle, + legend: options.legend, + primaryColor: options.primaryColor, + theme: options.theme, + }); + + if (result.backupPath) { + console.log(`Backup created: ${result.backupPath}`); + } + console.log(`HTML written: ${result.outputPath}`); +} + +main().catch((error) => { + console.error(error); + process.exit(1); +}); diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/renderer.ts b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/renderer.ts new file mode 100644 index 0000000..7a1234c --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/renderer.ts @@ -0,0 +1,434 @@ +import frontMatter from "front-matter"; +import hljs from "highlight.js/lib/core"; +import { marked, type RendererObject, type Tokens } from "marked"; +import readingTime, { type ReadTimeResults } from "reading-time"; +import { unified } from "unified"; +import remarkParse from "remark-parse"; +import remarkCjkFriendly from "remark-cjk-friendly"; +import remarkStringify from "remark-stringify"; + +import { + markedAlert, + markedFootnotes, + markedInfographic, + markedMarkup, + markedPlantUML, + markedRuby, + markedSlider, + markedToc, + MDKatex, +} from "./extensions/index.js"; +import { + COMMON_LANGUAGES, + highlightAndFormatCode, +} from "./utils/languages.js"; +import { macCodeSvg } from "./constants.js"; +import type { IOpts, ParseResult, RendererAPI } from "./types.js"; + +Object.entries(COMMON_LANGUAGES).forEach(([name, lang]) => { + hljs.registerLanguage(name, lang); +}); + +export { hljs }; + +marked.setOptions({ + breaks: true, +}); +marked.use(markedSlider()); + +function escapeHtml(text: string): string { + return text + .replace(/&/g, "&") + .replace(//g, ">") + .replace(/"/g, """) + .replace(/'/g, "'") + .replace(/`/g, "`"); +} + +function buildAddition(): string { + return ` + + `; +} + +function buildFootnoteArray(footnotes: [number, string, string][]): string { + return footnotes + .map(([index, title, link]) => + link === title + ? `[${index}]: ${title}
` + : `[${index}] ${title}: ${link}
` + ) + .join("\n"); +} + +function transform(legend: string, text: string | null, title: string | null): string { + const options = legend.split("-"); + for (const option of options) { + if (option === "alt" && text) { + return text; + } + if (option === "title" && title) { + return title; + } + } + return ""; +} + +function parseFrontMatterAndContent(markdownText: string): ParseResult { + try { + const parsed = frontMatter(markdownText); + const yamlData = parsed.attributes; + const markdownContent = parsed.body; + const readingTimeResult = readingTime(markdownContent); + return { + yamlData: yamlData as Record, + markdownContent, + readingTime: readingTimeResult, + }; + } catch (error) { + console.error("Error parsing front-matter:", error); + return { + yamlData: {}, + markdownContent: markdownText, + readingTime: readingTime(markdownText), + }; + } +} + +export function initRenderer(opts: IOpts = {}): RendererAPI { + const footnotes: [number, string, string][] = []; + let footnoteIndex = 0; + let codeIndex = 0; + const listOrderedStack: boolean[] = []; + const listCounters: number[] = []; + const isBrowser = typeof window !== "undefined"; + + function getOpts(): IOpts { + return opts; + } + + function styledContent(styleLabel: string, content: string, tagName?: string): string { + const tag = tagName ?? styleLabel; + const className = `${styleLabel.replace(/_/g, "-")}`; + const headingAttr = /^h\d$/.test(tag) ? " data-heading=\"true\"" : ""; + return `<${tag} class="${className}"${headingAttr}>${content}`; + } + + function addFootnote(title: string, link: string): number { + const existingFootnote = footnotes.find(([, , existingLink]) => existingLink === link); + if (existingFootnote) { + return existingFootnote[0]; + } + footnotes.push([++footnoteIndex, title, link]); + return footnoteIndex; + } + + function reset(newOpts: Partial): void { + footnotes.length = 0; + footnoteIndex = 0; + setOptions(newOpts); + } + + function setOptions(newOpts: Partial): void { + opts = { ...opts, ...newOpts }; + marked.use(markedAlert()); + if (isBrowser) { + marked.use(MDKatex({ nonStandard: true }, true)); + } + marked.use(markedMarkup()); + marked.use(markedInfographic({ themeMode: opts.themeMode })); + } + + function buildReadingTime(readingTimeResult: ReadTimeResults): string { + if (!opts.countStatus) { + return ""; + } + if (!readingTimeResult.words) { + return ""; + } + return ` +
+

字数 ${readingTimeResult?.words},阅读大约需 ${Math.ceil(readingTimeResult?.minutes)} 分钟

+
+ `; + } + + const buildFootnotes = () => { + if (!footnotes.length) { + return ""; + } + return ( + styledContent("h4", "引用链接") + + styledContent("footnotes", buildFootnoteArray(footnotes), "p") + ); + }; + + const renderer: RendererObject = { + heading({ tokens, depth }: Tokens.Heading) { + const text = this.parser.parseInline(tokens); + const tag = `h${depth}`; + return styledContent(tag, text); + }, + + paragraph({ tokens }: Tokens.Paragraph): string { + const text = this.parser.parseInline(tokens); + const isFigureImage = text.includes(" { + const windowRef = typeof window !== "undefined" ? (window as any) : undefined; + if (windowRef && windowRef.mermaid) { + const mermaid = windowRef.mermaid; + await mermaid.run(); + } else { + const mermaid = await import("mermaid"); + await mermaid.default.run(); + } + }, 0) as any as number; + } + return `
${text}
`; + } + const langText = lang.split(" ")[0]; + const isLanguageRegistered = hljs.getLanguage(langText); + const language = isLanguageRegistered ? langText : "plaintext"; + + const highlighted = highlightAndFormatCode( + text, + language, + hljs, + !!opts.isShowLineNumber + ); + + const span = `${macCodeSvg}`; + let pendingAttr = ""; + if (!isLanguageRegistered && langText !== "plaintext") { + const escapedText = text.replace(/"/g, """); + pendingAttr = ` data-language-pending="${langText}" data-raw-code="${escapedText}" data-show-line-number="${opts.isShowLineNumber}"`; + } + const code = `${highlighted}`; + + return `
${span}${code}
`; + }, + + codespan({ text }: Tokens.Codespan): string { + const escapedText = escapeHtml(text); + return styledContent("codespan", escapedText, "code"); + }, + + list({ ordered, items, start = 1 }: Tokens.List) { + listOrderedStack.push(ordered); + listCounters.push(Number(start)); + const html = items.map((item) => this.listitem(item)).join(""); + listOrderedStack.pop(); + listCounters.pop(); + return styledContent(ordered ? "ol" : "ul", html); + }, + + listitem(token: Tokens.ListItem) { + const ordered = listOrderedStack[listOrderedStack.length - 1]; + const idx = listCounters[listCounters.length - 1]!; + listCounters[listCounters.length - 1] = idx + 1; + const prefix = ordered ? `${idx}. ` : "• "; + let content: string; + try { + content = this.parser.parseInline(token.tokens); + } catch { + content = this.parser + .parse(token.tokens) + .replace(/^]*)?>([\s\S]*?)<\/p>/, "$1"); + } + return styledContent("listitem", `${prefix}${content}`, "li"); + }, + + image({ href, title, text }: Tokens.Image): string { + const newText = opts.legend ? transform(opts.legend, text, title) : ""; + const subText = newText ? styledContent("figcaption", newText) : ""; + const titleAttr = title ? ` title="${title}"` : ""; + return `
${text}${subText}
`; + }, + + link({ href, title, text, tokens }: Tokens.Link): string { + const parsedText = this.parser.parseInline(tokens); + if (/^https?:\/\/mp\.weixin\.qq\.com/.test(href)) { + return `${parsedText}`; + } + if (href === text) { + return parsedText; + } + if (opts.citeStatus) { + const ref = addFootnote(title || text, href); + return `${parsedText}[${ref}]`; + } + return `${parsedText}`; + }, + + strong({ tokens }: Tokens.Strong): string { + return styledContent("strong", this.parser.parseInline(tokens)); + }, + + em({ tokens }: Tokens.Em): string { + return styledContent("em", this.parser.parseInline(tokens)); + }, + + table({ header, rows }: Tokens.Table): string { + const headerRow = header + .map((cell) => { + const text = this.parser.parseInline(cell.tokens); + return styledContent("th", text); + }) + .join(""); + const body = rows + .map((row) => { + const rowContent = row.map((cell) => this.tablecell(cell)).join(""); + return styledContent("tr", rowContent); + }) + .join(""); + return ` +
+ + ${headerRow} + ${body} +
+
+ `; + }, + + tablecell(token: Tokens.TableCell): string { + const text = this.parser.parseInline(token.tokens); + return styledContent("td", text); + }, + + hr(_: Tokens.Hr): string { + return styledContent("hr", ""); + }, + }; + + marked.use({ renderer }); + marked.use(markedMarkup()); + marked.use(markedToc()); + marked.use(markedSlider()); + marked.use(markedAlert({})); + if (isBrowser) { + marked.use(MDKatex({ nonStandard: true }, true)); + } + marked.use(markedFootnotes()); + marked.use( + markedPlantUML({ + inlineSvg: isBrowser, + }) + ); + marked.use(markedInfographic()); + marked.use(markedRuby()); + + return { + buildAddition, + buildFootnotes, + setOptions, + reset, + parseFrontMatterAndContent, + buildReadingTime, + createContainer(content: string) { + return styledContent("container", content, "section"); + }, + getOpts, + }; +} + +function preprocessCjkEmphasis(markdown: string): string { + const processor = unified() + .use(remarkParse) + .use(remarkCjkFriendly); + const tree = processor.parse(markdown); + const extractText = (node: any): string => { + if (node.type === "text") return node.value; + if (node.children) return node.children.map(extractText).join(""); + return ""; + }; + const visit = (node: any, parent?: any, index?: number) => { + if (node.children) { + for (let i = 0; i < node.children.length; i++) { + visit(node.children[i], node, i); + } + } + if (node.type === "strong" && parent && typeof index === "number") { + const text = extractText(node); + parent.children[index] = { type: "html", value: `${text}` }; + } + if (node.type === "emphasis" && parent && typeof index === "number") { + const text = extractText(node); + parent.children[index] = { type: "html", value: `${text}` }; + } + }; + visit(tree); + const stringify = unified().use(remarkStringify); + let result = stringify.stringify(tree); + result = result.replace(/&#x([0-9A-Fa-f]+);/g, (_, hex) => + String.fromCodePoint(parseInt(hex, 16)) + ); + return result; +} + +export function renderMarkdown(raw: string, renderer: RendererAPI): { + html: string; + readingTime: ReadTimeResults; +} { + const { markdownContent, readingTime: readingTimeResult } = + renderer.parseFrontMatterAndContent(raw); + const preprocessed = preprocessCjkEmphasis(markdownContent); + const html = marked.parse(preprocessed) as string; + return { html, readingTime: readingTimeResult }; +} + +export function postProcessHtml( + baseHtml: string, + reading: ReadTimeResults, + renderer: RendererAPI +): string { + let html = baseHtml; + html = renderer.buildReadingTime(reading) + html; + html += renderer.buildFootnotes(); + html += renderer.buildAddition(); + html += ` + + `; + html += ` + + `; + return renderer.createContainer(html); +} diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/themes.ts b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/themes.ts new file mode 100644 index 0000000..9c3dbeb --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/themes.ts @@ -0,0 +1,62 @@ +import fs from "node:fs"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import type { ThemeName } from "./types.js"; + +const SCRIPT_DIR = path.dirname(fileURLToPath(import.meta.url)); +export const THEME_DIR = path.resolve(SCRIPT_DIR, "themes"); +const FALLBACK_THEMES: ThemeName[] = ["default", "grace", "simple"]; + +function stripOutputScope(cssContent: string): string { + let css = cssContent; + css = css.replace(/#output\s*\{/g, "body {"); + css = css.replace(/#output\s+/g, ""); + css = css.replace(/^#output\s*/gm, ""); + return css; +} + +function discoverThemesFromDir(dir: string): string[] { + if (!fs.existsSync(dir)) { + return []; + } + return fs + .readdirSync(dir) + .filter((name) => name.endsWith(".css")) + .map((name) => name.replace(/\.css$/i, "")) + .filter((name) => name.toLowerCase() !== "base"); +} + +function resolveThemeNames(): ThemeName[] { + const localThemes = discoverThemesFromDir(THEME_DIR); + const resolved = localThemes.filter((name) => + fs.existsSync(path.join(THEME_DIR, `${name}.css`)) + ); + return resolved.length ? resolved : FALLBACK_THEMES; +} + +export const THEME_NAMES: ThemeName[] = resolveThemeNames(); + +export function loadThemeCss(theme: ThemeName): { + baseCss: string; + themeCss: string; +} { + const basePath = path.join(THEME_DIR, "base.css"); + const themePath = path.join(THEME_DIR, `${theme}.css`); + + if (!fs.existsSync(basePath)) { + throw new Error(`Missing base CSS: ${basePath}`); + } + + if (!fs.existsSync(themePath)) { + throw new Error(`Missing theme CSS for "${theme}": ${themePath}`); + } + + return { + baseCss: fs.readFileSync(basePath, "utf-8"), + themeCss: fs.readFileSync(themePath, "utf-8"), + }; +} + +export function normalizeThemeCss(css: string): string { + return stripOutputScope(css); +} diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/themes/base.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/themes/base.css new file mode 100644 index 0000000..3ec1fe4 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/themes/base.css @@ -0,0 +1,39 @@ +/** + * MD 基础主题样式 + * 包含所有元素的基础样式和 CSS 变量定义 + */ + +/* ==================== 容器样式 ==================== */ +section, +container { + font-family: var(--md-font-family); + font-size: var(--md-font-size); + line-height: 1.75; + text-align: left; +} + +/* 确保 #output 容器应用基础样式 */ +#output { + font-family: var(--md-font-family); + font-size: var(--md-font-size); + line-height: 1.75; + text-align: left; +} + +/* ==================== Global resets ==================== */ +blockquote { + margin-top: 0; + margin-right: 0; + margin-bottom: 0; + margin-left: 0; +} + +/* 去除第一个元素的 margin-top */ +#output section > :first-child { + margin-top: 0 !important; +} + +.mermaid-diagram .nodeLabel p { + color: unset !important; + letter-spacing: unset !important; +} diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/themes/default.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/themes/default.css new file mode 100644 index 0000000..b9982f6 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/themes/default.css @@ -0,0 +1,434 @@ +/** + * MD 默认主题(经典主题) + * 按 Alt/Option + Shift + F 可格式化 + * 如需使用主题色,请使用 var(--md-primary-color) 代替颜色值 + */ + +/* ==================== 一级标题 ==================== */ +h1 { + display: table; + padding: 0 1em; + border-bottom: 2px solid var(--md-primary-color); + margin: 2em auto 1em; + color: hsl(var(--foreground)); + font-size: calc(var(--md-font-size) * 1.2); + font-weight: bold; + text-align: center; +} + +/* ==================== 二级标题 ==================== */ +h2 { + display: table; + padding: 0 0.2em; + margin: 4em auto 2em; + color: #fff; + background: var(--md-primary-color); + font-size: calc(var(--md-font-size) * 1.2); + font-weight: bold; + text-align: center; +} + +/* ==================== 三级标题 ==================== */ +h3 { + padding-left: 8px; + border-left: 3px solid var(--md-primary-color); + margin: 2em 8px 0.75em 0; + color: hsl(var(--foreground)); + font-size: calc(var(--md-font-size) * 1.1); + font-weight: bold; + line-height: 1.2; +} + +/* ==================== 四级标题 ==================== */ +h4 { + margin: 2em 8px 0.5em; + color: var(--md-primary-color); + font-size: calc(var(--md-font-size) * 1); + font-weight: bold; +} + +/* ==================== 五级标题 ==================== */ +h5 { + margin: 1.5em 8px 0.5em; + color: var(--md-primary-color); + font-size: calc(var(--md-font-size) * 1); + font-weight: bold; +} + +/* ==================== 六级标题 ==================== */ +h6 { + margin: 1.5em 8px 0.5em; + font-size: calc(var(--md-font-size) * 1); + color: var(--md-primary-color); +} + +/* ==================== 段落 ==================== */ +p { + margin: 1.5em 8px; + letter-spacing: 0.1em; + color: hsl(var(--foreground)); +} + +/* ==================== 引用块 ==================== */ +blockquote { + font-style: normal; + padding: 1em; + border-left: 4px solid var(--md-primary-color); + border-radius: 6px; + color: hsl(var(--foreground)); + background: var(--blockquote-background); + margin-bottom: 1em; +} + +blockquote > p { + display: block; + font-size: 1em; + letter-spacing: 0.1em; + color: hsl(var(--foreground)); + margin: 0; +} + +/* ==================== GFM 警告块 ==================== */ +.alert-title-note, +.alert-title-tip, +.alert-title-info, +.alert-title-important, +.alert-title-warning, +.alert-title-caution, +.alert-title-abstract, +.alert-title-summary, +.alert-title-tldr, +.alert-title-todo, +.alert-title-success, +.alert-title-done, +.alert-title-question, +.alert-title-help, +.alert-title-faq, +.alert-title-failure, +.alert-title-fail, +.alert-title-missing, +.alert-title-danger, +.alert-title-error, +.alert-title-bug, +.alert-title-example, +.alert-title-quote, +.alert-title-cite { + display: flex; + align-items: center; + gap: 0.5em; + margin-bottom: 0.5em; +} + +.alert-title-note { + color: #478be6; +} + +.alert-title-tip { + color: #57ab5a; +} + +.alert-title-info { + color: #93c5fd; +} + +.alert-title-important { + color: #986ee2; +} + +.alert-title-warning { + color: #c69026; +} + +.alert-title-caution { + color: #e5534b; +} + +/* Obsidian-style callout colors */ +.alert-title-abstract, +.alert-title-summary, +.alert-title-tldr { + color: #00bfff; +} + +.alert-title-todo { + color: #478be6; +} + +.alert-title-success, +.alert-title-done { + color: #57ab5a; +} + +.alert-title-question, +.alert-title-help, +.alert-title-faq { + color: #c69026; +} + +.alert-title-failure, +.alert-title-fail, +.alert-title-missing { + color: #e5534b; +} + +.alert-title-danger, +.alert-title-error { + color: #e5534b; +} + +.alert-title-bug { + color: #e5534b; +} + +.alert-title-example { + color: #986ee2; +} + +.alert-title-quote, +.alert-title-cite { + color: #9ca3af; +} + +/* GFM Alert SVG 图标颜色 */ +.alert-icon-note { + fill: #478be6; +} + +.alert-icon-tip { + fill: #57ab5a; +} + +.alert-icon-info { + fill: #93c5fd; +} + +.alert-icon-important { + fill: #986ee2; +} + +.alert-icon-warning { + fill: #c69026; +} + +.alert-icon-caution { + fill: #e5534b; +} + +/* Obsidian-style callout icon colors */ +.alert-icon-abstract, +.alert-icon-summary, +.alert-icon-tldr { + fill: #00bfff; +} + +.alert-icon-todo { + fill: #478be6; +} + +.alert-icon-success, +.alert-icon-done { + fill: #57ab5a; +} + +.alert-icon-question, +.alert-icon-help, +.alert-icon-faq { + fill: #c69026; +} + +.alert-icon-failure, +.alert-icon-fail, +.alert-icon-missing { + fill: #e5534b; +} + +.alert-icon-danger, +.alert-icon-error { + fill: #e5534b; +} + +.alert-icon-bug { + fill: #e5534b; +} + +.alert-icon-example { + fill: #986ee2; +} + +.alert-icon-quote, +.alert-icon-cite { + fill: #9ca3af; +} + +/* ==================== 代码块 ==================== */ +pre.code__pre, +.hljs.code__pre { + font-size: 90%; + overflow-x: auto; + border-radius: 8px; + padding: 0 !important; + line-height: 1.5; + margin: 10px 8px; + box-shadow: inset 0 0 10px rgba(0,0,0,0.05); +} + +/* ==================== 图片 ==================== */ +img { + display: block; + max-width: 100%; + margin: 0.1em auto 0.5em; + border-radius: 4px; +} + +/* ==================== 列表 ==================== */ +ol { + padding-left: 1em; + margin-left: 0; + color: hsl(var(--foreground)); +} + +ul { + list-style: circle; + padding-left: 1em; + margin-left: 0; + color: hsl(var(--foreground)); +} + +li { + display: block; + margin: 0.2em 8px; + color: hsl(var(--foreground)); +} + +/* ==================== 脚注 ==================== */ +/* footnotes 在 buildFootnotes() 中渲染为

标签 */ +p.footnotes { + margin: 0.5em 8px; + font-size: 80%; + color: hsl(var(--foreground)); +} + +/* ==================== 图表 ==================== */ +figure { + margin: 1.5em 8px; + color: hsl(var(--foreground)); +} + +figcaption, +.md-figcaption { + text-align: center; + color: #888; + font-size: 0.8em; +} + +/* ==================== 分隔线 ==================== */ +hr { + border-style: solid; + border-width: 2px 0 0; + border-color: rgba(0, 0, 0, 0.1); + -webkit-transform-origin: 0 0; + -webkit-transform: scale(1, 0.5); + transform-origin: 0 0; + transform: scale(1, 0.5); + height: 0.4em; + margin: 1.5em 0; +} + +/* ==================== 行内代码 ==================== */ +code { + font-size: 90%; + color: #d14; + background: rgba(27, 31, 35, 0.05); + padding: 3px 5px; + border-radius: 4px; +} + +/* 代码块内的 code 标签需要特殊处理(覆盖行内 code 样式) */ +pre.code__pre > code, +.hljs.code__pre > code { + display: -webkit-box; + padding: 0.5em 1em 1em; + overflow-x: auto; + text-indent: 0; + color: inherit; + background: none; + white-space: nowrap; + margin: 0; +} + +/* ==================== 强调 ==================== */ +em { + font-style: italic; + font-size: inherit; +} + +/* ==================== 链接 ==================== */ +a { + color: #576b95; + text-decoration: none; +} + +/* ==================== 粗体 ==================== */ +strong { + color: var(--md-primary-color); + font-weight: bold; + font-size: inherit; +} + +/* ==================== 表格 ==================== */ +table { + color: hsl(var(--foreground)); +} + +thead { + font-weight: bold; + color: hsl(var(--foreground)); +} + +th { + border: 1px solid #dfdfdf; + padding: 0.25em 0.5em; + color: hsl(var(--foreground)); + word-break: keep-all; + background: rgba(0, 0, 0, 0.05); +} + +td { + border: 1px solid #dfdfdf; + padding: 0.25em 0.5em; + color: hsl(var(--foreground)); + word-break: keep-all; +} + +/* ==================== KaTeX 公式 ==================== */ +.katex-inline { + max-width: 100%; + overflow-x: auto; +} + +.katex-block { + max-width: 100%; + overflow-x: auto; + -webkit-overflow-scrolling: touch; + padding: 0.5em 0; + text-align: center; +} + +/* ==================== 标记高亮 ==================== */ +.markup-highlight { + background-color: var(--md-primary-color); + padding: 2px 4px; + border-radius: 2px; + color: #fff; +} + +.markup-underline { + text-decoration: underline; + text-decoration-color: var(--md-primary-color); +} + +.markup-wavyline { + text-decoration: underline wavy; + text-decoration-color: var(--md-primary-color); + text-decoration-thickness: 2px; +} diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/themes/grace.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/themes/grace.css new file mode 100644 index 0000000..161e5f4 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/themes/grace.css @@ -0,0 +1,136 @@ +/** + * MD 优雅主题 (@brzhang) + * 在默认主题基础上添加优雅的视觉效果 + */ + +/* ==================== 标题样式 ==================== */ +h1 { + padding: 0.5em 1em; + border-bottom: 2px solid var(--md-primary-color); + font-size: calc(var(--md-font-size) * 1.4); + text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.1); +} + +h2 { + padding: 0.3em 1em; + border-radius: 8px; + font-size: calc(var(--md-font-size) * 1.3); + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); +} + +h3 { + padding-left: 12px; + font-size: calc(var(--md-font-size) * 1.2); + border-left: 4px solid var(--md-primary-color); + border-bottom: 1px dashed var(--md-primary-color); +} + +h4 { + font-size: calc(var(--md-font-size) * 1.1); +} + +h5 { + font-size: var(--md-font-size); +} + +h6 { + font-size: var(--md-font-size); +} + +/* ==================== 引用块 ==================== */ +blockquote { + font-style: italic; + padding: 1em 1em 1em 2em; + border-left: 4px solid var(--md-primary-color); + border-radius: 6px; + color: rgba(0, 0, 0, 0.6); + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05); + margin-bottom: 1em; +} + +.markdown-alert { + font-style: italic; +} + +/* ==================== 代码块 ==================== */ +pre.code__pre, +.hljs.code__pre { + box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.05); +} + +pre.code__pre > code, +.hljs.code__pre > code { + font-family: + 'Fira Code', + Menlo, + Operator Mono, + Consolas, + Monaco, + monospace; +} + +/* ==================== 图片 ==================== */ +img { + border-radius: 8px; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); +} + +figcaption, +.md-figcaption { + text-align: center; + color: #888; + font-size: 0.8em; +} + +/* ==================== 列表 ==================== */ +ol { + padding-left: 1.5em; +} + +ul { + list-style: none; + padding-left: 1.5em; +} + +li { + margin: 0.5em 8px; +} + +/* ==================== 分隔线 ==================== */ +hr { + height: 1px; + border: none; + margin: 2em 0; + background: linear-gradient(to right, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0)); +} + +/* ==================== 表格 ==================== */ +table { + border-collapse: separate; + border-spacing: 0; + border-radius: 8px; + margin: 1em 8px; + color: hsl(var(--foreground)); + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); + overflow: hidden; +} + +thead { + color: #fff; +} + +td { + padding: 0.5em 1em; +} + +/* ==================== 强调 ==================== */ +em { + font-style: italic; + font-size: inherit; +} + +/* ==================== 链接 ==================== */ +a { + color: #576b95; + text-decoration: none; +} diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/themes/modern.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/themes/modern.css new file mode 100644 index 0000000..ccd2cc0 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/themes/modern.css @@ -0,0 +1,465 @@ +/** + * MD 现代主题 (modern) + * 大圆角、药丸形标题、宽松行距、现代感 + * 如需使用主题色,请使用 var(--md-primary-color) 代替颜色值 + */ + +/* ==================== 容器样式覆盖 ==================== */ +section, +container { + font-family: var(--md-font-family); + font-size: var(--md-font-size); + line-height: 2; + letter-spacing: 0px; + font-weight: 400; + background-color: var(--md-container-bg); + border: 1px solid rgba(255, 255, 255, 0.01); + border-radius: 25px; + padding: 12px 12px; +} + +#output { + font-family: var(--md-font-family); + font-size: var(--md-font-size); + line-height: 2; +} + +/* ==================== 一级标题 ==================== */ +h1 { + display: table; + padding: 0.3em 1em; + margin: 20px auto; + color: hsl(var(--foreground)); + background: var(--md-primary-color); + border-radius: 15px; + font-size: 28px; + font-weight: bold; + text-align: center; +} + +/* ==================== 二级标题 ==================== */ +h2 { + display: block; + padding: 0.2em 0; + padding-bottom: 0; + margin: 0 auto 20px; + width: 100%; + color: var(--md-primary-color); + font-size: 20px; + font-weight: bold; + letter-spacing: 0.578px; + line-height: 1.7; + border-bottom: 2px solid var(--md-accent-color); + text-align: left; +} + +/* ==================== 三级标题 ==================== */ +h3 { + padding-left: 10px; + border-left: 4px solid var(--md-primary-color); + border-radius: 2px; + margin: 0 8px 10px; + color: hsl(var(--foreground)); + font-size: 20px; + font-weight: bold; + line-height: 1.2; +} + +/* ==================== 四级标题 ==================== */ +h4 { + margin: 0 8px 10px; + color: var(--md-primary-color); + font-size: 16px; + font-weight: bold; +} + +/* ==================== 五级标题 ==================== */ +h5 { + display: inline-block; + margin: 0 8px 10px; + padding: 4px 12px; + color: hsl(var(--foreground)); + background: rgba(255, 255, 255, 0.7); + border: 1px solid rgb(189, 224, 254); + border-radius: 20px; + font-size: 16px; + font-weight: 500; +} + +/* ==================== 六级标题 ==================== */ +h6 { + margin: 0 8px 10px; + color: var(--md-primary-color); + font-size: 16px; + font-weight: bold; +} + +/* ==================== 段落 ==================== */ +p { + margin: 20px 0; + letter-spacing: 0.1em; + color: hsl(var(--foreground)); + line-height: 2; + letter-spacing: 0px; + font-size: 15px; + font-weight: 400; + word-break: break-all; +} + +/* ==================== 引用块 ==================== */ +blockquote { + font-style: normal; + padding: 15px 0; + margin: 12px 0; + border-left: 7px solid var(--md-accent-color); + border-radius: 10px; + color: hsl(var(--foreground)); + background-color: var(--blockquote-background); +} + +blockquote > p { + display: block; + font-size: 1em; + letter-spacing: 0.1em; + color: hsl(var(--foreground)); + margin: 0; +} + +/* ==================== GFM 警告块 ==================== */ +.alert-title-note, +.alert-title-tip, +.alert-title-info, +.alert-title-important, +.alert-title-warning, +.alert-title-caution, +.alert-title-abstract, +.alert-title-summary, +.alert-title-tldr, +.alert-title-todo, +.alert-title-success, +.alert-title-done, +.alert-title-question, +.alert-title-help, +.alert-title-faq, +.alert-title-failure, +.alert-title-fail, +.alert-title-missing, +.alert-title-danger, +.alert-title-error, +.alert-title-bug, +.alert-title-example, +.alert-title-quote, +.alert-title-cite { + display: flex; + align-items: center; + gap: 0.5em; + margin-bottom: 0.5em; +} + +.alert-title-note { + color: #478be6; +} + +.alert-title-tip { + color: #57ab5a; +} + +.alert-title-info { + color: #93c5fd; +} + +.alert-title-important { + color: #986ee2; +} + +.alert-title-warning { + color: #c69026; +} + +.alert-title-caution { + color: #e5534b; +} + +.alert-title-abstract, +.alert-title-summary, +.alert-title-tldr { + color: #00bfff; +} + +.alert-title-todo { + color: #478be6; +} + +.alert-title-success, +.alert-title-done { + color: #57ab5a; +} + +.alert-title-question, +.alert-title-help, +.alert-title-faq { + color: #c69026; +} + +.alert-title-failure, +.alert-title-fail, +.alert-title-missing { + color: #e5534b; +} + +.alert-title-danger, +.alert-title-error { + color: #e5534b; +} + +.alert-title-bug { + color: #e5534b; +} + +.alert-title-example { + color: #986ee2; +} + +.alert-title-quote, +.alert-title-cite { + color: #9ca3af; +} + +/* GFM Alert SVG 图标颜色 */ +.alert-icon-note { + fill: #478be6; +} + +.alert-icon-tip { + fill: #57ab5a; +} + +.alert-icon-info { + fill: #93c5fd; +} + +.alert-icon-important { + fill: #986ee2; +} + +.alert-icon-warning { + fill: #c69026; +} + +.alert-icon-caution { + fill: #e5534b; +} + +.alert-icon-abstract, +.alert-icon-summary, +.alert-icon-tldr { + fill: #00bfff; +} + +.alert-icon-todo { + fill: #478be6; +} + +.alert-icon-success, +.alert-icon-done { + fill: #57ab5a; +} + +.alert-icon-question, +.alert-icon-help, +.alert-icon-faq { + fill: #c69026; +} + +.alert-icon-failure, +.alert-icon-fail, +.alert-icon-missing { + fill: #e5534b; +} + +.alert-icon-danger, +.alert-icon-error { + fill: #e5534b; +} + +.alert-icon-bug { + fill: #e5534b; +} + +.alert-icon-example { + fill: #986ee2; +} + +.alert-icon-quote, +.alert-icon-cite { + fill: #9ca3af; +} + +/* ==================== 代码块 ==================== */ +pre.code__pre, +.hljs.code__pre { + font-size: 90%; + overflow-x: auto; + border-radius: 10px; + padding: 0 !important; + line-height: 1.5; + margin: 10px 8px; + box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.05); +} + +/* ==================== 图片 ==================== */ +img { + display: block; + max-width: 100%; + margin: 0.1em auto 0.5em; + border-radius: 10px; +} + +/* ==================== 列表 ==================== */ +ol { + padding-left: 1em; + margin-left: 0; + color: hsl(var(--foreground)); + line-height: 2; +} + +ul { + list-style: circle; + padding-left: 1em; + margin-left: 0; + color: hsl(var(--foreground)); + line-height: 2; +} + +li { + display: block; + margin: 0.2em 8px; + color: hsl(var(--foreground)); +} + +/* ==================== 脚注 ==================== */ +p.footnotes { + margin: 0.5em 8px; + font-size: 80%; + color: hsl(var(--foreground)); +} + +/* ==================== 图表 ==================== */ +figure { + margin: 1.5em 8px; + color: hsl(var(--foreground)); +} + +figcaption, +.md-figcaption { + text-align: center; + color: #888; + font-size: 0.8em; +} + +/* ==================== 分隔线 ==================== */ +hr { + border-style: solid; + border-width: 1px 0 0; + border-color: var(--md-accent-color); + margin: 1.5em 0; +} + +/* ==================== 行内代码 ==================== */ +code { + font-size: 90%; + color: #d14; + background: rgba(27, 31, 35, 0.05); + padding: 3px 5px; + border-radius: 4px; +} + +/* 代码块内的 code 标签需要特殊处理(覆盖行内 code 样式) */ +pre.code__pre > code, +.hljs.code__pre > code { + display: -webkit-box; + padding: 0.5em 1em 1em; + overflow-x: auto; + text-indent: 0; + color: inherit; + background: none; + white-space: nowrap; + margin: 0; +} + +/* ==================== 强调 ==================== */ +em { + font-style: italic; + font-size: inherit; +} + +/* ==================== 链接 ==================== */ +a { + color: var(--md-primary-color); + text-decoration: none; +} + +/* ==================== 粗体 ==================== */ +strong { + color: var(--md-primary-color); + font-weight: bold; + font-size: inherit; +} + +/* ==================== 表格 ==================== */ +table { + color: hsl(var(--foreground)); +} + +thead { + font-weight: bold; + color: hsl(var(--foreground)); +} + +th { + border: 1px solid #dfdfdf; + padding: 0.25em 0.5em; + color: hsl(var(--foreground)); + word-break: keep-all; + background: color-mix(in srgb, var(--md-primary-color) 10%, transparent); +} + +td { + border: 1px solid #dfdfdf; + padding: 0.25em 0.5em; + color: hsl(var(--foreground)); + word-break: keep-all; +} + +/* ==================== KaTeX 公式 ==================== */ +.katex-inline { + max-width: 100%; + overflow-x: auto; +} + +.katex-block { + max-width: 100%; + overflow-x: auto; + -webkit-overflow-scrolling: touch; + padding: 0.5em 0; + text-align: center; +} + +/* ==================== 标记高亮 ==================== */ +.markup-highlight { + background-color: var(--md-primary-color); + padding: 2px 4px; + border-radius: 4px; + color: #fff; +} + +.markup-underline { + text-decoration: underline; + text-decoration-color: var(--md-primary-color); +} + +.markup-wavyline { + text-decoration: underline wavy; + text-decoration-color: var(--md-primary-color); + text-decoration-thickness: 2px; +} diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/themes/simple.css b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/themes/simple.css new file mode 100644 index 0000000..a1db867 --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/themes/simple.css @@ -0,0 +1,129 @@ +/** + * MD 简洁主题 (@okooo5km) + * 简洁现代的设计风格 + */ + +/* ==================== 标题样式 ==================== */ +h1 { + padding: 0.5em 1em; + font-size: calc(var(--md-font-size) * 1.4); + text-shadow: 1px 1px 3px rgba(0, 0, 0, 0.05); +} + +h2 { + padding: 0.3em 1.2em; + font-size: calc(var(--md-font-size) * 1.3); + border-radius: 8px 24px 8px 24px; + box-shadow: 0 2px 6px rgba(0, 0, 0, 0.06); +} + +h3 { + padding-left: 12px; + font-size: calc(var(--md-font-size) * 1.2); + border-radius: 6px; + line-height: 2.4em; + border-left: 4px solid var(--md-primary-color); + border-right: 1px solid color-mix(in srgb, var(--md-primary-color) 10%, transparent); + border-bottom: 1px solid color-mix(in srgb, var(--md-primary-color) 10%, transparent); + border-top: 1px solid color-mix(in srgb, var(--md-primary-color) 10%, transparent); + background: color-mix(in srgb, var(--md-primary-color) 8%, transparent); +} + +h4 { + font-size: calc(var(--md-font-size) * 1.1); + border-radius: 6px; +} + +h5 { + font-size: var(--md-font-size); + border-radius: 6px; +} + +h6 { + font-size: var(--md-font-size); + border-radius: 6px; +} + +/* ==================== 引用块 ==================== */ +blockquote { + font-style: italic; + padding: 1em 1em 1em 2em; + color: rgba(0, 0, 0, 0.6); + border-bottom: 0.2px solid rgba(0, 0, 0, 0.04); + border-top: 0.2px solid rgba(0, 0, 0, 0.04); + border-right: 0.2px solid rgba(0, 0, 0, 0.04); +} + +/* GFM Alert 样式覆盖 */ +.markdown-alert-note, +.markdown-alert-tip, +.markdown-alert-info, +.markdown-alert-important, +.markdown-alert-warning, +.markdown-alert-caution { + font-style: italic; +} + +/* ==================== 代码块 ==================== */ +pre.code__pre, +.hljs.code__pre { + border: 1px solid rgba(0, 0, 0, 0.04); +} + +pre.code__pre > code, +.hljs.code__pre > code { + font-family: + 'Fira Code', + Menlo, + Operator Mono, + Consolas, + Monaco, + monospace; +} + +/* ==================== 图片 ==================== */ +img { + border-radius: 8px; + border: 1px solid rgba(0, 0, 0, 0.04); +} + +figcaption, +.md-figcaption { + text-align: center; + color: #888; + font-size: 0.8em; +} + +/* ==================== 列表 ==================== */ +ol { + padding-left: 1.5em; +} + +ul { + list-style: none; + padding-left: 1.5em; +} + +li { + margin: 0.5em 8px; +} + +/* ==================== 分隔线 ==================== */ +hr { + height: 1px; + border: none; + margin: 2em 0; + background: linear-gradient(to right, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0)); +} + +/* ==================== 强调 ==================== */ +em { + font-style: italic; + font-size: inherit; +} + +/* ==================== 链接 ==================== */ +a { + color: #576b95; + text-decoration: none; +} diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/types.ts b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/types.ts new file mode 100644 index 0000000..669f8cb --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/types.ts @@ -0,0 +1,78 @@ +import type { ReadTimeResults } from "reading-time"; + +export type ThemeName = string; + +export interface StyleConfig { + primaryColor: string; + fontFamily: string; + fontSize: string; + foreground: string; + blockquoteBackground: string; + accentColor: string; + containerBg: string; +} + +export interface IOpts { + legend?: string; + citeStatus?: boolean; + countStatus?: boolean; + isMacCodeBlock?: boolean; + isShowLineNumber?: boolean; + themeMode?: "light" | "dark"; +} + +export interface RendererAPI { + reset: (newOpts: Partial) => void; + setOptions: (newOpts: Partial) => void; + getOpts: () => IOpts; + parseFrontMatterAndContent: (markdown: string) => { + yamlData: Record; + markdownContent: string; + readingTime: ReadTimeResults; + }; + buildReadingTime: (reading: ReadTimeResults) => string; + buildFootnotes: () => string; + buildAddition: () => string; + createContainer: (html: string) => string; +} + +export interface ParseResult { + yamlData: Record; + markdownContent: string; + readingTime: ReadTimeResults; +} + +export interface CliOptions { + inputPath: string; + theme: ThemeName; + keepTitle: boolean; + primaryColor?: string; + fontFamily?: string; + fontSize?: string; + codeTheme: string; + isMacCodeBlock: boolean; + isShowLineNumber: boolean; + citeStatus: boolean; + countStatus: boolean; + legend: string; +} + +export interface ExtendConfig { + default_theme: string | null; + default_color: string | null; + default_font_family: string | null; + default_font_size: string | null; + default_code_theme: string | null; + mac_code_block: boolean | null; + show_line_number: boolean | null; + cite: boolean | null; + count: boolean | null; + legend: string | null; + keep_title: boolean | null; +} + +export interface HtmlDocumentMeta { + title: string; + author?: string; + description?: string; +} diff --git a/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/utils/languages.ts b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/utils/languages.ts new file mode 100644 index 0000000..40905af --- /dev/null +++ b/skills/baoyu-post-to-wechat/scripts/vendor/baoyu-md/src/utils/languages.ts @@ -0,0 +1,238 @@ +import type { LanguageFn } from 'highlight.js' +import bash from 'highlight.js/lib/languages/bash' +import c from 'highlight.js/lib/languages/c' +import cpp from 'highlight.js/lib/languages/cpp' +import csharp from 'highlight.js/lib/languages/csharp' +import css from 'highlight.js/lib/languages/css' +import diff from 'highlight.js/lib/languages/diff' +import go from 'highlight.js/lib/languages/go' +import graphql from 'highlight.js/lib/languages/graphql' +import ini from 'highlight.js/lib/languages/ini' +import java from 'highlight.js/lib/languages/java' +import javascript from 'highlight.js/lib/languages/javascript' +import json from 'highlight.js/lib/languages/json' +import kotlin from 'highlight.js/lib/languages/kotlin' +import less from 'highlight.js/lib/languages/less' +import lua from 'highlight.js/lib/languages/lua' +import makefile from 'highlight.js/lib/languages/makefile' +import markdown from 'highlight.js/lib/languages/markdown' +import objectivec from 'highlight.js/lib/languages/objectivec' +import perl from 'highlight.js/lib/languages/perl' +import php from 'highlight.js/lib/languages/php' +import phpTemplate from 'highlight.js/lib/languages/php-template' +import plaintext from 'highlight.js/lib/languages/plaintext' +import python from 'highlight.js/lib/languages/python' +import pythonRepl from 'highlight.js/lib/languages/python-repl' +import r from 'highlight.js/lib/languages/r' +import ruby from 'highlight.js/lib/languages/ruby' +import rust from 'highlight.js/lib/languages/rust' +import scss from 'highlight.js/lib/languages/scss' +import shell from 'highlight.js/lib/languages/shell' +import sql from 'highlight.js/lib/languages/sql' +import swift from 'highlight.js/lib/languages/swift' +import typescript from 'highlight.js/lib/languages/typescript' +import vbnet from 'highlight.js/lib/languages/vbnet' +import wasm from 'highlight.js/lib/languages/wasm' +import xml from 'highlight.js/lib/languages/xml' +import yaml from 'highlight.js/lib/languages/yaml' + +export const COMMON_LANGUAGES: Record = { + bash, + c, + cpp, + csharp, + css, + diff, + go, + graphql, + ini, + java, + javascript, + json, + kotlin, + less, + lua, + makefile, + markdown, + objectivec, + perl, + php, + 'php-template': phpTemplate, + plaintext, + python, + 'python-repl': pythonRepl, + r, + ruby, + rust, + scss, + shell, + sql, + swift, + typescript, + vbnet, + wasm, + xml, + yaml, +} + +// highlight.js CDN 配置 +const HLJS_VERSION = `11.11.1` +const HLJS_CDN_BASE = `https://cdn-doocs.oss-cn-shenzhen.aliyuncs.com/npm/highlightjs/${HLJS_VERSION}` + +// 缓存正在加载的语言 +const loadingLanguages = new Map>() + +/** + * 生成语言包的 CDN URL + */ +function grammarUrlFor(language: string): string { + return `${HLJS_CDN_BASE}/es/languages/${language}.min.js` +} + +/** + * 动态加载并注册语言 + * @param language 语言名称 + * @param hljs highlight.js 实例 + */ +export async function loadAndRegisterLanguage(language: string, hljs: any): Promise { + // 如果已经注册,直接返回 + if (hljs.getLanguage(language)) { + return + } + + // 如果正在加载,等待加载完成 + if (loadingLanguages.has(language)) { + await loadingLanguages.get(language) + return + } + + // 开始加载 + const loadPromise = (async () => { + try { + const module = await import(/* @vite-ignore */ grammarUrlFor(language)) + hljs.registerLanguage(language, module.default) + } + catch (error) { + console.warn(`Failed to load language: ${language}`, error) + throw error + } + finally { + loadingLanguages.delete(language) + } + })() + + loadingLanguages.set(language, loadPromise) + await loadPromise +} + +/** + * 格式化高亮后的代码,处理空格和制表符 + */ +function formatHighlightedCode(html: string, preserveNewlines = false): string { + let formatted = html + // 将 span 之间的空格移到 span 内部 + formatted = formatted.replace(/(]*>[^<]*<\/span>)(\s+)(]*>[^<]*<\/span>)/g, (_: string, span1: string, spaces: string, span2: string) => span1 + span2.replace(/^(]*>)/, `$1${spaces}`)) + formatted = formatted.replace(/(\s+)(]*>)/g, (_: string, spaces: string, span: string) => span.replace(/^(]*>)/, `$1${spaces}`)) + // 替换制表符为4个空格 + formatted = formatted.replace(/\t/g, ` `) + + if (preserveNewlines) { + // 替换换行符为
,并将空格转换为   + formatted = formatted.replace(/\r\n/g, `
`).replace(/\n/g, `
`).replace(/(>[^<]+)|(^[^<]+)/g, (str: string) => str.replace(/\s/g, ` `)) + } + else { + // 只将空格转换为   + formatted = formatted.replace(/(>[^<]+)|(^[^<]+)/g, (str: string) => str.replace(/\s/g, ` `)) + } + + return formatted +} + +/** + * 高亮代码并格式化(支持行号) + * @param text 原始代码文本 + * @param language 语言名称 + * @param hljs highlight.js 实例 + * @param showLineNumber 是否显示行号 + * @returns 格式化后的 HTML + */ +export function highlightAndFormatCode(text: string, language: string, hljs: any, showLineNumber: boolean): string { + let highlighted = `` + + if (showLineNumber) { + const rawLines = text.replace(/\r\n/g, `\n`).split(`\n`) + + const highlightedLines = rawLines.map((lineRaw) => { + const lineHtml = hljs.highlight(lineRaw, { language }).value + const formatted = formatHighlightedCode(lineHtml, false) + return formatted === `` ? ` ` : formatted + }) + + const lineNumbersHtml = highlightedLines.map((_, idx) => `

${idx + 1}
`).join(``) + const codeInnerHtml = highlightedLines.join(`
`) + const codeLinesHtml = `
${codeInnerHtml}
` + const lineNumberColumnStyles = `text-align:right;padding:8px 0;border-right:1px solid rgba(0,0,0,0.04);user-select:none;background:var(--code-bg,transparent);` + + highlighted = ` +
+
${lineNumbersHtml}
+
${codeLinesHtml}
+
+ ` + } + else { + const rawHighlighted = hljs.highlight(text, { language }).value + highlighted = formatHighlightedCode(rawHighlighted, true) + } + + return highlighted +} + +export function highlightCodeBlock(codeBlock: Element, language: string, hljs: any): void { + const rawCode = codeBlock.getAttribute(`data-raw-code`) + const showLineNumber = codeBlock.getAttribute(`data-show-line-number`) === `true` + + if (!rawCode) + return + + const text = rawCode.replace(/"/g, `"`) + + const highlighted = highlightAndFormatCode(text, language, hljs, showLineNumber) + + codeBlock.innerHTML = highlighted + codeBlock.removeAttribute(`data-language-pending`) + codeBlock.removeAttribute(`data-raw-code`) + codeBlock.removeAttribute(`data-show-line-number`) +} + +/** + * 高亮 DOM 中待处理的代码块 + * 查找带有 data-language-pending 属性的代码块,动态加载语言后重新高亮 + * @param hljs highlight.js 实例 + * @param container 容器元素(可选,默认为 document) + */ +export function highlightPendingBlocks(hljs: any, container: Document | Element = document): void { + const pendingBlocks = container.querySelectorAll(`code[data-language-pending]`) + + pendingBlocks.forEach((codeBlock) => { + const language = codeBlock.getAttribute(`data-language-pending`) + if (!language) + return + + if (hljs.getLanguage(language)) { + // 语言已加载,直接高亮 + highlightCodeBlock(codeBlock, language, hljs) + } + else { + // 动态加载语言后重新高亮 + loadAndRegisterLanguage(language, hljs).then(() => { + highlightCodeBlock(codeBlock, language, hljs) + }).catch(() => { + // 加载失败,移除标记 + codeBlock.removeAttribute(`data-language-pending`) + codeBlock.removeAttribute(`data-raw-code`) + codeBlock.removeAttribute(`data-show-line-number`) + }) + } + }) +} diff --git a/skills/baoyu-post-to-weibo/scripts/bun.lock b/skills/baoyu-post-to-weibo/scripts/bun.lock index 00e2fa8..b5e4728 100644 --- a/skills/baoyu-post-to-weibo/scripts/bun.lock +++ b/skills/baoyu-post-to-weibo/scripts/bun.lock @@ -5,27 +5,205 @@ "name": "baoyu-post-to-weibo-scripts", "dependencies": { "baoyu-chrome-cdp": "file:./vendor/baoyu-chrome-cdp", - "front-matter": "^4.0.2", - "highlight.js": "^11.11.1", - "marked": "^15.0.6", + "baoyu-md": "file:./vendor/baoyu-md", }, }, }, "packages": { + "@types/debug": ["@types/debug@4.1.12", "", { "dependencies": { "@types/ms": "*" } }, "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ=="], + + "@types/mdast": ["@types/mdast@4.0.4", "", { "dependencies": { "@types/unist": "*" } }, "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA=="], + + "@types/ms": ["@types/ms@2.1.0", "", {}, "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA=="], + + "@types/unist": ["@types/unist@3.0.3", "", {}, "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="], + + "ansi-colors": ["ansi-colors@4.1.3", "", {}, "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw=="], + "argparse": ["argparse@1.0.10", "", { "dependencies": { "sprintf-js": "~1.0.2" } }, "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg=="], + "bail": ["bail@2.0.2", "", {}, "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw=="], + "baoyu-chrome-cdp": ["baoyu-chrome-cdp@file:vendor/baoyu-chrome-cdp", {}], + "baoyu-md": ["baoyu-md@file:vendor/baoyu-md", { "dependencies": { "fflate": "^0.8.2", "front-matter": "^4.0.2", "highlight.js": "^11.11.1", "juice": "^11.0.1", "marked": "^15.0.6", "reading-time": "^1.5.0", "remark-cjk-friendly": "^1.1.0", "remark-parse": "^11.0.0", "remark-stringify": "^11.0.0", "unified": "^11.0.5" } }], + + "boolbase": ["boolbase@1.0.0", "", {}, "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="], + + "character-entities": ["character-entities@2.0.2", "", {}, "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ=="], + + "cheerio": ["cheerio@1.0.0", "", { "dependencies": { "cheerio-select": "^2.1.0", "dom-serializer": "^2.0.0", "domhandler": "^5.0.3", "domutils": "^3.1.0", "encoding-sniffer": "^0.2.0", "htmlparser2": "^9.1.0", "parse5": "^7.1.2", "parse5-htmlparser2-tree-adapter": "^7.0.0", "parse5-parser-stream": "^7.1.2", "undici": "^6.19.5", "whatwg-mimetype": "^4.0.0" } }, "sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww=="], + + "cheerio-select": ["cheerio-select@2.1.0", "", { "dependencies": { "boolbase": "^1.0.0", "css-select": "^5.1.0", "css-what": "^6.1.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.3", "domutils": "^3.0.1" } }, "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g=="], + + "commander": ["commander@12.1.0", "", {}, "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA=="], + + "css-select": ["css-select@5.2.2", "", { "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.1.0", "domhandler": "^5.0.2", "domutils": "^3.0.1", "nth-check": "^2.0.1" } }, "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw=="], + + "css-what": ["css-what@6.2.2", "", {}, "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA=="], + + "debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], + + "decode-named-character-reference": ["decode-named-character-reference@1.3.0", "", { "dependencies": { "character-entities": "^2.0.0" } }, "sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q=="], + + "dequal": ["dequal@2.0.3", "", {}, "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA=="], + + "devlop": ["devlop@1.1.0", "", { "dependencies": { "dequal": "^2.0.0" } }, "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA=="], + + "dom-serializer": ["dom-serializer@2.0.0", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", "entities": "^4.2.0" } }, "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg=="], + + "domelementtype": ["domelementtype@2.3.0", "", {}, "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw=="], + + "domhandler": ["domhandler@5.0.3", "", { "dependencies": { "domelementtype": "^2.3.0" } }, "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w=="], + + "domutils": ["domutils@3.2.2", "", { "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.3" } }, "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw=="], + + "encoding-sniffer": ["encoding-sniffer@0.2.1", "", { "dependencies": { "iconv-lite": "^0.6.3", "whatwg-encoding": "^3.1.1" } }, "sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw=="], + + "entities": ["entities@7.0.1", "", {}, "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA=="], + + "escape-goat": ["escape-goat@3.0.0", "", {}, "sha512-w3PwNZJwRxlp47QGzhuEBldEqVHHhh8/tIPcl6ecf2Bou99cdAt0knihBV0Ecc7CGxYduXVBDheH1K2oADRlvw=="], + "esprima": ["esprima@4.0.1", "", { "bin": { "esparse": "./bin/esparse.js", "esvalidate": "./bin/esvalidate.js" } }, "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="], + "extend": ["extend@3.0.2", "", {}, "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="], + + "fflate": ["fflate@0.8.2", "", {}, "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A=="], + "front-matter": ["front-matter@4.0.2", "", { "dependencies": { "js-yaml": "^3.13.1" } }, "sha512-I8ZuJ/qG92NWX8i5x1Y8qyj3vizhXS31OxjKDu3LKP+7/qBgfIKValiZIEwoVoJKUHlhWtYrktkxV1XsX+pPlg=="], + "get-east-asian-width": ["get-east-asian-width@1.5.0", "", {}, "sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA=="], + "highlight.js": ["highlight.js@11.11.1", "", {}, "sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w=="], + "htmlparser2": ["htmlparser2@9.1.0", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.3", "domutils": "^3.1.0", "entities": "^4.5.0" } }, "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ=="], + + "iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="], + + "is-plain-obj": ["is-plain-obj@4.1.0", "", {}, "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg=="], + "js-yaml": ["js-yaml@3.14.2", "", { "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg=="], + "juice": ["juice@11.1.1", "", { "dependencies": { "cheerio": "1.0.0", "commander": "^12.1.0", "entities": "^7.0.0", "mensch": "^0.3.4", "slick": "^1.12.2", "web-resource-inliner": "^8.0.0" }, "bin": { "juice": "bin/juice" } }, "sha512-4SBfZqKcc6DrIS+5b/WiGoWaZsdUPBH+e6SbRlNjJpaIRtfoBhYReAtobIEW6mcLeFFDXLBJMuZwkJLkBJjs2w=="], + + "longest-streak": ["longest-streak@3.1.0", "", {}, "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g=="], + "marked": ["marked@15.0.12", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-8dD6FusOQSrpv9Z1rdNMdlSgQOIP880DHqnohobOmYLElGEqAL/JvxvuxZO16r4HtjTlfPRDC1hbvxC9dPN2nA=="], + "mdast-util-from-markdown": ["mdast-util-from-markdown@2.0.3", "", { "dependencies": { "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", "decode-named-character-reference": "^1.0.0", "devlop": "^1.0.0", "mdast-util-to-string": "^4.0.0", "micromark": "^4.0.0", "micromark-util-decode-numeric-character-reference": "^2.0.0", "micromark-util-decode-string": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q=="], + + "mdast-util-phrasing": ["mdast-util-phrasing@4.1.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "unist-util-is": "^6.0.0" } }, "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w=="], + + "mdast-util-to-markdown": ["mdast-util-to-markdown@2.1.2", "", { "dependencies": { "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", "longest-streak": "^3.0.0", "mdast-util-phrasing": "^4.0.0", "mdast-util-to-string": "^4.0.0", "micromark-util-classify-character": "^2.0.0", "micromark-util-decode-string": "^2.0.0", "unist-util-visit": "^5.0.0", "zwitch": "^2.0.0" } }, "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA=="], + + "mdast-util-to-string": ["mdast-util-to-string@4.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0" } }, "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg=="], + + "mensch": ["mensch@0.3.4", "", {}, "sha512-IAeFvcOnV9V0Yk+bFhYR07O3yNina9ANIN5MoXBKYJ/RLYPurd2d0yw14MDhpr9/momp0WofT1bPUh3hkzdi/g=="], + + "micromark": ["micromark@4.0.2", "", { "dependencies": { "@types/debug": "^4.0.0", "debug": "^4.0.0", "decode-named-character-reference": "^1.0.0", "devlop": "^1.0.0", "micromark-core-commonmark": "^2.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-chunked": "^2.0.0", "micromark-util-combine-extensions": "^2.0.0", "micromark-util-decode-numeric-character-reference": "^2.0.0", "micromark-util-encode": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-resolve-all": "^2.0.0", "micromark-util-sanitize-uri": "^2.0.0", "micromark-util-subtokenize": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA=="], + + "micromark-core-commonmark": ["micromark-core-commonmark@2.0.3", "", { "dependencies": { "decode-named-character-reference": "^1.0.0", "devlop": "^1.0.0", "micromark-factory-destination": "^2.0.0", "micromark-factory-label": "^2.0.0", "micromark-factory-space": "^2.0.0", "micromark-factory-title": "^2.0.0", "micromark-factory-whitespace": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-chunked": "^2.0.0", "micromark-util-classify-character": "^2.0.0", "micromark-util-html-tag-name": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-resolve-all": "^2.0.0", "micromark-util-subtokenize": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg=="], + + "micromark-extension-cjk-friendly": ["micromark-extension-cjk-friendly@1.2.3", "", { "dependencies": { "devlop": "^1.1.0", "micromark-extension-cjk-friendly-util": "2.1.1", "micromark-util-chunked": "^2.0.1", "micromark-util-resolve-all": "^2.0.1", "micromark-util-symbol": "^2.0.1" }, "peerDependencies": { "micromark": "^4.0.0", "micromark-util-types": "^2.0.0" }, "optionalPeers": ["micromark-util-types"] }, "sha512-gRzVLUdjXBLX6zNPSnHGDoo+ZTp5zy+MZm0g3sv+3chPXY7l9gW+DnrcHcZh/jiPR6MjPKO4AEJNp4Aw6V9z5Q=="], + + "micromark-extension-cjk-friendly-util": ["micromark-extension-cjk-friendly-util@2.1.1", "", { "dependencies": { "get-east-asian-width": "^1.3.0", "micromark-util-character": "^2.1.1", "micromark-util-symbol": "^2.0.1" } }, "sha512-egs6+12JU2yutskHY55FyR48ZiEcFOJFyk9rsiyIhcJ6IvWB6ABBqVrBw8IobqJTDZ/wdSr9eoXDPb5S2nW1bg=="], + + "micromark-factory-destination": ["micromark-factory-destination@2.0.1", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA=="], + + "micromark-factory-label": ["micromark-factory-label@2.0.1", "", { "dependencies": { "devlop": "^1.0.0", "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg=="], + + "micromark-factory-space": ["micromark-factory-space@2.0.1", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg=="], + + "micromark-factory-title": ["micromark-factory-title@2.0.1", "", { "dependencies": { "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw=="], + + "micromark-factory-whitespace": ["micromark-factory-whitespace@2.0.1", "", { "dependencies": { "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ=="], + + "micromark-util-character": ["micromark-util-character@2.1.1", "", { "dependencies": { "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q=="], + + "micromark-util-chunked": ["micromark-util-chunked@2.0.1", "", { "dependencies": { "micromark-util-symbol": "^2.0.0" } }, "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA=="], + + "micromark-util-classify-character": ["micromark-util-classify-character@2.0.1", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q=="], + + "micromark-util-combine-extensions": ["micromark-util-combine-extensions@2.0.1", "", { "dependencies": { "micromark-util-chunked": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg=="], + + "micromark-util-decode-numeric-character-reference": ["micromark-util-decode-numeric-character-reference@2.0.2", "", { "dependencies": { "micromark-util-symbol": "^2.0.0" } }, "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw=="], + + "micromark-util-decode-string": ["micromark-util-decode-string@2.0.1", "", { "dependencies": { "decode-named-character-reference": "^1.0.0", "micromark-util-character": "^2.0.0", "micromark-util-decode-numeric-character-reference": "^2.0.0", "micromark-util-symbol": "^2.0.0" } }, "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ=="], + + "micromark-util-encode": ["micromark-util-encode@2.0.1", "", {}, "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw=="], + + "micromark-util-html-tag-name": ["micromark-util-html-tag-name@2.0.1", "", {}, "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA=="], + + "micromark-util-normalize-identifier": ["micromark-util-normalize-identifier@2.0.1", "", { "dependencies": { "micromark-util-symbol": "^2.0.0" } }, "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q=="], + + "micromark-util-resolve-all": ["micromark-util-resolve-all@2.0.1", "", { "dependencies": { "micromark-util-types": "^2.0.0" } }, "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg=="], + + "micromark-util-sanitize-uri": ["micromark-util-sanitize-uri@2.0.1", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-encode": "^2.0.0", "micromark-util-symbol": "^2.0.0" } }, "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ=="], + + "micromark-util-subtokenize": ["micromark-util-subtokenize@2.1.0", "", { "dependencies": { "devlop": "^1.0.0", "micromark-util-chunked": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA=="], + + "micromark-util-symbol": ["micromark-util-symbol@2.0.1", "", {}, "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q=="], + + "micromark-util-types": ["micromark-util-types@2.0.2", "", {}, "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA=="], + + "mime": ["mime@2.6.0", "", { "bin": { "mime": "cli.js" } }, "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg=="], + + "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], + + "nth-check": ["nth-check@2.1.1", "", { "dependencies": { "boolbase": "^1.0.0" } }, "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w=="], + + "parse5": ["parse5@7.3.0", "", { "dependencies": { "entities": "^6.0.0" } }, "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw=="], + + "parse5-htmlparser2-tree-adapter": ["parse5-htmlparser2-tree-adapter@7.1.0", "", { "dependencies": { "domhandler": "^5.0.3", "parse5": "^7.0.0" } }, "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g=="], + + "parse5-parser-stream": ["parse5-parser-stream@7.1.2", "", { "dependencies": { "parse5": "^7.0.0" } }, "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow=="], + + "reading-time": ["reading-time@1.5.0", "", {}, "sha512-onYyVhBNr4CmAxFsKS7bz+uTLRakypIe4R+5A824vBSkQy/hB3fZepoVEf8OVAxzLvK+H/jm9TzpI3ETSm64Kg=="], + + "remark-cjk-friendly": ["remark-cjk-friendly@1.2.3", "", { "dependencies": { "micromark-extension-cjk-friendly": "1.2.3" }, "peerDependencies": { "@types/mdast": "^4.0.0", "unified": "^11.0.0" }, "optionalPeers": ["@types/mdast"] }, "sha512-UvAgxwlNk+l9Oqgl/9MWK2eWRS7zgBW/nXX9AthV7nd/3lNejF138E7Xbmk9Zs4WjTJGs721r7fAEc7tNFoH7g=="], + + "remark-parse": ["remark-parse@11.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-from-markdown": "^2.0.0", "micromark-util-types": "^2.0.0", "unified": "^11.0.0" } }, "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA=="], + + "remark-stringify": ["remark-stringify@11.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-to-markdown": "^2.0.0", "unified": "^11.0.0" } }, "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw=="], + + "safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="], + + "slick": ["slick@1.12.2", "", {}, "sha512-4qdtOGcBjral6YIBCWJ0ljFSKNLz9KkhbWtuGvUyRowl1kxfuE1x/Z/aJcaiilpb3do9bl5K7/1h9XC5wWpY/A=="], + "sprintf-js": ["sprintf-js@1.0.3", "", {}, "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g=="], + + "trough": ["trough@2.2.0", "", {}, "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw=="], + + "undici": ["undici@6.24.0", "", {}, "sha512-lVLNosgqo5EkGqh5XUDhGfsMSoO8K0BAN0TyJLvwNRSl4xWGZlCVYsAIpa/OpA3TvmnM01GWcoKmc3ZWo5wKKA=="], + + "unified": ["unified@11.0.5", "", { "dependencies": { "@types/unist": "^3.0.0", "bail": "^2.0.0", "devlop": "^1.0.0", "extend": "^3.0.0", "is-plain-obj": "^4.0.0", "trough": "^2.0.0", "vfile": "^6.0.0" } }, "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA=="], + + "unist-util-is": ["unist-util-is@6.0.1", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g=="], + + "unist-util-stringify-position": ["unist-util-stringify-position@4.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ=="], + + "unist-util-visit": ["unist-util-visit@5.1.0", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0", "unist-util-visit-parents": "^6.0.0" } }, "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg=="], + + "unist-util-visit-parents": ["unist-util-visit-parents@6.0.2", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0" } }, "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ=="], + + "valid-data-url": ["valid-data-url@3.0.1", "", {}, "sha512-jOWVmzVceKlVVdwjNSenT4PbGghU0SBIizAev8ofZVgivk/TVHXSbNL8LP6M3spZvkR9/QolkyJavGSX5Cs0UA=="], + + "vfile": ["vfile@6.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "vfile-message": "^4.0.0" } }, "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q=="], + + "vfile-message": ["vfile-message@4.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw=="], + + "web-resource-inliner": ["web-resource-inliner@8.0.0", "", { "dependencies": { "ansi-colors": "^4.1.1", "escape-goat": "^3.0.0", "htmlparser2": "^9.1.0", "mime": "^2.4.6", "valid-data-url": "^3.0.0" } }, "sha512-Ezr98sqXW/+OCGoUEXuOKVR+oVFlSdn1tIySEEJdiSAw4IjrW8hQkwARSSBJTSB5Us5dnytDgL0ZDliAYBhaNA=="], + + "whatwg-encoding": ["whatwg-encoding@3.1.1", "", { "dependencies": { "iconv-lite": "0.6.3" } }, "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ=="], + + "whatwg-mimetype": ["whatwg-mimetype@4.0.0", "", {}, "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg=="], + + "zwitch": ["zwitch@2.0.4", "", {}, "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A=="], + + "dom-serializer/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="], + + "htmlparser2/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="], + + "parse5/entities": ["entities@6.0.1", "", {}, "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="], } } diff --git a/skills/baoyu-post-to-weibo/scripts/md-to-html.ts b/skills/baoyu-post-to-weibo/scripts/md-to-html.ts index 216990b..8c26033 100644 --- a/skills/baoyu-post-to-weibo/scripts/md-to-html.ts +++ b/skills/baoyu-post-to-weibo/scripts/md-to-html.ts @@ -1,21 +1,26 @@ -import fs from 'node:fs'; -import { mkdir, writeFile } from 'node:fs/promises'; -import https from 'node:https'; -import os from 'node:os'; -import path from 'node:path'; -import process from 'node:process'; -import { createHash } from 'node:crypto'; +import fs from "node:fs"; +import os from "node:os"; +import path from "node:path"; +import process from "node:process"; -import frontMatter from 'front-matter'; -import hljs from 'highlight.js/lib/common'; -import { Lexer, Marked, type RendererObject, type Tokens } from 'marked'; +import { + extractSummaryFromBody, + extractTitleFromMarkdown, + parseFrontmatter, + pickFirstString, + renderMarkdownDocument, + replaceMarkdownImagesWithPlaceholders, + resolveColorToken, + resolveContentImages, + resolveImagePath, + serializeFrontmatter, + stripWrappingQuotes, +} from "baoyu-md"; interface ImageInfo { placeholder: string; localPath: string; originalPath: string; - alt: string; - blockIndex: number; } interface ParsedMarkdown { @@ -25,350 +30,63 @@ interface ParsedMarkdown { coverImage: string | null; contentImages: ImageInfo[]; html: string; - totalBlocks: number; -} - -type FrontmatterFields = Record; - -function parseFrontmatter(content: string): { frontmatter: FrontmatterFields; body: string } { - try { - const parsed = frontMatter(content); - return { - frontmatter: parsed.attributes ?? {}, - body: parsed.body, - }; - } catch { - return { frontmatter: {}, body: content }; - } -} - -function stripWrappingQuotes(value: string): string { - if (!value) return value; - const doubleQuoted = value.startsWith('"') && value.endsWith('"'); - const singleQuoted = value.startsWith("'") && value.endsWith("'"); - const cjkDoubleQuoted = value.startsWith('\u201c') && value.endsWith('\u201d'); - const cjkSingleQuoted = value.startsWith('\u2018') && value.endsWith('\u2019'); - if (doubleQuoted || singleQuoted || cjkDoubleQuoted || cjkSingleQuoted) { - return value.slice(1, -1).trim(); - } - return value.trim(); -} - -function toFrontmatterString(value: unknown): string | undefined { - if (typeof value === 'string') { - return stripWrappingQuotes(value); - } - if (typeof value === 'number' || typeof value === 'boolean') { - return String(value); - } - return undefined; -} - -function pickFirstString(frontmatter: FrontmatterFields, keys: string[]): string | undefined { - for (const key of keys) { - const value = toFrontmatterString(frontmatter[key]); - if (value) return value; - } - return undefined; -} - -function extractTitleFromMarkdown(markdown: string): string { - const tokens = Lexer.lex(markdown, { gfm: true, breaks: true }); - for (const token of tokens) { - if (token.type === 'heading' && token.depth === 1) { - return stripWrappingQuotes(token.text); - } - } - return ''; -} - -function extractSummaryFromBody(body: string, maxLen: number): string { - const lines = body.split('\n').filter(l => l.trim() && !l.startsWith('#') && !l.startsWith('!') && !l.startsWith('```')); - const firstParagraph = lines[0]?.replace(/[*_`\[\]()]/g, '').trim() || ''; - if (firstParagraph.length <= maxLen) return firstParagraph; - return firstParagraph.slice(0, maxLen - 1) + '\u2026'; -} - -function downloadFile(url: string, destPath: string, maxRedirects = 5): Promise { - return new Promise((resolve, reject) => { - if (!url.startsWith('https://')) { - reject(new Error(`Refusing non-HTTPS download: ${url}`)); - return; - } - if (maxRedirects <= 0) { - reject(new Error('Too many redirects')); - return; - } - const file = fs.createWriteStream(destPath); - - const request = https.get(url, { headers: { 'User-Agent': 'Mozilla/5.0' } }, (response) => { - if (response.statusCode === 301 || response.statusCode === 302) { - const redirectUrl = response.headers.location; - if (redirectUrl) { - file.close(); - fs.unlinkSync(destPath); - downloadFile(redirectUrl, destPath, maxRedirects - 1).then(resolve).catch(reject); - return; - } - } - - if (response.statusCode !== 200) { - file.close(); - fs.unlinkSync(destPath); - reject(new Error(`Failed to download: ${response.statusCode}`)); - return; - } - - response.pipe(file); - file.on('finish', () => { - file.close(); - resolve(); - }); - }); - - request.on('error', (err) => { - file.close(); - fs.unlink(destPath, () => {}); - reject(err); - }); - - request.setTimeout(30000, () => { - request.destroy(); - reject(new Error('Download timeout')); - }); - }); -} - -function getImageExtension(urlOrPath: string): string { - const match = urlOrPath.match(/\.(jpg|jpeg|png|gif|webp)(\?|$)/i); - return match ? match[1]!.toLowerCase() : 'png'; -} - -function resolveLocalWithFallback(resolved: string): string { - if (fs.existsSync(resolved)) return resolved; - const ext = path.extname(resolved); - const base = resolved.slice(0, -ext.length); - const alternatives = [ - base + '.webp', - base + '.jpg', - base + '.jpeg', - base + '.png', - base + '.gif', - base + '_original.png', - base + '_original.jpg', - ].filter((p) => p !== resolved); - for (const alt of alternatives) { - if (fs.existsSync(alt)) { - console.error(`[md-to-html] Image fallback: ${path.basename(resolved)} → ${path.basename(alt)}`); - return alt; - } - } - return resolved; -} - -async function resolveImagePath(imagePath: string, baseDir: string, tempDir: string): Promise { - if (imagePath.startsWith('http://')) { - console.error(`[md-to-html] Skipping non-HTTPS image: ${imagePath}`); - return ''; - } - if (imagePath.startsWith('https://')) { - const hash = createHash('md5').update(imagePath).digest('hex').slice(0, 8); - const ext = getImageExtension(imagePath); - const localPath = path.join(tempDir, `remote_${hash}.${ext}`); - - if (!fs.existsSync(localPath)) { - console.error(`[md-to-html] Downloading: ${imagePath}`); - await downloadFile(imagePath, localPath); - } - return localPath; - } - - const resolved = path.isAbsolute(imagePath) ? imagePath : path.resolve(baseDir, imagePath); - return resolveLocalWithFallback(resolved); -} - -function escapeHtml(text: string): string { - return text - .replace(/&/g, '&') - .replace(//g, '>') - .replace(/"/g, '"') - .replace(/'/g, '''); -} - -function highlightCode(code: string, lang: string): string { - try { - if (lang && hljs.getLanguage(lang)) { - return hljs.highlight(code, { language: lang, ignoreIllegals: true }).value; - } - return hljs.highlightAuto(code).value; - } catch { - return escapeHtml(code); - } -} - -const EMPTY_PARAGRAPH = '

'; - -function convertMarkdownToHtml(markdown: string, imageCallback: (src: string, alt: string) => string): { html: string; totalBlocks: number } { - const blockTokens = Lexer.lex(markdown, { gfm: true, breaks: true }); - - const renderer: RendererObject = { - heading({ depth, tokens }: Tokens.Heading): string { - if (depth === 1) { - return ''; - } - return `

${this.parser.parseInline(tokens)}

`; - }, - - paragraph({ tokens }: Tokens.Paragraph): string { - const text = this.parser.parseInline(tokens).trim(); - if (!text) return ''; - return `

${text}

`; - }, - - blockquote({ tokens }: Tokens.Blockquote): string { - return `
${this.parser.parse(tokens)}
`; - }, - - code({ text, lang = '' }: Tokens.Code): string { - const language = lang.split(/\s+/)[0]!.toLowerCase(); - const source = text.replace(/\n$/, ''); - const highlighted = highlightCode(source, language).replace(/\n/g, '
'); - const label = language ? `[${escapeHtml(language)}]
` : ''; - return `
${label}${highlighted}
`; - }, - - image({ href, text }: Tokens.Image): string { - if (!href) return ''; - return imageCallback(href, text ?? ''); - }, - - link({ href, title, tokens, text }: Tokens.Link): string { - const label = tokens?.length ? this.parser.parseInline(tokens) : escapeHtml(text || href || ''); - if (!href) return label; - - const titleAttr = title ? ` title="${escapeHtml(title)}"` : ''; - return `${label}`; - }, - }; - - const parser = new Marked({ - gfm: true, - breaks: true, - }); - parser.use({ renderer }); - - const rendered = parser.parse(markdown); - if (typeof rendered !== 'string') { - throw new Error('Unexpected async markdown parse result'); - } - - const totalBlocks = blockTokens.filter((token) => { - if (token.type === 'space') return false; - if (token.type === 'heading' && token.depth === 1) return false; - return true; - }).length; - - const blocks = rendered - .replace(/(<\/(?:p|h[1-6]|blockquote|ol|ul|hr|pre)>)/gi, '$1\n') - .split('\n') - .filter((l) => l.trim()); - - const spaced: string[] = []; - const nestTags = ['ol', 'ul', 'blockquote']; - let depth = 0; - for (let i = 0; i < blocks.length; i++) { - const block = blocks[i]!; - const opens = (block.match(new RegExp(`<(${nestTags.join('|')})[\\s>]`, 'gi')) || []).length; - const closes = (block.match(new RegExp(``, 'gi')) || []).length; - - spaced.push(block); - depth += opens - closes; - - if (depth <= 0 && i < blocks.length - 1) { - const lastIsEmpty = spaced.length > 0 && spaced[spaced.length - 1] === EMPTY_PARAGRAPH; - if (!lastIsEmpty) { - spaced.push(EMPTY_PARAGRAPH); - } - } - if (depth < 0) depth = 0; - } - - return { - html: spaced.join('\n'), - totalBlocks, - }; } export async function parseMarkdown( markdownPath: string, - options?: { coverImage?: string; title?: string; tempDir?: string }, + options?: { + coverImage?: string; + title?: string; + tempDir?: string; + theme?: string; + color?: string; + citeStatus?: boolean; + }, ): Promise { - const content = fs.readFileSync(markdownPath, 'utf-8'); + const content = fs.readFileSync(markdownPath, "utf-8"); const baseDir = path.dirname(markdownPath); - const tempDir = options?.tempDir ?? path.join(os.tmpdir(), 'weibo-article-images'); - - await mkdir(tempDir, { recursive: true }); + const tempDir = options?.tempDir ?? fs.mkdtempSync(path.join(os.tmpdir(), "weibo-article-images-")); const { frontmatter, body } = parseFrontmatter(content); - let title = stripWrappingQuotes(options?.title ?? '') || pickFirstString(frontmatter, ['title']) || ''; - if (!title) { - title = extractTitleFromMarkdown(body); - } + let title = stripWrappingQuotes(options?.title ?? "") + || stripWrappingQuotes(frontmatter.title ?? "") + || extractTitleFromMarkdown(body); if (!title) { title = path.basename(markdownPath, path.extname(markdownPath)); } - let summary = pickFirstString(frontmatter, ['summary', 'description', 'excerpt']) || ''; - if (!summary) summary = extractSummaryFromBody(body, 44); + let summary = stripWrappingQuotes(frontmatter.summary ?? "") + || stripWrappingQuotes(frontmatter.description ?? "") + || stripWrappingQuotes(frontmatter.excerpt ?? ""); + if (!summary) { + summary = extractSummaryFromBody(body, 44); + } const shortSummary = extractSummaryFromBody(body, 44); - let coverImagePath = stripWrappingQuotes(options?.coverImage ?? '') || pickFirstString(frontmatter, [ - 'featureImage', 'cover_image', 'coverImage', 'cover', 'image', - ]) || null; + const coverImagePath = stripWrappingQuotes(options?.coverImage ?? "") + || pickFirstString(frontmatter, ["featureImage", "cover_image", "coverImage", "cover", "image"]) + || null; - const images: Array<{ src: string; alt: string; blockIndex: number }> = []; - let imageCounter = 0; + const { images, markdown: rewrittenBody } = replaceMarkdownImagesWithPlaceholders( + body, + "WBIMGPH_", + ); + const rewrittenMarkdown = `${serializeFrontmatter(frontmatter)}${rewrittenBody}`; - const { html, totalBlocks } = convertMarkdownToHtml(body, (src, alt) => { - const placeholder = `WBIMGPH_${++imageCounter}`; - images.push({ src, alt, blockIndex: -1 }); - return placeholder; + const { html } = await renderMarkdownDocument(rewrittenMarkdown, { + citeStatus: options?.citeStatus ?? false, + defaultTitle: title, + keepTitle: false, + primaryColor: resolveColorToken(options?.color), + theme: options?.theme, }); - const htmlLines = html.split('\n'); - for (let i = 0; i < images.length; i++) { - const placeholder = `WBIMGPH_${i + 1}`; - for (let lineIndex = 0; lineIndex < htmlLines.length; lineIndex++) { - const regex = new RegExp(`\\b${placeholder}\\b`); - if (regex.test(htmlLines[lineIndex]!)) { - images[i]!.blockIndex = lineIndex; - break; - } - } - } - - const contentImages: ImageInfo[] = []; - - for (let i = 0; i < images.length; i++) { - const img = images[i]!; - const localPath = await resolveImagePath(img.src, baseDir, tempDir); - - contentImages.push({ - placeholder: `WBIMGPH_${i + 1}`, - localPath, - originalPath: img.src, - alt: img.alt, - blockIndex: img.blockIndex, - }); - } - - const finalHtml = html.replace(/\n{3,}/g, '\n\n').trim(); + const contentImages = await resolveContentImages(images, baseDir, tempDir, "md-to-html"); let resolvedCoverImage: string | null = null; if (coverImagePath) { - resolvedCoverImage = await resolveImagePath(coverImagePath, baseDir, tempDir); + resolvedCoverImage = await resolveImagePath(coverImagePath, baseDir, tempDir, "md-to-html"); } return { @@ -377,14 +95,13 @@ export async function parseMarkdown( shortSummary, coverImage: resolvedCoverImage, contentImages, - html: finalHtml, - totalBlocks, + html, }; } async function main(): Promise { const args = process.argv.slice(2); - if (args.length === 0 || args.includes('--help') || args.includes('-h')) { + if (args.length === 0 || args.includes("--help") || args.includes("-h")) { console.log(`Convert Markdown to HTML for Weibo article publishing Usage: @@ -404,51 +121,49 @@ Options: let markdownPath: string | undefined; let title: string | undefined; let coverImage: string | undefined; - let outputFormat: 'json' | 'html' = 'json'; + let outputFormat: "json" | "html" = "json"; let htmlOnly = false; let saveHtmlPath: string | undefined; for (let i = 0; i < args.length; i++) { const arg = args[i]!; - if (arg === '--title' && args[i + 1]) { + if (arg === "--title" && args[i + 1]) { title = args[++i]; - } else if (arg === '--cover' && args[i + 1]) { + } else if (arg === "--cover" && args[i + 1]) { coverImage = args[++i]; - } else if (arg === '--output' && args[i + 1]) { - outputFormat = args[++i] as 'json' | 'html'; - } else if (arg === '--html-only') { + } else if (arg === "--output" && args[i + 1]) { + outputFormat = args[++i] as "json" | "html"; + } else if (arg === "--html-only") { htmlOnly = true; - } else if (arg === '--save-html' && args[i + 1]) { + } else if (arg === "--save-html" && args[i + 1]) { saveHtmlPath = args[++i]; - } else if (!arg.startsWith('-')) { + } else if (!arg.startsWith("-")) { markdownPath = arg; } } if (!markdownPath || !fs.existsSync(markdownPath)) { - console.error('Error: Valid markdown file path required'); + console.error("Error: Valid markdown file path required"); process.exit(1); } const result = await parseMarkdown(markdownPath, { title, coverImage }); if (saveHtmlPath) { - await writeFile(saveHtmlPath, result.html, 'utf-8'); + fs.writeFileSync(saveHtmlPath, result.html, "utf-8"); console.error(`[md-to-html] HTML saved to: ${saveHtmlPath}`); } - if (htmlOnly) { - console.log(result.html); - } else if (outputFormat === 'html') { + if (htmlOnly || outputFormat === "html") { console.log(result.html); } else { console.log(JSON.stringify(result, null, 2)); } } -if (import.meta.main ?? (process.argv[1] && path.resolve(process.argv[1]) === path.resolve(import.meta.filename ?? ''))) { - await main().catch((err) => { - console.error(`Error: ${err instanceof Error ? err.message : String(err)}`); +if (import.meta.main ?? (process.argv[1] && path.resolve(process.argv[1]) === path.resolve(import.meta.filename ?? ""))) { + await main().catch((error) => { + console.error(`Error: ${error instanceof Error ? error.message : String(error)}`); process.exit(1); }); } diff --git a/skills/baoyu-post-to-weibo/scripts/package.json b/skills/baoyu-post-to-weibo/scripts/package.json index 44b0089..9c7b538 100644 --- a/skills/baoyu-post-to-weibo/scripts/package.json +++ b/skills/baoyu-post-to-weibo/scripts/package.json @@ -4,8 +4,6 @@ "type": "module", "dependencies": { "baoyu-chrome-cdp": "file:./vendor/baoyu-chrome-cdp", - "front-matter": "^4.0.2", - "highlight.js": "^11.11.1", - "marked": "^15.0.6" + "baoyu-md": "file:./vendor/baoyu-md" } } diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/package.json b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/package.json new file mode 100644 index 0000000..a6f7086 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/package.json @@ -0,0 +1,21 @@ +{ + "name": "baoyu-md", + "private": true, + "version": "0.1.0", + "type": "module", + "exports": { + ".": "./src/index.ts" + }, + "dependencies": { + "fflate": "^0.8.2", + "front-matter": "^4.0.2", + "highlight.js": "^11.11.1", + "juice": "^11.0.1", + "marked": "^15.0.6", + "reading-time": "^1.5.0", + "remark-cjk-friendly": "^1.1.0", + "remark-parse": "^11.0.0", + "remark-stringify": "^11.0.0", + "unified": "^11.0.5" + } +} diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/LICENSE b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/LICENSE new file mode 100644 index 0000000..245b7fe --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/LICENSE @@ -0,0 +1,18 @@ +This directory contains code adapted from the doocs/md project. + +Original project: https://github.com/doocs/md +License: WTFPL (Do What The Fuck You Want To Public License) + + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + Version 2, December 2004 + + Copyright (C) 2025 Doocs + + Everyone is permitted to copy and distribute verbatim or modified + copies of this license document, and changing it is allowed as long + as the name is changed. + + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. You just DO WHAT THE FUCK YOU WANT TO. diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/cli.ts b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/cli.ts new file mode 100644 index 0000000..5a7861b --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/cli.ts @@ -0,0 +1,163 @@ +import type { CliOptions, ThemeName } from "./types.js"; +import { + FONT_FAMILY_MAP, + FONT_SIZE_OPTIONS, + COLOR_PRESETS, + CODE_BLOCK_THEMES, +} from "./constants.js"; +import { THEME_NAMES } from "./themes.js"; +import { loadExtendConfig } from "./extend-config.js"; + +export function printUsage(): void { + console.error( + [ + "Usage:", + " npx tsx render.ts [options]", + "", + "Options:", + ` --theme Theme (${THEME_NAMES.join(", ")})`, + ` --color Primary color: ${Object.keys(COLOR_PRESETS).join(", ")}, or hex`, + ` --font-family Font: ${Object.keys(FONT_FAMILY_MAP).join(", ")}, or CSS value`, + ` --font-size Font size: ${FONT_SIZE_OPTIONS.join(", ")} (default: 16px)`, + ` --code-theme Code highlight theme (default: github)`, + ` --mac-code-block Show Mac-style code block header`, + ` --line-number Show line numbers in code blocks`, + ` --cite Enable footnote citations`, + ` --count Show reading time / word count`, + ` --legend Image caption: title-alt, alt-title, title, alt, none`, + ` --keep-title Keep the first heading in output`, + ].join("\n") + ); +} + +function parseArgValue(argv: string[], i: number, flag: string): string | null { + const arg = argv[i]!; + if (arg.includes("=")) { + return arg.slice(flag.length + 1); + } + const next = argv[i + 1]; + return next ?? null; +} + +function resolveFontFamily(value: string): string { + return FONT_FAMILY_MAP[value] ?? value; +} + +function resolveColor(value: string): string { + return COLOR_PRESETS[value] ?? value; +} + +export function parseArgs(argv: string[]): CliOptions | null { + const ext = loadExtendConfig(); + + let inputPath = ""; + let theme: ThemeName = ext.default_theme ?? "default"; + let keepTitle = ext.keep_title ?? false; + let primaryColor: string | undefined = ext.default_color ? resolveColor(ext.default_color) : undefined; + let fontFamily: string | undefined = ext.default_font_family ? resolveFontFamily(ext.default_font_family) : undefined; + let fontSize: string | undefined = ext.default_font_size ?? undefined; + let codeTheme = ext.default_code_theme ?? "github"; + let isMacCodeBlock = ext.mac_code_block ?? true; + let isShowLineNumber = ext.show_line_number ?? false; + let citeStatus = ext.cite ?? false; + let countStatus = ext.count ?? false; + let legend = ext.legend ?? "alt"; + + for (let i = 0; i < argv.length; i += 1) { + const arg = argv[i]!; + + if (!arg.startsWith("--") && !inputPath) { + inputPath = arg; + continue; + } + + if (arg === "--help" || arg === "-h") { + return null; + } + + if (arg === "--keep-title") { keepTitle = true; continue; } + if (arg === "--mac-code-block") { isMacCodeBlock = true; continue; } + if (arg === "--no-mac-code-block") { isMacCodeBlock = false; continue; } + if (arg === "--line-number") { isShowLineNumber = true; continue; } + if (arg === "--cite") { citeStatus = true; continue; } + if (arg === "--count") { countStatus = true; continue; } + + if (arg === "--theme" || arg.startsWith("--theme=")) { + const val = parseArgValue(argv, i, "--theme"); + if (!val) { console.error("Missing value for --theme"); return null; } + theme = val as ThemeName; + if (!arg.includes("=")) i += 1; + continue; + } + + if (arg === "--color" || arg.startsWith("--color=")) { + const val = parseArgValue(argv, i, "--color"); + if (!val) { console.error("Missing value for --color"); return null; } + primaryColor = resolveColor(val); + if (!arg.includes("=")) i += 1; + continue; + } + + if (arg === "--font-family" || arg.startsWith("--font-family=")) { + const val = parseArgValue(argv, i, "--font-family"); + if (!val) { console.error("Missing value for --font-family"); return null; } + fontFamily = resolveFontFamily(val); + if (!arg.includes("=")) i += 1; + continue; + } + + if (arg === "--font-size" || arg.startsWith("--font-size=")) { + const val = parseArgValue(argv, i, "--font-size"); + if (!val) { console.error("Missing value for --font-size"); return null; } + fontSize = val.endsWith("px") ? val : `${val}px`; + if (!FONT_SIZE_OPTIONS.includes(fontSize)) { + console.error(`Invalid font size: ${fontSize}. Valid: ${FONT_SIZE_OPTIONS.join(", ")}`); + return null; + } + if (!arg.includes("=")) i += 1; + continue; + } + + if (arg === "--code-theme" || arg.startsWith("--code-theme=")) { + const val = parseArgValue(argv, i, "--code-theme"); + if (!val) { console.error("Missing value for --code-theme"); return null; } + codeTheme = val; + if (!CODE_BLOCK_THEMES.includes(codeTheme)) { + console.error(`Unknown code theme: ${codeTheme}`); + return null; + } + if (!arg.includes("=")) i += 1; + continue; + } + + if (arg === "--legend" || arg.startsWith("--legend=")) { + const val = parseArgValue(argv, i, "--legend"); + if (!val) { console.error("Missing value for --legend"); return null; } + const valid = ["title-alt", "alt-title", "title", "alt", "none"]; + if (!valid.includes(val)) { + console.error(`Invalid legend: ${val}. Valid: ${valid.join(", ")}`); + return null; + } + legend = val; + if (!arg.includes("=")) i += 1; + continue; + } + + console.error(`Unknown argument: ${arg}`); + return null; + } + + if (!inputPath) { + return null; + } + + if (!THEME_NAMES.includes(theme)) { + console.error(`Unknown theme: ${theme}`); + return null; + } + + return { + inputPath, theme, keepTitle, primaryColor, fontFamily, fontSize, + codeTheme, isMacCodeBlock, isShowLineNumber, citeStatus, countStatus, legend, + }; +} diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/1c-light.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/1c-light.min.css new file mode 100644 index 0000000..a9d9bf9 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/1c-light.min.css @@ -0,0 +1,9 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*! + Theme: 1c-light + Description: Style IDE 1C:Enterprise 8 + Author: (c) Barilko Vitaliy + Maintainer: @Diversus23 + Website: https://softonit.ru/ + License: see project LICENSE + Touched: 2023 +*/.hljs{color:#00f;background:#fff}.hljs-comment{color:green}.hljs-tag{color:#444a}.hljs-tag .hljs-attr,.hljs-tag .hljs-name{color:#444}.hljs-attribute,.hljs-doctag,.hljs-function,.hljs-keyword,.hljs-name,.hljs-punctuation,.hljs-selector-tag{color:red}.hljs-params,.hljs-type{color:#00f}.hljs-deletion,.hljs-number,.hljs-quote,.hljs-selector-class,.hljs-selector-id,.hljs-string,.hljs-symbol,.hljs-template-tag{color:#000}.hljs-section,.hljs-title{color:#00f}.hljs-link,.hljs-operator,.hljs-regexp,.hljs-selector-attr,.hljs-selector-pseudo,.hljs-template-variable,.hljs-variable{color:#ab5656}.hljs-literal{color:red}.hljs-addition,.hljs-built_in,.hljs-bullet,.hljs-code{color:#00f}.hljs-meta,.hljs-meta .hljs-keyword,.hljs-meta .hljs-string{color:#963200}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/a11y-dark.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/a11y-dark.min.css new file mode 100644 index 0000000..7820d7d --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/a11y-dark.min.css @@ -0,0 +1,7 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*! + Theme: a11y-dark + Author: @ericwbailey + Maintainer: @ericwbailey + + Based on the Tomorrow Night Eighties theme: https://github.com/isagalaev/highlight.js/blob/master/src/styles/tomorrow-night-eighties.css +*/.hljs{background:#2b2b2b;color:#f8f8f2}.hljs-comment,.hljs-quote{color:#d4d0ab}.hljs-deletion,.hljs-name,.hljs-regexp,.hljs-selector-class,.hljs-selector-id,.hljs-tag,.hljs-template-variable,.hljs-variable{color:#ffa07a}.hljs-built_in,.hljs-link,.hljs-literal,.hljs-meta,.hljs-number,.hljs-params,.hljs-type{color:#f5ab35}.hljs-attribute{color:gold}.hljs-addition,.hljs-bullet,.hljs-string,.hljs-symbol{color:#abe338}.hljs-section,.hljs-title{color:#00e0e0}.hljs-keyword,.hljs-selector-tag{color:#dcc6e0}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}@media screen and (-ms-high-contrast:active){.hljs-addition,.hljs-attribute,.hljs-built_in,.hljs-bullet,.hljs-comment,.hljs-link,.hljs-literal,.hljs-meta,.hljs-number,.hljs-params,.hljs-quote,.hljs-string,.hljs-symbol,.hljs-type{color:highlight}.hljs-keyword,.hljs-selector-tag{font-weight:700}} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/a11y-light.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/a11y-light.min.css new file mode 100644 index 0000000..8b5ab90 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/a11y-light.min.css @@ -0,0 +1,7 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*! + Theme: a11y-light + Author: @ericwbailey + Maintainer: @ericwbailey + + Based on the Tomorrow Night Eighties theme: https://github.com/isagalaev/highlight.js/blob/master/src/styles/tomorrow-night-eighties.css +*/.hljs{background:#fefefe;color:#545454}.hljs-comment,.hljs-quote{color:#696969}.hljs-deletion,.hljs-name,.hljs-regexp,.hljs-selector-class,.hljs-selector-id,.hljs-tag,.hljs-template-variable,.hljs-variable{color:#d91e18}.hljs-attribute,.hljs-built_in,.hljs-link,.hljs-literal,.hljs-meta,.hljs-number,.hljs-params,.hljs-type{color:#aa5d00}.hljs-addition,.hljs-bullet,.hljs-string,.hljs-symbol{color:green}.hljs-section,.hljs-title{color:#007faa}.hljs-keyword,.hljs-selector-tag{color:#7928a1}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}@media screen and (-ms-high-contrast:active){.hljs-addition,.hljs-attribute,.hljs-built_in,.hljs-bullet,.hljs-comment,.hljs-link,.hljs-literal,.hljs-meta,.hljs-number,.hljs-params,.hljs-quote,.hljs-string,.hljs-symbol,.hljs-type{color:highlight}.hljs-keyword,.hljs-selector-tag{font-weight:700}} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/agate.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/agate.min.css new file mode 100644 index 0000000..bdbeed4 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/agate.min.css @@ -0,0 +1,20 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*! + Theme: Agate + Author: (c) Taufik Nurrohman + Maintainer: @taufik-nurrohman + Updated: 2021-04-24 + + #333 + #62c8f3 + #7bd694 + #888 + #a2fca2 + #ade5fc + #b8d8a2 + #c6b4f0 + #d36363 + #fc9b9b + #fcc28c + #ffa + #fff +*/.hljs{background:#333;color:#fff}.hljs-doctag,.hljs-meta-keyword,.hljs-name,.hljs-strong{font-weight:700}.hljs-code,.hljs-emphasis{font-style:italic}.hljs-section,.hljs-tag{color:#62c8f3}.hljs-selector-class,.hljs-selector-id,.hljs-template-variable,.hljs-variable{color:#ade5fc}.hljs-meta-string,.hljs-string{color:#a2fca2}.hljs-attr,.hljs-quote,.hljs-selector-attr{color:#7bd694}.hljs-tag .hljs-attr{color:inherit}.hljs-attribute,.hljs-title,.hljs-type{color:#ffa}.hljs-number,.hljs-symbol{color:#d36363}.hljs-bullet,.hljs-template-tag{color:#b8d8a2}.hljs-built_in,.hljs-keyword,.hljs-literal,.hljs-selector-tag{color:#fcc28c}.hljs-code,.hljs-comment,.hljs-formula{color:#888}.hljs-link,.hljs-regexp,.hljs-selector-pseudo{color:#c6b4f0}.hljs-meta{color:#fc9b9b}.hljs-deletion{background:#fc9b9b;color:#333}.hljs-addition{background:#a2fca2;color:#333}.hljs-subst{color:#fff}.hljs a{color:inherit}.hljs a:focus,.hljs a:hover{color:inherit;text-decoration:underline}.hljs mark{background:#555;color:inherit} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/an-old-hope.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/an-old-hope.min.css new file mode 100644 index 0000000..ffc7f8c --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/an-old-hope.min.css @@ -0,0 +1,9 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*! + Theme: An Old Hope – Star Wars Syntax + Author: (c) Gustavo Costa + Maintainer: @gusbemacbe + + Original theme - Ocean Dark Theme – by https://github.com/gavsiu + Based on Jesse Leite's Atom syntax theme 'An Old Hope' + https://github.com/JesseLeite/an-old-hope-syntax-atom +*/.hljs{background:#1c1d21;color:#c0c5ce}.hljs-comment,.hljs-quote{color:#b6b18b}.hljs-deletion,.hljs-name,.hljs-regexp,.hljs-selector-class,.hljs-selector-id,.hljs-tag,.hljs-template-variable,.hljs-variable{color:#eb3c54}.hljs-built_in,.hljs-link,.hljs-literal,.hljs-meta,.hljs-number,.hljs-params,.hljs-type{color:#e7ce56}.hljs-attribute{color:#ee7c2b}.hljs-addition,.hljs-bullet,.hljs-string,.hljs-symbol{color:#4fb4d7}.hljs-section,.hljs-title{color:#78bb65}.hljs-keyword,.hljs-selector-tag{color:#b45ea4}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/androidstudio.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/androidstudio.min.css new file mode 100644 index 0000000..7fbe783 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/androidstudio.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#a9b7c6;background:#282b2e}.hljs-bullet,.hljs-literal,.hljs-number,.hljs-symbol{color:#6897bb}.hljs-deletion,.hljs-keyword,.hljs-selector-tag{color:#cc7832}.hljs-link,.hljs-template-variable,.hljs-variable{color:#629755}.hljs-comment,.hljs-quote{color:grey}.hljs-meta{color:#bbb529}.hljs-addition,.hljs-attribute,.hljs-string{color:#6a8759}.hljs-section,.hljs-title,.hljs-type{color:#ffc66d}.hljs-name,.hljs-selector-class,.hljs-selector-id{color:#e8bf6a}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/arduino-light.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/arduino-light.min.css new file mode 100644 index 0000000..cadb130 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/arduino-light.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#fff;color:#434f54}.hljs-subst{color:#434f54}.hljs-attribute,.hljs-doctag,.hljs-keyword,.hljs-name,.hljs-selector-tag{color:#00979d}.hljs-addition,.hljs-built_in,.hljs-bullet,.hljs-code,.hljs-literal{color:#d35400}.hljs-link,.hljs-regexp,.hljs-selector-attr,.hljs-selector-pseudo,.hljs-symbol,.hljs-template-variable,.hljs-variable{color:#00979d}.hljs-deletion,.hljs-quote,.hljs-selector-class,.hljs-selector-id,.hljs-string,.hljs-template-tag,.hljs-type{color:#005c5f}.hljs-comment{color:rgba(149,165,166,.8)}.hljs-meta .hljs-keyword{color:#728e00}.hljs-meta{color:#434f54}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}.hljs-function{color:#728e00}.hljs-section,.hljs-title{color:#800;font-weight:700}.hljs-number{color:#8a7b52} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/arta.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/arta.min.css new file mode 100644 index 0000000..8dcdc74 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/arta.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#222;color:#aaa}.hljs-subst{color:#aaa}.hljs-section{color:#fff}.hljs-comment,.hljs-meta,.hljs-quote{color:#444}.hljs-bullet,.hljs-regexp,.hljs-string,.hljs-symbol{color:#fc3}.hljs-addition,.hljs-number{color:#0c6}.hljs-attribute,.hljs-built_in,.hljs-link,.hljs-literal,.hljs-template-variable,.hljs-type{color:#32aaee}.hljs-keyword,.hljs-name,.hljs-selector-class,.hljs-selector-id,.hljs-selector-tag{color:#64a}.hljs-deletion,.hljs-template-tag,.hljs-title,.hljs-variable{color:#b16}.hljs-doctag,.hljs-section,.hljs-strong{font-weight:700}.hljs-emphasis{font-style:italic} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/ascetic.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/ascetic.min.css new file mode 100644 index 0000000..3c9fe03 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/ascetic.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#fff;color:#000}.hljs-addition,.hljs-attribute,.hljs-bullet,.hljs-link,.hljs-section,.hljs-string,.hljs-symbol,.hljs-template-variable,.hljs-variable{color:#888}.hljs-comment,.hljs-deletion,.hljs-meta,.hljs-quote{color:#ccc}.hljs-keyword,.hljs-name,.hljs-section,.hljs-selector-tag,.hljs-strong,.hljs-type{font-weight:700}.hljs-emphasis{font-style:italic} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/atom-one-dark-reasonable.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/atom-one-dark-reasonable.min.css new file mode 100644 index 0000000..9296216 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/atom-one-dark-reasonable.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#abb2bf;background:#282c34}.hljs-keyword,.hljs-operator,.hljs-pattern-match{color:#f92672}.hljs-function,.hljs-pattern-match .hljs-constructor{color:#61aeee}.hljs-function .hljs-params{color:#a6e22e}.hljs-function .hljs-params .hljs-typing{color:#fd971f}.hljs-module-access .hljs-module{color:#7e57c2}.hljs-constructor{color:#e2b93d}.hljs-constructor .hljs-string{color:#9ccc65}.hljs-comment,.hljs-quote{color:#b18eb1;font-style:italic}.hljs-doctag,.hljs-formula{color:#c678dd}.hljs-deletion,.hljs-name,.hljs-section,.hljs-selector-tag,.hljs-subst{color:#e06c75}.hljs-literal{color:#56b6c2}.hljs-addition,.hljs-attribute,.hljs-meta .hljs-string,.hljs-regexp,.hljs-string{color:#98c379}.hljs-built_in,.hljs-class .hljs-title,.hljs-title.class_{color:#e6c07b}.hljs-attr,.hljs-number,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-pseudo,.hljs-template-variable,.hljs-type,.hljs-variable{color:#d19a66}.hljs-bullet,.hljs-link,.hljs-meta,.hljs-selector-id,.hljs-symbol,.hljs-title{color:#61aeee}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}.hljs-link{text-decoration:underline} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/atom-one-dark.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/atom-one-dark.min.css new file mode 100644 index 0000000..5344ee3 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/atom-one-dark.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#abb2bf;background:#282c34}.hljs-comment,.hljs-quote{color:#5c6370;font-style:italic}.hljs-doctag,.hljs-formula,.hljs-keyword{color:#c678dd}.hljs-deletion,.hljs-name,.hljs-section,.hljs-selector-tag,.hljs-subst{color:#e06c75}.hljs-literal{color:#56b6c2}.hljs-addition,.hljs-attribute,.hljs-meta .hljs-string,.hljs-regexp,.hljs-string{color:#98c379}.hljs-attr,.hljs-number,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-pseudo,.hljs-template-variable,.hljs-type,.hljs-variable{color:#d19a66}.hljs-bullet,.hljs-link,.hljs-meta,.hljs-selector-id,.hljs-symbol,.hljs-title{color:#61aeee}.hljs-built_in,.hljs-class .hljs-title,.hljs-title.class_{color:#e6c07b}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}.hljs-link{text-decoration:underline} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/atom-one-light.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/atom-one-light.min.css new file mode 100644 index 0000000..df0268a --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/atom-one-light.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#383a42;background:#fafafa}.hljs-comment,.hljs-quote{color:#a0a1a7;font-style:italic}.hljs-doctag,.hljs-formula,.hljs-keyword{color:#a626a4}.hljs-deletion,.hljs-name,.hljs-section,.hljs-selector-tag,.hljs-subst{color:#e45649}.hljs-literal{color:#0184bb}.hljs-addition,.hljs-attribute,.hljs-meta .hljs-string,.hljs-regexp,.hljs-string{color:#50a14f}.hljs-attr,.hljs-number,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-pseudo,.hljs-template-variable,.hljs-type,.hljs-variable{color:#986801}.hljs-bullet,.hljs-link,.hljs-meta,.hljs-selector-id,.hljs-symbol,.hljs-title{color:#4078f2}.hljs-built_in,.hljs-class .hljs-title,.hljs-title.class_{color:#c18401}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}.hljs-link{text-decoration:underline} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/brown-paper.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/brown-paper.min.css new file mode 100644 index 0000000..6231e8a --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/brown-paper.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#363c69;background:url(./brown-papersq.png) #b7a68e}.hljs-keyword,.hljs-literal,.hljs-selector-tag{color:#059}.hljs-addition,.hljs-attribute,.hljs-built_in,.hljs-bullet,.hljs-link,.hljs-name,.hljs-section,.hljs-string,.hljs-symbol,.hljs-template-tag,.hljs-template-variable,.hljs-title,.hljs-type,.hljs-variable{color:#2c009f}.hljs-comment,.hljs-deletion,.hljs-meta,.hljs-quote{color:#802022}.hljs-doctag,.hljs-keyword,.hljs-literal,.hljs-name,.hljs-section,.hljs-selector-tag,.hljs-strong,.hljs-title,.hljs-type{font-weight:700}.hljs-emphasis{font-style:italic} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/codepen-embed.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/codepen-embed.min.css new file mode 100644 index 0000000..0d7dff6 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/codepen-embed.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#222;color:#fff}.hljs-comment,.hljs-quote{color:#777}.hljs-built_in,.hljs-bullet,.hljs-deletion,.hljs-link,.hljs-literal,.hljs-meta,.hljs-number,.hljs-params,.hljs-regexp,.hljs-symbol,.hljs-tag,.hljs-template-variable,.hljs-variable{color:#ab875d}.hljs-attribute,.hljs-name,.hljs-section,.hljs-selector-class,.hljs-selector-id,.hljs-title,.hljs-type{color:#9b869b}.hljs-addition,.hljs-keyword,.hljs-selector-tag,.hljs-string{color:#8f9c6c}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/color-brewer.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/color-brewer.min.css new file mode 100644 index 0000000..1c677e3 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/color-brewer.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#000;background:#fff}.hljs-addition,.hljs-meta,.hljs-string,.hljs-symbol,.hljs-template-tag,.hljs-template-variable{color:#756bb1}.hljs-comment,.hljs-quote{color:#636363}.hljs-bullet,.hljs-link,.hljs-literal,.hljs-number,.hljs-regexp{color:#31a354}.hljs-deletion,.hljs-variable{color:#88f}.hljs-built_in,.hljs-doctag,.hljs-keyword,.hljs-name,.hljs-section,.hljs-selector-class,.hljs-selector-id,.hljs-selector-tag,.hljs-strong,.hljs-tag,.hljs-title,.hljs-type{color:#3182bd}.hljs-emphasis{font-style:italic}.hljs-attribute{color:#e6550d} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/dark.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/dark.min.css new file mode 100644 index 0000000..9ed546b --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/dark.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#ddd;background:#303030}.hljs-keyword,.hljs-link,.hljs-literal,.hljs-section,.hljs-selector-tag{color:#fff}.hljs-addition,.hljs-attribute,.hljs-built_in,.hljs-bullet,.hljs-name,.hljs-string,.hljs-symbol,.hljs-template-tag,.hljs-template-variable,.hljs-title,.hljs-type,.hljs-variable{color:#d88}.hljs-comment,.hljs-deletion,.hljs-meta,.hljs-quote{color:#979797}.hljs-doctag,.hljs-keyword,.hljs-literal,.hljs-name,.hljs-section,.hljs-selector-tag,.hljs-strong,.hljs-title,.hljs-type{font-weight:700}.hljs-emphasis{font-style:italic} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/default.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/default.min.css new file mode 100644 index 0000000..a75ea91 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/default.min.css @@ -0,0 +1,9 @@ +/*! + Theme: Default + Description: Original highlight.js style + Author: (c) Ivan Sagalaev + Maintainer: @highlightjs/core-team + Website: https://highlightjs.org/ + License: see project LICENSE + Touched: 2021 +*/pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#f3f3f3;color:#444}.hljs-comment{color:#697070}.hljs-punctuation,.hljs-tag{color:#444a}.hljs-tag .hljs-attr,.hljs-tag .hljs-name{color:#444}.hljs-attribute,.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-name,.hljs-selector-tag{font-weight:700}.hljs-deletion,.hljs-number,.hljs-quote,.hljs-selector-class,.hljs-selector-id,.hljs-string,.hljs-template-tag,.hljs-type{color:#800}.hljs-section,.hljs-title{color:#800;font-weight:700}.hljs-link,.hljs-operator,.hljs-regexp,.hljs-selector-attr,.hljs-selector-pseudo,.hljs-symbol,.hljs-template-variable,.hljs-variable{color:#ab5656}.hljs-literal{color:#695}.hljs-addition,.hljs-built_in,.hljs-bullet,.hljs-code{color:#397300}.hljs-meta{color:#1f7199}.hljs-meta .hljs-string{color:#38a}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/devibeans.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/devibeans.min.css new file mode 100644 index 0000000..d8c4c0f --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/devibeans.min.css @@ -0,0 +1,7 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*! + Theme: devibeans (dark) + Author: @terminaldweller + Maintainer: @terminaldweller + + Inspired by vim's jellybeans theme (https://github.com/nanotech/jellybeans.vim) +*/.hljs{background:#000;color:#a39e9b}.hljs-attr,.hljs-template-tag{color:#8787d7}.hljs-comment,.hljs-doctag,.hljs-quote{color:#396}.hljs-params{color:#a39e9b}.hljs-regexp{color:#d700ff}.hljs-literal,.hljs-number,.hljs-selector-id,.hljs-tag{color:#ef5350}.hljs-meta,.hljs-meta .hljs-keyword{color:#0087ff}.hljs-code,.hljs-formula,.hljs-keyword,.hljs-link,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-pseudo,.hljs-template-variable,.hljs-variable{color:#64b5f6}.hljs-built_in,.hljs-deletion,.hljs-title{color:#ff8700}.hljs-attribute,.hljs-function,.hljs-name,.hljs-property,.hljs-section,.hljs-type{color:#ffd75f}.hljs-addition,.hljs-bullet,.hljs-meta .hljs-string,.hljs-string,.hljs-subst,.hljs-symbol{color:#558b2f}.hljs-selector-tag{color:#96f}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/docco.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/docco.min.css new file mode 100644 index 0000000..382ecbb --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/docco.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#000;background:#f8f8ff}.hljs-comment,.hljs-quote{color:#408080;font-style:italic}.hljs-keyword,.hljs-literal,.hljs-selector-tag,.hljs-subst{color:#954121}.hljs-number{color:#40a070}.hljs-doctag,.hljs-string{color:#219161}.hljs-section,.hljs-selector-class,.hljs-selector-id,.hljs-type{color:#19469d}.hljs-params{color:#00f}.hljs-title{color:#458;font-weight:700}.hljs-attribute,.hljs-name,.hljs-tag{color:navy;font-weight:400}.hljs-template-variable,.hljs-variable{color:teal}.hljs-link,.hljs-regexp{color:#b68}.hljs-bullet,.hljs-symbol{color:#990073}.hljs-built_in{color:#0086b3}.hljs-meta{color:#999;font-weight:700}.hljs-deletion{background:#fdd}.hljs-addition{background:#dfd}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/far.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/far.min.css new file mode 100644 index 0000000..c338ef6 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/far.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#0ff;background:navy}.hljs-addition,.hljs-attribute,.hljs-built_in,.hljs-bullet,.hljs-string,.hljs-symbol,.hljs-template-tag,.hljs-template-variable{color:#ff0}.hljs-keyword,.hljs-name,.hljs-section,.hljs-selector-class,.hljs-selector-id,.hljs-selector-tag,.hljs-type,.hljs-variable{color:#fff}.hljs-comment,.hljs-deletion,.hljs-doctag,.hljs-quote{color:#888}.hljs-link,.hljs-literal,.hljs-number,.hljs-regexp{color:#0f0}.hljs-meta{color:teal}.hljs-keyword,.hljs-name,.hljs-section,.hljs-selector-tag,.hljs-strong,.hljs-title{font-weight:700}.hljs-emphasis{font-style:italic} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/felipec.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/felipec.min.css new file mode 100644 index 0000000..7f76cd0 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/felipec.min.css @@ -0,0 +1,7 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*! + * Theme: FelipeC + * Author: (c) 2021 Felipe Contreras + * Website: https://github.com/felipec/vim-felipec + * + * Autogenerated with vim-felipec's generator. +*/.hljs{color:#dedde4;background-color:#1d1c21}.hljs ::selection,.hljs::selection{color:#1d1c21;background-color:#ba9cef}.hljs-code,.hljs-comment,.hljs-quote{color:#9e9da4}.hljs-deletion,.hljs-literal,.hljs-number{color:#f09080}.hljs-doctag,.hljs-meta,.hljs-operator,.hljs-punctuation,.hljs-selector-attr,.hljs-subst,.hljs-template-variable{color:#ffbb7b}.hljs-type{color:#fddb7c}.hljs-selector-class,.hljs-selector-id,.hljs-tag,.hljs-title{color:#c4da7d}.hljs-addition,.hljs-regexp,.hljs-string{color:#93e4a4}.hljs-class,.hljs-property{color:#65e7d1}.hljs-name,.hljs-selector-tag{color:#30c2d8}.hljs-built_in,.hljs-keyword{color:#5fb8f2}.hljs-bullet,.hljs-section{color:#90aafa}.hljs-selector-pseudo{color:#ba9cef}.hljs-attr,.hljs-attribute,.hljs-params,.hljs-variable{color:#d991d2}.hljs-link,.hljs-symbol{color:#ec8dab}.hljs-literal,.hljs-strong,.hljs-title{font-weight:700}.hljs-emphasis{font-style:italic} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/foundation.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/foundation.min.css new file mode 100644 index 0000000..1ddcfa6 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/foundation.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#eee;color:#000}.hljs-addition,.hljs-attribute,.hljs-emphasis,.hljs-link{color:#070}.hljs-emphasis{font-style:italic}.hljs-deletion,.hljs-string,.hljs-strong{color:#d14}.hljs-strong{font-weight:700}.hljs-comment,.hljs-quote{color:#998;font-style:italic}.hljs-section,.hljs-title{color:#900}.hljs-class .hljs-title,.hljs-title.class_,.hljs-type{color:#458}.hljs-template-variable,.hljs-variable{color:#369}.hljs-bullet{color:#970}.hljs-meta{color:#34b}.hljs-code,.hljs-keyword,.hljs-literal,.hljs-number,.hljs-selector-tag{color:#099}.hljs-regexp{background-color:#fff0ff;color:#808}.hljs-symbol{color:#990073}.hljs-name,.hljs-selector-class,.hljs-selector-id,.hljs-tag{color:#070} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/github-dark-dimmed.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/github-dark-dimmed.min.css new file mode 100644 index 0000000..e266dfc --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/github-dark-dimmed.min.css @@ -0,0 +1,9 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*! + Theme: GitHub Dark Dimmed + Description: Dark dimmed theme as seen on github.com + Author: github.com + Maintainer: @Hirse + Updated: 2021-05-15 + + Colors taken from GitHub's CSS +*/.hljs{color:#adbac7;background:#22272e}.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language_{color:#f47067}.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-title.function_{color:#dcbdfb}.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-variable{color:#6cb6ff}.hljs-meta .hljs-string,.hljs-regexp,.hljs-string{color:#96d0ff}.hljs-built_in,.hljs-symbol{color:#f69d50}.hljs-code,.hljs-comment,.hljs-formula{color:#768390}.hljs-name,.hljs-quote,.hljs-selector-pseudo,.hljs-selector-tag{color:#8ddb8c}.hljs-subst{color:#adbac7}.hljs-section{color:#316dca;font-weight:700}.hljs-bullet{color:#eac55f}.hljs-emphasis{color:#adbac7;font-style:italic}.hljs-strong{color:#adbac7;font-weight:700}.hljs-addition{color:#b4f1b4;background-color:#1b4721}.hljs-deletion{color:#ffd8d3;background-color:#78191b} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/github-dark.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/github-dark.min.css new file mode 100644 index 0000000..03b6da8 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/github-dark.min.css @@ -0,0 +1,10 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*! + Theme: GitHub Dark + Description: Dark theme as seen on github.com + Author: github.com + Maintainer: @Hirse + Updated: 2021-05-15 + + Outdated base version: https://github.com/primer/github-syntax-dark + Current colors taken from GitHub's CSS +*/.hljs{color:#c9d1d9;background:#0d1117}.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language_{color:#ff7b72}.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-title.function_{color:#d2a8ff}.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-variable{color:#79c0ff}.hljs-meta .hljs-string,.hljs-regexp,.hljs-string{color:#a5d6ff}.hljs-built_in,.hljs-symbol{color:#ffa657}.hljs-code,.hljs-comment,.hljs-formula{color:#8b949e}.hljs-name,.hljs-quote,.hljs-selector-pseudo,.hljs-selector-tag{color:#7ee787}.hljs-subst{color:#c9d1d9}.hljs-section{color:#1f6feb;font-weight:700}.hljs-bullet{color:#f2cc60}.hljs-emphasis{color:#c9d1d9;font-style:italic}.hljs-strong{color:#c9d1d9;font-weight:700}.hljs-addition{color:#aff5b4;background-color:#033a16}.hljs-deletion{color:#ffdcd7;background-color:#67060c} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/github.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/github.min.css new file mode 100644 index 0000000..275239a --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/github.min.css @@ -0,0 +1,10 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*! + Theme: GitHub + Description: Light theme as seen on github.com + Author: github.com + Maintainer: @Hirse + Updated: 2021-05-15 + + Outdated base version: https://github.com/primer/github-syntax-light + Current colors taken from GitHub's CSS +*/.hljs{color:#24292e;background:#fff}.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language_{color:#d73a49}.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-title.function_{color:#6f42c1}.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-variable{color:#005cc5}.hljs-meta .hljs-string,.hljs-regexp,.hljs-string{color:#032f62}.hljs-built_in,.hljs-symbol{color:#e36209}.hljs-code,.hljs-comment,.hljs-formula{color:#6a737d}.hljs-name,.hljs-quote,.hljs-selector-pseudo,.hljs-selector-tag{color:#22863a}.hljs-subst{color:#24292e}.hljs-section{color:#005cc5;font-weight:700}.hljs-bullet{color:#735c0f}.hljs-emphasis{color:#24292e;font-style:italic}.hljs-strong{color:#24292e;font-weight:700}.hljs-addition{color:#22863a;background-color:#f0fff4}.hljs-deletion{color:#b31d28;background-color:#ffeef0} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/gml.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/gml.min.css new file mode 100644 index 0000000..89455fe --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/gml.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#222;color:silver}.hljs-keyword{color:#ffb871;font-weight:700}.hljs-built_in{color:#ffb871}.hljs-literal{color:#ff8080}.hljs-symbol{color:#58e55a}.hljs-comment{color:#5b995b}.hljs-string{color:#ff0}.hljs-number{color:#ff8080}.hljs-addition,.hljs-attribute,.hljs-bullet,.hljs-code,.hljs-deletion,.hljs-doctag,.hljs-function,.hljs-link,.hljs-meta,.hljs-meta .hljs-keyword,.hljs-name,.hljs-quote,.hljs-regexp,.hljs-section,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-selector-pseudo,.hljs-selector-tag,.hljs-subst,.hljs-template-tag,.hljs-template-variable,.hljs-title,.hljs-type,.hljs-variable{color:silver}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/googlecode.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/googlecode.min.css new file mode 100644 index 0000000..0140b89 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/googlecode.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#fff;color:#000}.hljs-comment,.hljs-quote{color:#800}.hljs-keyword,.hljs-name,.hljs-section,.hljs-selector-tag,.hljs-title{color:#008}.hljs-template-variable,.hljs-variable{color:#660}.hljs-regexp,.hljs-selector-attr,.hljs-selector-pseudo,.hljs-string{color:#080}.hljs-bullet,.hljs-link,.hljs-literal,.hljs-meta,.hljs-number,.hljs-symbol{color:#066}.hljs-attr,.hljs-built_in,.hljs-doctag,.hljs-params,.hljs-title,.hljs-type{color:#606}.hljs-attribute,.hljs-subst{color:#000}.hljs-formula{background-color:#eee;font-style:italic}.hljs-selector-class,.hljs-selector-id{color:#9b703f}.hljs-addition{background-color:#baeeba}.hljs-deletion{background-color:#ffc8bd}.hljs-doctag,.hljs-strong{font-weight:700}.hljs-emphasis{font-style:italic} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/gradient-dark.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/gradient-dark.min.css new file mode 100644 index 0000000..4aba928 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/gradient-dark.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background-color:#652487;background-image:linear-gradient(160deg,#652487 0,#443ac3 35%,#0174b7 68%,#04988e 100%);color:#e7e4eb}.hljs-subtr{color:#e7e4eb}.hljs-comment,.hljs-doctag,.hljs-meta,.hljs-quote{color:#af8dd9}.hljs-attr,.hljs-regexp,.hljs-selector-id,.hljs-selector-tag,.hljs-tag,.hljs-template-tag{color:#aefbff}.hljs-bullet,.hljs-params,.hljs-selector-class{color:#f19fff}.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-section,.hljs-symbol,.hljs-type{color:#17fc95}.hljs-addition,.hljs-link,.hljs-number{color:#c5fe00}.hljs-string{color:#38c0ff}.hljs-addition,.hljs-attribute{color:#e7ff9f}.hljs-template-variable,.hljs-variable{color:#e447ff}.hljs-built_in,.hljs-class,.hljs-formula,.hljs-function,.hljs-name,.hljs-title{color:#ffc800}.hljs-deletion,.hljs-literal,.hljs-selector-pseudo{color:#ff9e44}.hljs-emphasis,.hljs-quote{font-style:italic}.hljs-keyword,.hljs-params,.hljs-section,.hljs-selector-class,.hljs-selector-id,.hljs-selector-tag,.hljs-strong,.hljs-template-tag{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/gradient-light.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/gradient-light.min.css new file mode 100644 index 0000000..c5db6fd --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/gradient-light.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background-color:#f9ccff;background-image:linear-gradient(295deg,#f9ccff 0,#e6bbf9 11%,#9ec6f9 32%,#55e6ee 60%,#91f5d1 74%,#f9ffbf 98%);color:#250482}.hljs-subtr{color:#01958b}.hljs-comment,.hljs-doctag,.hljs-meta,.hljs-quote{color:#cb7200}.hljs-attr,.hljs-regexp,.hljs-selector-id,.hljs-selector-tag,.hljs-tag,.hljs-template-tag{color:#07bd5f}.hljs-bullet,.hljs-params,.hljs-selector-class{color:#43449f}.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-section,.hljs-symbol,.hljs-type{color:#7d2801}.hljs-addition,.hljs-link,.hljs-number{color:#7f0096}.hljs-string{color:#2681ab}.hljs-addition,.hljs-attribute{color:#296562}.hljs-template-variable,.hljs-variable{color:#025c8f}.hljs-built_in,.hljs-class,.hljs-formula,.hljs-function,.hljs-name,.hljs-title{color:#529117}.hljs-deletion,.hljs-literal,.hljs-selector-pseudo{color:#ad13ff}.hljs-emphasis,.hljs-quote{font-style:italic}.hljs-keyword,.hljs-params,.hljs-section,.hljs-selector-class,.hljs-selector-id,.hljs-selector-tag,.hljs-strong,.hljs-template-tag{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/grayscale.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/grayscale.min.css new file mode 100644 index 0000000..5eefdaa --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/grayscale.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#333;background:#fff}.hljs-comment,.hljs-quote{color:#777;font-style:italic}.hljs-keyword,.hljs-selector-tag,.hljs-subst{color:#333;font-weight:700}.hljs-literal,.hljs-number{color:#777}.hljs-doctag,.hljs-formula,.hljs-string{color:#333;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAYAAACp8Z5+AAAAJ0lEQVQIW2O8e/fufwYGBgZBQUEQxcCIIfDu3Tuwivfv30NUoAsAALHpFMMLqZlPAAAAAElFTkSuQmCC)}.hljs-section,.hljs-selector-id,.hljs-title{color:#000;font-weight:700}.hljs-subst{font-weight:400}.hljs-class .hljs-title,.hljs-name,.hljs-title.class_,.hljs-type{color:#333;font-weight:700}.hljs-tag{color:#333}.hljs-regexp{color:#333;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAICAYAAADA+m62AAAAPUlEQVQYV2NkQAN37979r6yszIgujiIAU4RNMVwhuiQ6H6wQl3XI4oy4FMHcCJPHcDS6J2A2EqUQpJhohQDexSef15DBCwAAAABJRU5ErkJggg==)}.hljs-bullet,.hljs-link,.hljs-symbol{color:#000;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAKElEQVQIW2NkQAO7d+/+z4gsBhJwdXVlhAvCBECKwIIwAbhKZBUwBQA6hBpm5efZsgAAAABJRU5ErkJggg==)}.hljs-built_in{color:#000;text-decoration:underline}.hljs-meta{color:#999;font-weight:700}.hljs-deletion{color:#fff;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAADCAYAAABS3WWCAAAAE0lEQVQIW2MMDQ39zzhz5kwIAQAyxweWgUHd1AAAAABJRU5ErkJggg==)}.hljs-addition{color:#000;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAYAAADgkQYQAAAALUlEQVQYV2N89+7dfwYk8P79ewZBQUFkIQZGOiu6e/cuiptQHAPl0NtNxAQBAM97Oejj3Dg7AAAAAElFTkSuQmCC)}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/hybrid.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/hybrid.min.css new file mode 100644 index 0000000..52489b6 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/hybrid.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#1d1f21;color:#c5c8c6}.hljs span::selection,.hljs::selection{background:#373b41}.hljs span::-moz-selection,.hljs::-moz-selection{background:#373b41}.hljs-name,.hljs-title{color:#f0c674}.hljs-comment,.hljs-meta,.hljs-meta .hljs-keyword{color:#707880}.hljs-deletion,.hljs-link,.hljs-literal,.hljs-number,.hljs-symbol{color:#c66}.hljs-addition,.hljs-doctag,.hljs-regexp,.hljs-selector-attr,.hljs-selector-pseudo,.hljs-string{color:#b5bd68}.hljs-attribute,.hljs-code,.hljs-selector-id{color:#b294bb}.hljs-bullet,.hljs-keyword,.hljs-selector-tag,.hljs-tag{color:#81a2be}.hljs-subst,.hljs-template-tag,.hljs-template-variable,.hljs-variable{color:#8abeb7}.hljs-built_in,.hljs-quote,.hljs-section,.hljs-selector-class,.hljs-type{color:#de935f}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/idea.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/idea.min.css new file mode 100644 index 0000000..7cc62ff --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/idea.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#000;background:#fff}.hljs-subst,.hljs-title{font-weight:400;color:#000}.hljs-comment,.hljs-quote{color:grey;font-style:italic}.hljs-meta{color:olive}.hljs-tag{background:#efefef}.hljs-keyword,.hljs-literal,.hljs-name,.hljs-section,.hljs-selector-class,.hljs-selector-id,.hljs-selector-tag,.hljs-type{font-weight:700;color:navy}.hljs-attribute,.hljs-link,.hljs-number,.hljs-regexp{font-weight:700;color:#00f}.hljs-link,.hljs-number,.hljs-regexp{font-weight:400}.hljs-string{color:green;font-weight:700}.hljs-bullet,.hljs-formula,.hljs-symbol{color:#000;background:#d0eded;font-style:italic}.hljs-doctag{text-decoration:underline}.hljs-template-variable,.hljs-variable{color:#660e7a}.hljs-addition{background:#baeeba}.hljs-deletion{background:#ffc8bd}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/intellij-light.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/intellij-light.min.css new file mode 100644 index 0000000..97fc3e2 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/intellij-light.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#000;background:#fff}.hljs-subst,.hljs-title{font-weight:400;color:#000}.hljs-title.function_{color:#7a7a43}.hljs-code,.hljs-comment,.hljs-quote{color:#8c8c8c;font-style:italic}.hljs-meta{color:#9e880d}.hljs-section{color:#871094}.hljs-built_in,.hljs-keyword,.hljs-literal,.hljs-meta .hljs-keyword,.hljs-name,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-selector-pseudo,.hljs-selector-tag,.hljs-symbol,.hljs-template-tag,.hljs-type,.hljs-variable.language_{color:#0033b3}.hljs-attr,.hljs-property{color:#871094}.hljs-attribute{color:#174ad4}.hljs-number{color:#1750eb}.hljs-regexp{color:#264eff}.hljs-link{text-decoration:underline;color:#006dcc}.hljs-meta .hljs-string,.hljs-string{color:#067d17}.hljs-char.escape_{color:#0037a6}.hljs-doctag{text-decoration:underline}.hljs-template-variable{color:#248f8f}.hljs-addition{background:#bee6be}.hljs-deletion{background:#d6d6d6}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/ir-black.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/ir-black.min.css new file mode 100644 index 0000000..e78fd08 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/ir-black.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#000;color:#f8f8f8}.hljs-comment,.hljs-meta,.hljs-quote{color:#7c7c7c}.hljs-keyword,.hljs-name,.hljs-selector-tag,.hljs-tag{color:#96cbfe}.hljs-attribute,.hljs-selector-id{color:#ffffb6}.hljs-addition,.hljs-selector-attr,.hljs-selector-pseudo,.hljs-string{color:#a8ff60}.hljs-subst{color:#daefa3}.hljs-link,.hljs-regexp{color:#e9c062}.hljs-doctag,.hljs-section,.hljs-title,.hljs-type{color:#ffffb6}.hljs-bullet,.hljs-literal,.hljs-symbol,.hljs-template-variable,.hljs-variable{color:#c6c5fe}.hljs-deletion,.hljs-number{color:#ff73fd}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/isbl-editor-dark.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/isbl-editor-dark.min.css new file mode 100644 index 0000000..535ef87 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/isbl-editor-dark.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#404040}.hljs,.hljs-subst{color:#f0f0f0}.hljs-comment{color:#b5b5b5;font-style:italic}.hljs-attribute,.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-name,.hljs-selector-tag{color:#f0f0f0;font-weight:700}.hljs-string{color:#97bf0d}.hljs-deletion,.hljs-number,.hljs-quote,.hljs-selector-class,.hljs-selector-id,.hljs-template-tag,.hljs-type{color:#f0f0f0}.hljs-link,.hljs-regexp,.hljs-selector-attr,.hljs-selector-pseudo,.hljs-symbol,.hljs-template-variable,.hljs-variable{color:#e2c696}.hljs-built_in,.hljs-literal{color:#97bf0d;font-weight:700}.hljs-addition,.hljs-bullet,.hljs-code{color:#397300}.hljs-class{color:#ce9d4d;font-weight:700}.hljs-section,.hljs-title{color:#df471e}.hljs-title>.hljs-built_in{color:#81bce9;font-weight:400}.hljs-meta{color:#1f7199}.hljs-meta .hljs-string{color:#4d99bf}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/isbl-editor-light.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/isbl-editor-light.min.css new file mode 100644 index 0000000..f008c74 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/isbl-editor-light.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#fff;color:#000}.hljs-subst{color:#000}.hljs-comment{color:#555;font-style:italic}.hljs-attribute,.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-name,.hljs-selector-tag{color:#000;font-weight:700}.hljs-string{color:navy}.hljs-deletion,.hljs-number,.hljs-quote,.hljs-selector-class,.hljs-selector-id,.hljs-template-tag,.hljs-type{color:#000}.hljs-link,.hljs-regexp,.hljs-selector-attr,.hljs-selector-pseudo,.hljs-symbol,.hljs-template-variable,.hljs-variable{color:#5e1700}.hljs-built_in,.hljs-literal{color:navy;font-weight:700}.hljs-addition,.hljs-bullet,.hljs-code{color:#397300}.hljs-class{color:#6f1c00;font-weight:700}.hljs-section,.hljs-title{color:#fb2c00}.hljs-title>.hljs-built_in{color:teal;font-weight:400}.hljs-meta{color:#1f7199}.hljs-meta .hljs-string{color:#4d99bf}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/kimbie-dark.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/kimbie-dark.min.css new file mode 100644 index 0000000..cf56cea --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/kimbie-dark.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#221a0f;color:#d3af86}.hljs-comment,.hljs-quote{color:#d6baad}.hljs-meta,.hljs-name,.hljs-regexp,.hljs-selector-class,.hljs-selector-id,.hljs-tag,.hljs-template-variable,.hljs-variable{color:#dc3958}.hljs-built_in,.hljs-deletion,.hljs-link,.hljs-literal,.hljs-number,.hljs-params,.hljs-type{color:#f79a32}.hljs-addition,.hljs-bullet,.hljs-string,.hljs-symbol{color:#889b4a}.hljs-function,.hljs-keyword,.hljs-selector-tag{color:#98676a}.hljs-attribute,.hljs-section,.hljs-title{color:#f06431}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/kimbie-light.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/kimbie-light.min.css new file mode 100644 index 0000000..b9d0ea4 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/kimbie-light.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#fbebd4;color:#84613d}.hljs-comment,.hljs-quote{color:#a57a4c}.hljs-meta,.hljs-name,.hljs-regexp,.hljs-selector-class,.hljs-selector-id,.hljs-tag,.hljs-template-variable,.hljs-variable{color:#dc3958}.hljs-built_in,.hljs-deletion,.hljs-link,.hljs-literal,.hljs-number,.hljs-params,.hljs-type{color:#f79a32}.hljs-addition,.hljs-bullet,.hljs-string,.hljs-symbol{color:#889b4a}.hljs-function,.hljs-keyword,.hljs-selector-tag{color:#98676a}.hljs-attribute,.hljs-section,.hljs-title{color:#f06431}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/lightfair.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/lightfair.min.css new file mode 100644 index 0000000..b6c3791 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/lightfair.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#444;background:#fff}.hljs-name{color:#01a3a3}.hljs-meta,.hljs-tag{color:#789}.hljs-comment{color:#888}.hljs-attribute,.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-name,.hljs-selector-tag{font-weight:700}.hljs-deletion,.hljs-number,.hljs-quote,.hljs-selector-class,.hljs-selector-id,.hljs-string,.hljs-template-tag,.hljs-type{color:#4286f4}.hljs-section,.hljs-title{color:#4286f4;font-weight:700}.hljs-link,.hljs-regexp,.hljs-selector-attr,.hljs-selector-pseudo,.hljs-symbol,.hljs-template-variable,.hljs-variable{color:#bc6060}.hljs-literal{color:#62bcbc}.hljs-addition,.hljs-built_in,.hljs-bullet,.hljs-code{color:#25c6c6}.hljs-meta .hljs-string{color:#4d99bf}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/lioshi.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/lioshi.min.css new file mode 100644 index 0000000..3d6a92f --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/lioshi.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#303030;color:#c5c8c6}.hljs-comment{color:#8d8d8d}.hljs-quote{color:#b3c7d8}.hljs-deletion,.hljs-name,.hljs-regexp,.hljs-selector-class,.hljs-selector-id,.hljs-tag,.hljs-template-variable,.hljs-variable{color:#c66}.hljs-built_in,.hljs-literal,.hljs-number,.hljs-subst .hljs-link,.hljs-type{color:#de935f}.hljs-attribute{color:#f0c674}.hljs-addition,.hljs-bullet,.hljs-params,.hljs-string{color:#b5bd68}.hljs-class,.hljs-function,.hljs-keyword,.hljs-selector-tag{color:#be94bb}.hljs-meta,.hljs-section,.hljs-title{color:#81a2be}.hljs-symbol{color:#dbc4d9}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/magula.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/magula.min.css new file mode 100644 index 0000000..e024387 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/magula.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background-color:#f4f4f4;color:#000}.hljs-subst{color:#000}.hljs-addition,.hljs-attribute,.hljs-bullet,.hljs-string,.hljs-symbol,.hljs-template-tag,.hljs-template-variable,.hljs-title,.hljs-variable{color:#050}.hljs-comment,.hljs-quote{color:#777}.hljs-link,.hljs-literal,.hljs-number,.hljs-regexp,.hljs-type{color:#800}.hljs-deletion,.hljs-meta{color:#00e}.hljs-built_in,.hljs-doctag,.hljs-keyword,.hljs-name,.hljs-section,.hljs-selector-tag,.hljs-tag,.hljs-title{font-weight:700;color:navy}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/mono-blue.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/mono-blue.min.css new file mode 100644 index 0000000..fb74d40 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/mono-blue.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#eaeef3;color:#00193a}.hljs-doctag,.hljs-keyword,.hljs-name,.hljs-section,.hljs-selector-tag,.hljs-strong,.hljs-title{font-weight:700}.hljs-comment{color:#738191}.hljs-addition,.hljs-built_in,.hljs-literal,.hljs-name,.hljs-quote,.hljs-section,.hljs-selector-class,.hljs-selector-id,.hljs-string,.hljs-tag,.hljs-title,.hljs-type{color:#0048ab}.hljs-attribute,.hljs-bullet,.hljs-deletion,.hljs-link,.hljs-meta,.hljs-regexp,.hljs-subst,.hljs-symbol,.hljs-template-variable,.hljs-variable{color:#4c81c9}.hljs-emphasis{font-style:italic} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/monokai-sublime.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/monokai-sublime.min.css new file mode 100644 index 0000000..247e2e9 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/monokai-sublime.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#23241f;color:#f8f8f2}.hljs-subst,.hljs-tag{color:#f8f8f2}.hljs-emphasis,.hljs-strong{color:#a8a8a2}.hljs-bullet,.hljs-link,.hljs-literal,.hljs-number,.hljs-quote,.hljs-regexp{color:#ae81ff}.hljs-code,.hljs-section,.hljs-selector-class,.hljs-title{color:#a6e22e}.hljs-strong{font-weight:700}.hljs-emphasis{font-style:italic}.hljs-attr,.hljs-keyword,.hljs-name,.hljs-selector-tag{color:#f92672}.hljs-attribute,.hljs-symbol{color:#66d9ef}.hljs-class .hljs-title,.hljs-params,.hljs-title.class_{color:#f8f8f2}.hljs-addition,.hljs-built_in,.hljs-selector-attr,.hljs-selector-id,.hljs-selector-pseudo,.hljs-string,.hljs-template-variable,.hljs-type,.hljs-variable{color:#e6db74}.hljs-comment,.hljs-deletion,.hljs-meta{color:#75715e} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/monokai.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/monokai.min.css new file mode 100644 index 0000000..d289f63 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/monokai.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#272822;color:#ddd}.hljs-keyword,.hljs-literal,.hljs-name,.hljs-number,.hljs-selector-tag,.hljs-strong,.hljs-tag{color:#f92672}.hljs-code{color:#66d9ef}.hljs-attr,.hljs-attribute,.hljs-link,.hljs-regexp,.hljs-symbol{color:#bf79db}.hljs-addition,.hljs-built_in,.hljs-bullet,.hljs-emphasis,.hljs-section,.hljs-selector-attr,.hljs-selector-pseudo,.hljs-string,.hljs-subst,.hljs-template-tag,.hljs-template-variable,.hljs-title,.hljs-type,.hljs-variable{color:#a6e22e}.hljs-class .hljs-title,.hljs-title.class_{color:#fff}.hljs-comment,.hljs-deletion,.hljs-meta,.hljs-quote{color:#75715e}.hljs-doctag,.hljs-keyword,.hljs-literal,.hljs-section,.hljs-selector-id,.hljs-selector-tag,.hljs-title,.hljs-type{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/night-owl.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/night-owl.min.css new file mode 100644 index 0000000..ed94590 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/night-owl.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#011627;color:#d6deeb}.hljs-keyword{color:#c792ea;font-style:italic}.hljs-built_in{color:#addb67;font-style:italic}.hljs-type{color:#82aaff}.hljs-literal{color:#ff5874}.hljs-number{color:#f78c6c}.hljs-regexp{color:#5ca7e4}.hljs-string{color:#ecc48d}.hljs-subst{color:#d3423e}.hljs-symbol{color:#82aaff}.hljs-class{color:#ffcb8b}.hljs-function{color:#82aaff}.hljs-title{color:#dcdcaa;font-style:italic}.hljs-params{color:#7fdbca}.hljs-comment{color:#637777;font-style:italic}.hljs-doctag{color:#7fdbca}.hljs-meta,.hljs-meta .hljs-keyword{color:#82aaff}.hljs-meta .hljs-string{color:#ecc48d}.hljs-section{color:#82b1ff}.hljs-attr,.hljs-name,.hljs-tag{color:#7fdbca}.hljs-attribute{color:#80cbc4}.hljs-variable{color:#addb67}.hljs-bullet{color:#d9f5dd}.hljs-code{color:#80cbc4}.hljs-emphasis{color:#c792ea;font-style:italic}.hljs-strong{color:#addb67;font-weight:700}.hljs-formula{color:#c792ea}.hljs-link{color:#ff869a}.hljs-quote{color:#697098;font-style:italic}.hljs-selector-tag{color:#ff6363}.hljs-selector-id{color:#fad430}.hljs-selector-class{color:#addb67;font-style:italic}.hljs-selector-attr,.hljs-selector-pseudo{color:#c792ea;font-style:italic}.hljs-template-tag{color:#c792ea}.hljs-template-variable{color:#addb67}.hljs-addition{color:#addb67ff;font-style:italic}.hljs-deletion{color:#ef535090;font-style:italic} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/nnfx-dark.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/nnfx-dark.min.css new file mode 100644 index 0000000..4e6403d --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/nnfx-dark.min.css @@ -0,0 +1,10 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*! + Theme: nnfx dark + Description: a theme inspired by Netscape Navigator/Firefox + Author: (c) 2020-2021 Jim Mason + Maintainer: @RocketMan + License: https://creativecommons.org/licenses/by-sa/4.0 CC BY-SA 4.0 + Updated: 2021-05-17 + + @version 1.1.0 +*/.hljs{background:#333;color:#fff}.language-xml .hljs-meta,.language-xml .hljs-meta-string{font-weight:700;font-style:italic;color:#69f}.hljs-comment,.hljs-quote{font-style:italic;color:#9c6}.hljs-built_in,.hljs-keyword,.hljs-name{color:#a7a}.hljs-attr,.hljs-name{font-weight:700}.hljs-string{font-weight:400}.hljs-code,.hljs-link,.hljs-meta .hljs-string,.hljs-number,.hljs-regexp,.hljs-string{color:#bce}.hljs-bullet,.hljs-symbol,.hljs-template-variable,.hljs-title,.hljs-variable{color:#d40}.hljs-class .hljs-title,.hljs-title.class_,.hljs-type{font-weight:700;color:#96c}.hljs-attr,.hljs-function .hljs-title,.hljs-subst,.hljs-tag,.hljs-title.function_{color:#fff}.hljs-formula{background-color:#eee;font-style:italic}.hljs-addition{background-color:#797}.hljs-deletion{background-color:#c99}.hljs-meta{color:#69f}.hljs-section,.hljs-selector-class,.hljs-selector-id,.hljs-selector-pseudo,.hljs-selector-tag{font-weight:700;color:#69f}.hljs-selector-pseudo{font-style:italic}.hljs-doctag,.hljs-strong{font-weight:700}.hljs-emphasis{font-style:italic} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/nnfx-light.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/nnfx-light.min.css new file mode 100644 index 0000000..469223a --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/nnfx-light.min.css @@ -0,0 +1,10 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*! + Theme: nnfx light + Description: a theme inspired by Netscape Navigator/Firefox + Author: (c) 2020-2021 Jim Mason + Maintainer: @RocketMan + License: https://creativecommons.org/licenses/by-sa/4.0 CC BY-SA 4.0 + Updated: 2021-05-17 + + @version 1.1.0 +*/.hljs{background:#fff;color:#000}.language-xml .hljs-meta,.language-xml .hljs-meta-string{font-weight:700;font-style:italic;color:#48b}.hljs-comment,.hljs-quote{font-style:italic;color:#070}.hljs-built_in,.hljs-keyword,.hljs-name{color:#808}.hljs-attr,.hljs-name{font-weight:700}.hljs-string{font-weight:400}.hljs-code,.hljs-link,.hljs-meta .hljs-string,.hljs-number,.hljs-regexp,.hljs-string{color:#00f}.hljs-bullet,.hljs-symbol,.hljs-template-variable,.hljs-title,.hljs-variable{color:#f40}.hljs-class .hljs-title,.hljs-title.class_,.hljs-type{font-weight:700;color:#639}.hljs-attr,.hljs-function .hljs-title,.hljs-subst,.hljs-tag,.hljs-title.function_{color:#000}.hljs-formula{background-color:#eee;font-style:italic}.hljs-addition{background-color:#beb}.hljs-deletion{background-color:#fbb}.hljs-meta{color:#269}.hljs-section,.hljs-selector-class,.hljs-selector-id,.hljs-selector-pseudo,.hljs-selector-tag{font-weight:700;color:#48b}.hljs-selector-pseudo{font-style:italic}.hljs-doctag,.hljs-strong{font-weight:700}.hljs-emphasis{font-style:italic} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/nord.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/nord.min.css new file mode 100644 index 0000000..efbb0c1 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/nord.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#2e3440}.hljs,.hljs-subst{color:#d8dee9}.hljs-selector-tag{color:#81a1c1}.hljs-selector-id{color:#8fbcbb;font-weight:700}.hljs-selector-attr,.hljs-selector-class{color:#8fbcbb}.hljs-property,.hljs-selector-pseudo{color:#88c0d0}.hljs-addition{background-color:rgba(163,190,140,.5)}.hljs-deletion{background-color:rgba(191,97,106,.5)}.hljs-built_in,.hljs-class,.hljs-type{color:#8fbcbb}.hljs-function,.hljs-function>.hljs-title,.hljs-title.hljs-function{color:#88c0d0}.hljs-keyword,.hljs-literal,.hljs-symbol{color:#81a1c1}.hljs-number{color:#b48ead}.hljs-regexp{color:#ebcb8b}.hljs-string{color:#a3be8c}.hljs-title{color:#8fbcbb}.hljs-params{color:#d8dee9}.hljs-bullet{color:#81a1c1}.hljs-code{color:#8fbcbb}.hljs-emphasis{font-style:italic}.hljs-formula{color:#8fbcbb}.hljs-strong{font-weight:700}.hljs-link:hover{text-decoration:underline}.hljs-comment,.hljs-quote{color:#4c566a}.hljs-doctag{color:#8fbcbb}.hljs-meta,.hljs-meta .hljs-keyword{color:#5e81ac}.hljs-meta .hljs-string{color:#a3be8c}.hljs-attr{color:#8fbcbb}.hljs-attribute{color:#d8dee9}.hljs-name{color:#81a1c1}.hljs-section{color:#88c0d0}.hljs-tag{color:#81a1c1}.hljs-template-variable,.hljs-variable{color:#d8dee9}.hljs-template-tag{color:#5e81ac}.language-abnf .hljs-attribute{color:#88c0d0}.language-abnf .hljs-symbol{color:#ebcb8b}.language-apache .hljs-attribute{color:#88c0d0}.language-apache .hljs-section{color:#81a1c1}.language-arduino .hljs-built_in{color:#88c0d0}.language-aspectj .hljs-meta{color:#d08770}.language-aspectj>.hljs-title{color:#88c0d0}.language-bnf .hljs-attribute{color:#8fbcbb}.language-clojure .hljs-name{color:#88c0d0}.language-clojure .hljs-symbol{color:#ebcb8b}.language-coq .hljs-built_in{color:#88c0d0}.language-cpp .hljs-meta .hljs-string{color:#8fbcbb}.language-css .hljs-built_in{color:#88c0d0}.language-css .hljs-keyword{color:#d08770}.language-diff .hljs-meta,.language-ebnf .hljs-attribute{color:#8fbcbb}.language-glsl .hljs-built_in{color:#88c0d0}.language-groovy .hljs-meta:not(:first-child),.language-haxe .hljs-meta,.language-java .hljs-meta{color:#d08770}.language-ldif .hljs-attribute{color:#8fbcbb}.language-lisp .hljs-name,.language-lua .hljs-built_in,.language-moonscript .hljs-built_in,.language-nginx .hljs-attribute{color:#88c0d0}.language-nginx .hljs-section{color:#5e81ac}.language-pf .hljs-built_in,.language-processing .hljs-built_in{color:#88c0d0}.language-scss .hljs-keyword,.language-stylus .hljs-keyword{color:#81a1c1}.language-swift .hljs-meta{color:#d08770}.language-vim .hljs-built_in{color:#88c0d0;font-style:italic}.language-yaml .hljs-meta{color:#d08770} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/obsidian.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/obsidian.min.css new file mode 100644 index 0000000..c2a0786 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/obsidian.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#e0e2e4;background:#282b2e}.hljs-keyword,.hljs-literal,.hljs-selector-id,.hljs-selector-tag{color:#93c763}.hljs-number{color:#ffcd22}.hljs-attribute{color:#668bb0}.hljs-link,.hljs-regexp{color:#d39745}.hljs-meta{color:#557182}.hljs-addition,.hljs-built_in,.hljs-bullet,.hljs-emphasis,.hljs-name,.hljs-selector-attr,.hljs-selector-pseudo,.hljs-subst,.hljs-tag,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable{color:#8cbbad}.hljs-string,.hljs-symbol{color:#ec7600}.hljs-comment,.hljs-deletion,.hljs-quote{color:#818e96}.hljs-selector-class{color:#a082bd}.hljs-doctag,.hljs-keyword,.hljs-literal,.hljs-name,.hljs-section,.hljs-selector-tag,.hljs-strong,.hljs-title,.hljs-type{font-weight:700}.hljs-class .hljs-title,.hljs-code,.hljs-section,.hljs-title.class_{color:#fff} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/panda-syntax-dark.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/panda-syntax-dark.min.css new file mode 100644 index 0000000..55e26c6 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/panda-syntax-dark.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#e6e6e6;background:#2a2c2d}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}.hljs-link{text-decoration:underline}.hljs-comment,.hljs-quote{color:#bbb;font-style:italic}.hljs-params{color:#bbb}.hljs-attr,.hljs-punctuation{color:#e6e6e6}.hljs-meta,.hljs-name,.hljs-selector-tag{color:#ff4b82}.hljs-char.escape_,.hljs-operator{color:#b084eb}.hljs-deletion,.hljs-keyword{color:#ff75b5}.hljs-regexp,.hljs-selector-attr,.hljs-selector-pseudo,.hljs-variable.language_{color:#ff9ac1}.hljs-code,.hljs-formula,.hljs-property,.hljs-section,.hljs-subst,.hljs-title.function_{color:#45a9f9}.hljs-addition,.hljs-bullet,.hljs-meta .hljs-string,.hljs-selector-class,.hljs-string,.hljs-symbol,.hljs-title.class_,.hljs-title.class_.inherited__{color:#19f9d8}.hljs-attribute,.hljs-built_in,.hljs-doctag,.hljs-link,.hljs-literal,.hljs-meta .hljs-keyword,.hljs-number,.hljs-punctuation,.hljs-selector-id,.hljs-tag,.hljs-template-tag,.hljs-template-variable,.hljs-title,.hljs-type,.hljs-variable{color:#ffb86c} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/panda-syntax-light.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/panda-syntax-light.min.css new file mode 100644 index 0000000..6710dbd --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/panda-syntax-light.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#2a2c2d;background:#e6e6e6}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}.hljs-link{text-decoration:underline}.hljs-comment,.hljs-quote{color:#676b79;font-style:italic}.hljs-params{color:#676b79}.hljs-attr,.hljs-punctuation{color:#2a2c2d}.hljs-char.escape_,.hljs-meta,.hljs-name,.hljs-operator,.hljs-selector-tag{color:#c56200}.hljs-deletion,.hljs-keyword{color:#d92792}.hljs-regexp,.hljs-selector-attr,.hljs-selector-pseudo,.hljs-variable.language_{color:#cc5e91}.hljs-code,.hljs-formula,.hljs-property,.hljs-section,.hljs-subst,.hljs-title.function_{color:#3787c7}.hljs-addition,.hljs-bullet,.hljs-meta .hljs-string,.hljs-selector-class,.hljs-string,.hljs-symbol,.hljs-title.class_,.hljs-title.class_.inherited__{color:#0d7d6c}.hljs-attribute,.hljs-built_in,.hljs-doctag,.hljs-link,.hljs-literal,.hljs-meta .hljs-keyword,.hljs-number,.hljs-selector-id,.hljs-tag,.hljs-template-tag,.hljs-template-variable,.hljs-title,.hljs-type,.hljs-variable{color:#7641bb} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/paraiso-dark.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/paraiso-dark.min.css new file mode 100644 index 0000000..d51dd18 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/paraiso-dark.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#2f1e2e;color:#a39e9b}.hljs-comment,.hljs-quote{color:#8d8687}.hljs-link,.hljs-meta,.hljs-name,.hljs-regexp,.hljs-selector-class,.hljs-selector-id,.hljs-tag,.hljs-template-variable,.hljs-variable{color:#ef6155}.hljs-built_in,.hljs-deletion,.hljs-literal,.hljs-number,.hljs-params,.hljs-type{color:#f99b15}.hljs-attribute,.hljs-section,.hljs-title{color:#fec418}.hljs-addition,.hljs-bullet,.hljs-string,.hljs-symbol{color:#48b685}.hljs-keyword,.hljs-selector-tag{color:#815ba4}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/paraiso-light.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/paraiso-light.min.css new file mode 100644 index 0000000..3a17c3f --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/paraiso-light.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#e7e9db;color:#4f424c}.hljs-comment,.hljs-quote{color:#776e71}.hljs-link,.hljs-meta,.hljs-name,.hljs-regexp,.hljs-selector-class,.hljs-selector-id,.hljs-tag,.hljs-template-variable,.hljs-variable{color:#ef6155}.hljs-built_in,.hljs-deletion,.hljs-literal,.hljs-number,.hljs-params,.hljs-type{color:#f99b15}.hljs-attribute,.hljs-section,.hljs-title{color:#fec418}.hljs-addition,.hljs-bullet,.hljs-string,.hljs-symbol{color:#48b685}.hljs-keyword,.hljs-selector-tag{color:#815ba4}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/pojoaque.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/pojoaque.min.css new file mode 100644 index 0000000..71345a9 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/pojoaque.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#dccf8f;background:url(./pojoaque.jpg) left top #181914}.hljs-comment,.hljs-quote{color:#586e75;font-style:italic}.hljs-addition,.hljs-keyword,.hljs-literal,.hljs-selector-tag{color:#b64926}.hljs-doctag,.hljs-number,.hljs-regexp,.hljs-string{color:#468966}.hljs-built_in,.hljs-name,.hljs-section,.hljs-title{color:#ffb03b}.hljs-class .hljs-title,.hljs-tag,.hljs-template-variable,.hljs-title.class_,.hljs-type,.hljs-variable{color:#b58900}.hljs-attribute{color:#b89859}.hljs-bullet,.hljs-link,.hljs-meta,.hljs-subst,.hljs-symbol{color:#cb4b16}.hljs-deletion{color:#dc322f}.hljs-selector-class,.hljs-selector-id{color:#d3a60c}.hljs-formula{background:#073642}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/purebasic.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/purebasic.min.css new file mode 100644 index 0000000..e026c45 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/purebasic.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#ffffdf}.hljs,.hljs-attr,.hljs-function,.hljs-name,.hljs-number,.hljs-params,.hljs-subst,.hljs-type{color:#000}.hljs-addition,.hljs-comment,.hljs-regexp,.hljs-section,.hljs-selector-pseudo{color:#0aa}.hljs-built_in,.hljs-class,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-selector-class{color:#066;font-weight:700}.hljs-code,.hljs-tag,.hljs-title,.hljs-variable{color:#066}.hljs-selector-attr,.hljs-string{color:#0080ff}.hljs-attribute,.hljs-deletion,.hljs-link,.hljs-symbol{color:#924b72}.hljs-literal,.hljs-meta,.hljs-selector-id{color:#924b72;font-weight:700}.hljs-name,.hljs-strong{font-weight:700}.hljs-emphasis{font-style:italic} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/qtcreator-dark.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/qtcreator-dark.min.css new file mode 100644 index 0000000..976e519 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/qtcreator-dark.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#aaa;background:#000}.hljs-emphasis,.hljs-strong{color:#a8a8a2}.hljs-bullet,.hljs-literal,.hljs-number,.hljs-quote,.hljs-regexp{color:#f5f}.hljs-code .hljs-selector-class{color:#aaf}.hljs-emphasis,.hljs-stronge,.hljs-type{font-style:italic}.hljs-function,.hljs-keyword,.hljs-name,.hljs-section,.hljs-selector-tag,.hljs-symbol{color:#ff5}.hljs-subst,.hljs-tag,.hljs-title{color:#aaa}.hljs-attribute{color:#f55}.hljs-class .hljs-title,.hljs-params,.hljs-title.class_,.hljs-variable{color:#88f}.hljs-addition,.hljs-built_in,.hljs-link,.hljs-selector-attr,.hljs-selector-id,.hljs-selector-pseudo,.hljs-string,.hljs-template-tag,.hljs-template-variable,.hljs-type{color:#f5f}.hljs-comment,.hljs-deletion,.hljs-meta{color:#5ff} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/qtcreator-light.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/qtcreator-light.min.css new file mode 100644 index 0000000..7f1af8c --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/qtcreator-light.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#000;background:#fff}.hljs-emphasis,.hljs-strong{color:#000}.hljs-bullet,.hljs-literal,.hljs-number,.hljs-quote,.hljs-regexp{color:navy}.hljs-code .hljs-selector-class{color:purple}.hljs-emphasis,.hljs-stronge,.hljs-type{font-style:italic}.hljs-function,.hljs-keyword,.hljs-name,.hljs-section,.hljs-selector-tag,.hljs-symbol{color:olive}.hljs-subst,.hljs-tag,.hljs-title{color:#000}.hljs-attribute{color:maroon}.hljs-class .hljs-title,.hljs-params,.hljs-title.class_,.hljs-variable{color:#0055af}.hljs-addition,.hljs-built_in,.hljs-comment,.hljs-deletion,.hljs-link,.hljs-meta,.hljs-selector-attr,.hljs-selector-id,.hljs-selector-pseudo,.hljs-string,.hljs-template-tag,.hljs-template-variable,.hljs-type{color:green} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/rainbow.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/rainbow.min.css new file mode 100644 index 0000000..c8ca25f --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/rainbow.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#474949;color:#d1d9e1}.hljs-comment,.hljs-quote{color:#969896;font-style:italic}.hljs-addition,.hljs-keyword,.hljs-literal,.hljs-selector-tag,.hljs-type{color:#c9c}.hljs-number,.hljs-selector-attr,.hljs-selector-pseudo{color:#f99157}.hljs-doctag,.hljs-regexp,.hljs-string{color:#8abeb7}.hljs-built_in,.hljs-name,.hljs-section,.hljs-title{color:#b5bd68}.hljs-class .hljs-title,.hljs-selector-id,.hljs-template-variable,.hljs-title.class_,.hljs-variable{color:#fc6}.hljs-name,.hljs-section,.hljs-strong{font-weight:700}.hljs-bullet,.hljs-link,.hljs-meta,.hljs-subst,.hljs-symbol{color:#f99157}.hljs-deletion{color:#dc322f}.hljs-formula{background:#eee8d5}.hljs-attr,.hljs-attribute{color:#81a2be}.hljs-emphasis{font-style:italic} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/routeros.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/routeros.min.css new file mode 100644 index 0000000..0378678 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/routeros.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#444;background:#f0f0f0}.hljs-subst{color:#444}.hljs-comment{color:#888}.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-name,.hljs-selector-tag{font-weight:700}.hljs-attribute{color:#0e9a00}.hljs-function{color:#99069a}.hljs-deletion,.hljs-number,.hljs-quote,.hljs-selector-class,.hljs-selector-id,.hljs-string,.hljs-template-tag,.hljs-type{color:#800}.hljs-section,.hljs-title{color:#800;font-weight:700}.hljs-link,.hljs-regexp,.hljs-selector-attr,.hljs-selector-pseudo,.hljs-symbol,.hljs-template-variable,.hljs-variable{color:#bc6060}.hljs-literal{color:#78a960}.hljs-addition,.hljs-built_in,.hljs-bullet,.hljs-code{color:#0c9a9a}.hljs-meta{color:#1f7199}.hljs-meta .hljs-string{color:#4d99bf}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/school-book.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/school-book.min.css new file mode 100644 index 0000000..843f268 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/school-book.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#3e5915;background:#f6f5b2}.hljs-keyword,.hljs-literal,.hljs-selector-tag{color:#059}.hljs-subst{color:#3e5915}.hljs-addition,.hljs-attribute,.hljs-built_in,.hljs-bullet,.hljs-link,.hljs-section,.hljs-string,.hljs-symbol,.hljs-template-tag,.hljs-template-variable,.hljs-title,.hljs-type,.hljs-variable{color:#2c009f}.hljs-comment,.hljs-deletion,.hljs-meta,.hljs-quote{color:#e60415}.hljs-doctag,.hljs-keyword,.hljs-literal,.hljs-name,.hljs-section,.hljs-selector-id,.hljs-selector-tag,.hljs-strong,.hljs-title,.hljs-type{font-weight:700}.hljs-emphasis{font-style:italic} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/shades-of-purple.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/shades-of-purple.min.css new file mode 100644 index 0000000..3dd25b4 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/shades-of-purple.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#2d2b57;color:#e3dfff;font-weight:400}.hljs-subst{color:#e3dfff}.hljs-title{color:#fad000;font-weight:400}.hljs-name{color:#a1feff}.hljs-tag{color:#fff}.hljs-attr{color:#f8d000;font-style:italic}.hljs-built_in,.hljs-keyword,.hljs-section,.hljs-selector-tag{color:#fb9e00}.hljs-addition,.hljs-attribute,.hljs-bullet,.hljs-code,.hljs-deletion,.hljs-quote,.hljs-regexp,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-pseudo,.hljs-string,.hljs-symbol,.hljs-template-tag{color:#4cd213}.hljs-meta,.hljs-meta .hljs-string{color:#fb9e00}.hljs-comment{color:#ac65ff}.hljs-keyword,.hljs-literal,.hljs-name,.hljs-selector-tag,.hljs-strong{font-weight:400}.hljs-literal,.hljs-number{color:#fa658d}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/srcery.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/srcery.min.css new file mode 100644 index 0000000..377d61a --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/srcery.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#1c1b19;color:#fce8c3}.hljs-literal,.hljs-quote,.hljs-subst{color:#fce8c3}.hljs-symbol,.hljs-type{color:#68a8e4}.hljs-deletion,.hljs-keyword{color:#ef2f27}.hljs-attribute,.hljs-function,.hljs-name,.hljs-section,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-selector-pseudo,.hljs-title{color:#fbb829}.hljs-class,.hljs-code,.hljs-property,.hljs-template-variable,.hljs-variable{color:#0aaeb3}.hljs-addition,.hljs-bullet,.hljs-regexp,.hljs-string{color:#98bc37}.hljs-built_in,.hljs-params{color:#ff5c8f}.hljs-selector-tag,.hljs-template-tag{color:#2c78bf}.hljs-comment,.hljs-link,.hljs-meta,.hljs-number{color:#918175}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/stackoverflow-dark.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/stackoverflow-dark.min.css new file mode 100644 index 0000000..33cea55 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/stackoverflow-dark.min.css @@ -0,0 +1,13 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*! + Theme: StackOverflow Dark + Description: Dark theme as used on stackoverflow.com + Author: stackoverflow.com + Maintainer: @Hirse + Website: https://github.com/StackExchange/Stacks + License: MIT + Updated: 2021-05-15 + + Updated for @stackoverflow/stacks v0.64.0 + Code Blocks: /blob/v0.64.0/lib/css/components/_stacks-code-blocks.less + Colors: /blob/v0.64.0/lib/css/exports/_stacks-constants-colors.less +*/.hljs{color:#fff;background:#1c1b1b}.hljs-subst{color:#fff}.hljs-comment{color:#999}.hljs-attr,.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-section,.hljs-selector-tag{color:#88aece}.hljs-attribute{color:#c59bc1}.hljs-name,.hljs-number,.hljs-quote,.hljs-selector-id,.hljs-template-tag,.hljs-type{color:#f08d49}.hljs-selector-class{color:#88aece}.hljs-link,.hljs-regexp,.hljs-selector-attr,.hljs-string,.hljs-symbol,.hljs-template-variable,.hljs-variable{color:#b5bd68}.hljs-meta,.hljs-selector-pseudo{color:#88aece}.hljs-built_in,.hljs-literal,.hljs-title{color:#f08d49}.hljs-bullet,.hljs-code{color:#ccc}.hljs-meta .hljs-string{color:#b5bd68}.hljs-deletion{color:#de7176}.hljs-addition{color:#76c490}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/stackoverflow-light.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/stackoverflow-light.min.css new file mode 100644 index 0000000..c36d63d --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/stackoverflow-light.min.css @@ -0,0 +1,13 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*! + Theme: StackOverflow Light + Description: Light theme as used on stackoverflow.com + Author: stackoverflow.com + Maintainer: @Hirse + Website: https://github.com/StackExchange/Stacks + License: MIT + Updated: 2021-05-15 + + Updated for @stackoverflow/stacks v0.64.0 + Code Blocks: /blob/v0.64.0/lib/css/components/_stacks-code-blocks.less + Colors: /blob/v0.64.0/lib/css/exports/_stacks-constants-colors.less +*/.hljs{color:#2f3337;background:#f6f6f6}.hljs-subst{color:#2f3337}.hljs-comment{color:#656e77}.hljs-attr,.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-section,.hljs-selector-tag{color:#015692}.hljs-attribute{color:#803378}.hljs-name,.hljs-number,.hljs-quote,.hljs-selector-id,.hljs-template-tag,.hljs-type{color:#b75501}.hljs-selector-class{color:#015692}.hljs-link,.hljs-regexp,.hljs-selector-attr,.hljs-string,.hljs-symbol,.hljs-template-variable,.hljs-variable{color:#54790d}.hljs-meta,.hljs-selector-pseudo{color:#015692}.hljs-built_in,.hljs-literal,.hljs-title{color:#b75501}.hljs-bullet,.hljs-code{color:#535a60}.hljs-meta .hljs-string{color:#54790d}.hljs-deletion{color:#c02d2e}.hljs-addition{color:#2f6f44}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/sunburst.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/sunburst.min.css new file mode 100644 index 0000000..9210ae6 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/sunburst.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#000;color:#f8f8f8}.hljs-comment,.hljs-quote{color:#aeaeae;font-style:italic}.hljs-keyword,.hljs-selector-tag,.hljs-type{color:#e28964}.hljs-string{color:#65b042}.hljs-subst{color:#daefa3}.hljs-link,.hljs-regexp{color:#e9c062}.hljs-name,.hljs-section,.hljs-tag,.hljs-title{color:#89bdff}.hljs-class .hljs-title,.hljs-doctag,.hljs-title.class_{text-decoration:underline}.hljs-bullet,.hljs-number,.hljs-symbol{color:#3387cc}.hljs-params,.hljs-template-variable,.hljs-variable{color:#3e87e3}.hljs-attribute{color:#cda869}.hljs-meta{color:#8996a8}.hljs-formula{background-color:#0e2231;color:#f8f8f8;font-style:italic}.hljs-addition{background-color:#253b22;color:#f8f8f8}.hljs-deletion{background-color:#420e09;color:#f8f8f8}.hljs-selector-class{color:#9b703f}.hljs-selector-id{color:#8b98ab}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/tokyo-night-dark.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/tokyo-night-dark.min.css new file mode 100644 index 0000000..dc63ad9 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/tokyo-night-dark.min.css @@ -0,0 +1,8 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*! + Theme: Tokyo-night-Dark + origin: https://github.com/enkia/tokyo-night-vscode-theme + Description: Original highlight.js style + Author: (c) Henri Vandersleyen + License: see project LICENSE + Touched: 2022 +*/.hljs-comment,.hljs-meta{color:#565f89}.hljs-deletion,.hljs-doctag,.hljs-regexp,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-selector-pseudo,.hljs-tag,.hljs-template-tag,.hljs-variable.language_{color:#f7768e}.hljs-link,.hljs-literal,.hljs-number,.hljs-params,.hljs-template-variable,.hljs-type,.hljs-variable{color:#ff9e64}.hljs-attribute,.hljs-built_in{color:#e0af68}.hljs-keyword,.hljs-property,.hljs-subst,.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-title.function_{color:#7dcfff}.hljs-selector-tag{color:#73daca}.hljs-addition,.hljs-bullet,.hljs-quote,.hljs-string,.hljs-symbol{color:#9ece6a}.hljs-code,.hljs-formula,.hljs-section{color:#7aa2f7}.hljs-attr,.hljs-char.escape_,.hljs-keyword,.hljs-name,.hljs-operator{color:#bb9af7}.hljs-punctuation{color:#c0caf5}.hljs{background:#1a1b26;color:#9aa5ce}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/tokyo-night-light.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/tokyo-night-light.min.css new file mode 100644 index 0000000..0096d4d --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/tokyo-night-light.min.css @@ -0,0 +1,8 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*! + Theme: Tokyo-night-light + origin: https://github.com/enkia/tokyo-night-vscode-theme + Description: Original highlight.js style + Author: (c) Henri Vandersleyen + License: see project LICENSE + Touched: 2022 +*/.hljs-comment,.hljs-meta{color:#9699a3}.hljs-deletion,.hljs-doctag,.hljs-regexp,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-selector-pseudo,.hljs-tag,.hljs-template-tag,.hljs-variable.language_{color:#8c4351}.hljs-link,.hljs-literal,.hljs-number,.hljs-params,.hljs-template-variable,.hljs-type,.hljs-variable{color:#965027}.hljs-attribute,.hljs-built_in{color:#8f5e15}.hljs-keyword,.hljs-property,.hljs-subst,.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-title.function_{color:#0f4b6e}.hljs-selector-tag{color:#33635c}.hljs-addition,.hljs-bullet,.hljs-quote,.hljs-string,.hljs-symbol{color:#485e30}.hljs-code,.hljs-formula,.hljs-section{color:#34548a}.hljs-attr,.hljs-char.escape_,.hljs-keyword,.hljs-name,.hljs-operator{color:#5a4a78}.hljs-punctuation{color:#343b58}.hljs{background:#d5d6db;color:#565a6e}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/tomorrow-night-blue.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/tomorrow-night-blue.min.css new file mode 100644 index 0000000..2f71b26 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/tomorrow-night-blue.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs-comment,.hljs-quote{color:#7285b7}.hljs-deletion,.hljs-name,.hljs-regexp,.hljs-selector-class,.hljs-selector-id,.hljs-tag,.hljs-template-variable,.hljs-variable{color:#ff9da4}.hljs-built_in,.hljs-link,.hljs-literal,.hljs-meta,.hljs-number,.hljs-params,.hljs-type{color:#ffc58f}.hljs-attribute{color:#ffeead}.hljs-addition,.hljs-bullet,.hljs-string,.hljs-symbol{color:#d1f1a9}.hljs-section,.hljs-title{color:#bbdaff}.hljs-keyword,.hljs-selector-tag{color:#ebbbff}.hljs{background:#002451;color:#fff}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/tomorrow-night-bright.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/tomorrow-night-bright.min.css new file mode 100644 index 0000000..d335629 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/tomorrow-night-bright.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs-comment,.hljs-quote{color:#969896}.hljs-deletion,.hljs-name,.hljs-regexp,.hljs-selector-class,.hljs-selector-id,.hljs-tag,.hljs-template-variable,.hljs-variable{color:#d54e53}.hljs-built_in,.hljs-link,.hljs-literal,.hljs-meta,.hljs-number,.hljs-params,.hljs-type{color:#e78c45}.hljs-attribute{color:#e7c547}.hljs-addition,.hljs-bullet,.hljs-string,.hljs-symbol{color:#b9ca4a}.hljs-section,.hljs-title{color:#7aa6da}.hljs-keyword,.hljs-selector-tag{color:#c397d8}.hljs{background:#000;color:#eaeaea}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/vs.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/vs.min.css new file mode 100644 index 0000000..fb695c1 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/vs.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#fff;color:#000}.hljs-comment,.hljs-quote,.hljs-variable{color:green}.hljs-built_in,.hljs-keyword,.hljs-name,.hljs-selector-tag,.hljs-tag{color:#00f}.hljs-addition,.hljs-attribute,.hljs-literal,.hljs-section,.hljs-string,.hljs-template-tag,.hljs-template-variable,.hljs-title,.hljs-type{color:#a31515}.hljs-deletion,.hljs-meta,.hljs-selector-attr,.hljs-selector-pseudo{color:#2b91af}.hljs-doctag{color:grey}.hljs-attr{color:red}.hljs-bullet,.hljs-link,.hljs-symbol{color:#00b0e8}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/vs2015.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/vs2015.min.css new file mode 100644 index 0000000..7f6fe11 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/vs2015.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#1e1e1e;color:#dcdcdc}.hljs-keyword,.hljs-literal,.hljs-name,.hljs-symbol{color:#569cd6}.hljs-link{color:#569cd6;text-decoration:underline}.hljs-built_in,.hljs-type{color:#4ec9b0}.hljs-class,.hljs-number{color:#b8d7a3}.hljs-meta .hljs-string,.hljs-string{color:#d69d85}.hljs-regexp,.hljs-template-tag{color:#9a5334}.hljs-formula,.hljs-function,.hljs-params,.hljs-subst,.hljs-title{color:#dcdcdc}.hljs-comment,.hljs-quote{color:#57a64a;font-style:italic}.hljs-doctag{color:#608b4e}.hljs-meta,.hljs-meta .hljs-keyword,.hljs-tag{color:#9b9b9b}.hljs-template-variable,.hljs-variable{color:#bd63c5}.hljs-attr,.hljs-attribute{color:#9cdcfe}.hljs-section{color:gold}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}.hljs-bullet,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-selector-pseudo,.hljs-selector-tag{color:#d7ba7d}.hljs-addition{background-color:#144212;display:inline-block;width:100%}.hljs-deletion{background-color:#600;display:inline-block;width:100%} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/xcode.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/xcode.min.css new file mode 100644 index 0000000..cda4adc --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/xcode.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#fff;color:#000}.xml .hljs-meta{color:silver}.hljs-comment,.hljs-quote{color:#007400}.hljs-attribute,.hljs-keyword,.hljs-literal,.hljs-name,.hljs-selector-tag,.hljs-tag{color:#aa0d91}.hljs-template-variable,.hljs-variable{color:#3f6e74}.hljs-code,.hljs-meta .hljs-string,.hljs-string{color:#c41a16}.hljs-link,.hljs-regexp{color:#0e0eff}.hljs-bullet,.hljs-number,.hljs-symbol,.hljs-title{color:#1c00cf}.hljs-meta,.hljs-section{color:#643820}.hljs-built_in,.hljs-class .hljs-title,.hljs-params,.hljs-title.class_,.hljs-type{color:#5c2699}.hljs-attr{color:#836c28}.hljs-subst{color:#000}.hljs-formula{background-color:#eee;font-style:italic}.hljs-addition{background-color:#baeeba}.hljs-deletion{background-color:#ffc8bd}.hljs-selector-class,.hljs-selector-id{color:#9b703f}.hljs-doctag,.hljs-strong{font-weight:700}.hljs-emphasis{font-style:italic} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/xt256.min.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/xt256.min.css new file mode 100644 index 0000000..ef34f0c --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/code-themes/xt256.min.css @@ -0,0 +1 @@ +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#eaeaea;background:#000}.hljs-subst{color:#eaeaea}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}.hljs-type{color:#eaeaea}.hljs-params{color:#da0000}.hljs-literal,.hljs-name,.hljs-number{color:red;font-weight:bolder}.hljs-comment{color:#969896}.hljs-quote,.hljs-selector-id{color:#0ff}.hljs-template-variable,.hljs-title,.hljs-variable{color:#0ff;font-weight:700}.hljs-keyword,.hljs-selector-class,.hljs-symbol{color:#fff000}.hljs-bullet,.hljs-string{color:#0f0}.hljs-section,.hljs-tag{color:#000fff}.hljs-selector-tag{color:#000fff;font-weight:700}.hljs-attribute,.hljs-built_in,.hljs-link,.hljs-regexp{color:#f0f}.hljs-meta{color:#fff;font-weight:bolder} \ No newline at end of file diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/constants.ts b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/constants.ts new file mode 100644 index 0000000..2edd803 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/constants.ts @@ -0,0 +1,84 @@ +import type { StyleConfig } from "./types.js"; + +export const FONT_FAMILY_MAP: Record = { + sans: `-apple-system-font,BlinkMacSystemFont, Helvetica Neue, PingFang SC, Hiragino Sans GB , Microsoft YaHei UI , Microsoft YaHei ,Arial,sans-serif`, + serif: `Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, 'PingFang SC', Cambria, Cochin, Georgia, Times, 'Times New Roman', serif`, + "serif-cjk": `"Source Han Serif SC", "Noto Serif CJK SC", "Source Han Serif CN", STSong, SimSun, serif`, + mono: `Menlo, Monaco, 'Courier New', monospace`, +}; + +export const FONT_SIZE_OPTIONS = ["14px", "15px", "16px", "17px", "18px"]; + +export const COLOR_PRESETS: Record = { + blue: "#0F4C81", + green: "#009874", + vermilion: "#FA5151", + yellow: "#FECE00", + purple: "#92617E", + sky: "#55C9EA", + rose: "#B76E79", + olive: "#556B2F", + black: "#333333", + gray: "#A9A9A9", + pink: "#FFB7C5", + red: "#A93226", + orange: "#D97757", +}; + +export const CODE_BLOCK_THEMES = [ + "1c-light", "a11y-dark", "a11y-light", "agate", "an-old-hope", + "androidstudio", "arduino-light", "arta", "ascetic", + "atom-one-dark-reasonable", "atom-one-dark", "atom-one-light", + "brown-paper", "codepen-embed", "color-brewer", "dark", "default", + "devibeans", "docco", "far", "felipec", "foundation", + "github-dark-dimmed", "github-dark", "github", "gml", "googlecode", + "gradient-dark", "gradient-light", "grayscale", "hybrid", "idea", + "intellij-light", "ir-black", "isbl-editor-dark", "isbl-editor-light", + "kimbie-dark", "kimbie-light", "lightfair", "lioshi", "magula", + "mono-blue", "monokai-sublime", "monokai", "night-owl", "nnfx-dark", + "nnfx-light", "nord", "obsidian", "panda-syntax-dark", + "panda-syntax-light", "paraiso-dark", "paraiso-light", "pojoaque", + "purebasic", "qtcreator-dark", "qtcreator-light", "rainbow", "routeros", + "school-book", "shades-of-purple", "srcery", "stackoverflow-dark", + "stackoverflow-light", "sunburst", "tokyo-night-dark", "tokyo-night-light", + "tomorrow-night-blue", "tomorrow-night-bright", "vs", "vs2015", "xcode", + "xt256", +]; + +export const DEFAULT_STYLE: StyleConfig = { + primaryColor: "#0F4C81", + fontFamily: FONT_FAMILY_MAP.sans!, + fontSize: "16px", + foreground: "0 0% 3.9%", + blockquoteBackground: "#f7f7f7", + accentColor: "#6B7280", + containerBg: "transparent", +}; + +export const THEME_STYLE_DEFAULTS: Record> = { + default: { + primaryColor: COLOR_PRESETS.blue, + }, + grace: { + primaryColor: COLOR_PRESETS.purple, + }, + simple: { + primaryColor: COLOR_PRESETS.green, + }, + modern: { + primaryColor: COLOR_PRESETS.orange, + accentColor: "#E4B1A0", + containerBg: "rgba(250, 249, 245, 1)", + fontFamily: FONT_FAMILY_MAP.sans, + fontSize: "15px", + blockquoteBackground: "rgba(255, 255, 255, 0.6)", + }, +}; + +export const macCodeSvg = ` + + + + + +`.trim(); diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/content.ts b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/content.ts new file mode 100644 index 0000000..6be2b51 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/content.ts @@ -0,0 +1,105 @@ +import { Lexer } from "marked"; + +export type FrontmatterFields = Record; + +export function parseFrontmatter(content: string): { + frontmatter: FrontmatterFields; + body: string; +} { + const match = content.match(/^\s*---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/); + if (!match) { + return { frontmatter: {}, body: content }; + } + + const frontmatter: FrontmatterFields = {}; + const lines = match[1]!.split("\n"); + for (const line of lines) { + const colonIdx = line.indexOf(":"); + if (colonIdx <= 0) continue; + + const key = line.slice(0, colonIdx).trim(); + const value = line.slice(colonIdx + 1).trim(); + frontmatter[key] = stripWrappingQuotes(value); + } + + return { frontmatter, body: match[2]! }; +} + +export function serializeFrontmatter(frontmatter: FrontmatterFields): string { + const entries = Object.entries(frontmatter); + if (entries.length === 0) return ""; + return `---\n${entries.map(([key, value]) => `${key}: ${value}`).join("\n")}\n---\n`; +} + +export function stripWrappingQuotes(value: string): string { + if (!value) return value; + + const doubleQuoted = value.startsWith('"') && value.endsWith('"'); + const singleQuoted = value.startsWith("'") && value.endsWith("'"); + const cjkDoubleQuoted = value.startsWith("\u201c") && value.endsWith("\u201d"); + const cjkSingleQuoted = value.startsWith("\u2018") && value.endsWith("\u2019"); + + if (doubleQuoted || singleQuoted || cjkDoubleQuoted || cjkSingleQuoted) { + return value.slice(1, -1).trim(); + } + + return value.trim(); +} + +export function toFrontmatterString(value: unknown): string | undefined { + if (typeof value === "string") { + return stripWrappingQuotes(value); + } + if (typeof value === "number" || typeof value === "boolean") { + return String(value); + } + return undefined; +} + +export function pickFirstString( + frontmatter: Record, + keys: string[], +): string | undefined { + for (const key of keys) { + const value = toFrontmatterString(frontmatter[key]); + if (value) return value; + } + return undefined; +} + +export function extractTitleFromMarkdown(markdown: string): string { + const tokens = Lexer.lex(markdown, { gfm: true, breaks: true }); + for (const token of tokens) { + if (token.type !== "heading" || (token.depth !== 1 && token.depth !== 2)) continue; + return stripWrappingQuotes(token.text); + } + return ""; +} + +export function extractSummaryFromBody(body: string, maxLen: number): string { + const lines = body.split("\n"); + + for (const line of lines) { + const trimmed = line.trim(); + if (!trimmed) continue; + if (trimmed.startsWith("#")) continue; + if (trimmed.startsWith("![")) continue; + if (trimmed.startsWith(">")) continue; + if (trimmed.startsWith("-") || trimmed.startsWith("*")) continue; + if (/^\d+\./.test(trimmed)) continue; + if (trimmed.startsWith("```")) continue; + + const cleanText = trimmed + .replace(/\*\*(.+?)\*\*/g, "$1") + .replace(/\*(.+?)\*/g, "$1") + .replace(/\[([^\]]+)\]\([^)]+\)/g, "$1") + .replace(/`([^`]+)`/g, "$1"); + + if (cleanText.length > 20) { + if (cleanText.length <= maxLen) return cleanText; + return `${cleanText.slice(0, maxLen - 3)}...`; + } + } + + return ""; +} diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/document.ts b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/document.ts new file mode 100644 index 0000000..e370740 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/document.ts @@ -0,0 +1,206 @@ +import fs from "node:fs"; +import path from "node:path"; + +import type { ReadTimeResults } from "reading-time"; + +import { + COLOR_PRESETS, + DEFAULT_STYLE, + FONT_FAMILY_MAP, + THEME_STYLE_DEFAULTS, +} from "./constants.js"; +import { + extractSummaryFromBody, + extractTitleFromMarkdown, + pickFirstString, + stripWrappingQuotes, +} from "./content.js"; +import { loadExtendConfig } from "./extend-config.js"; +import { + buildCss, + buildHtmlDocument, + inlineCss, + loadCodeThemeCss, + modifyHtmlStructure, + normalizeInlineCss, + removeFirstHeading, +} from "./html-builder.js"; +import { initRenderer, postProcessHtml, renderMarkdown } from "./renderer.js"; +import { loadThemeCss, normalizeThemeCss } from "./themes.js"; +import type { HtmlDocumentMeta, IOpts, StyleConfig, ThemeName } from "./types.js"; + +export interface RenderMarkdownDocumentOptions { + codeTheme?: string; + countStatus?: boolean; + citeStatus?: boolean; + defaultTitle?: string; + fontFamily?: string; + fontSize?: string; + isMacCodeBlock?: boolean; + isShowLineNumber?: boolean; + keepTitle?: boolean; + legend?: string; + primaryColor?: string; + theme?: ThemeName; + themeMode?: IOpts["themeMode"]; +} + +export interface RenderMarkdownDocumentResult { + contentHtml: string; + html: string; + meta: HtmlDocumentMeta; + readingTime: ReadTimeResults; + style: StyleConfig; + yamlData: Record; +} + +export function resolveColorToken(value?: string): string | undefined { + if (!value) return undefined; + return COLOR_PRESETS[value] ?? value; +} + +export function resolveFontFamilyToken(value?: string): string | undefined { + if (!value) return undefined; + return FONT_FAMILY_MAP[value] ?? value; +} + +export function formatTimestamp(date = new Date()): string { + const pad = (value: number) => String(value).padStart(2, "0"); + return `${date.getFullYear()}${pad(date.getMonth() + 1)}${pad( + date.getDate(), + )}${pad(date.getHours())}${pad(date.getMinutes())}${pad(date.getSeconds())}`; +} + +export function buildMarkdownDocumentMeta( + markdown: string, + yamlData: Record, + defaultTitle = "document", +): HtmlDocumentMeta { + const title = pickFirstString(yamlData, ["title"]) + || extractTitleFromMarkdown(markdown) + || defaultTitle; + const author = pickFirstString(yamlData, ["author"]); + const description = pickFirstString(yamlData, ["description", "summary"]) + || extractSummaryFromBody(markdown, 120); + + return { + title: stripWrappingQuotes(title), + author: author ? stripWrappingQuotes(author) : undefined, + description: description ? stripWrappingQuotes(description) : undefined, + }; +} + +export function resolveMarkdownStyle(options: RenderMarkdownDocumentOptions = {}): StyleConfig { + const theme = options.theme ?? "default"; + const themeDefaults = THEME_STYLE_DEFAULTS[theme] ?? {}; + + return { + ...DEFAULT_STYLE, + ...themeDefaults, + ...(options.primaryColor !== undefined ? { primaryColor: options.primaryColor } : {}), + ...(options.fontFamily !== undefined ? { fontFamily: options.fontFamily } : {}), + ...(options.fontSize !== undefined ? { fontSize: options.fontSize } : {}), + }; +} + +export function resolveRenderOptions( + options: RenderMarkdownDocumentOptions = {}, +): RenderMarkdownDocumentOptions { + const extendConfig = loadExtendConfig(); + + return { + codeTheme: options.codeTheme ?? extendConfig.default_code_theme ?? "github", + countStatus: options.countStatus ?? extendConfig.count ?? false, + citeStatus: options.citeStatus ?? extendConfig.cite ?? false, + defaultTitle: options.defaultTitle, + fontFamily: options.fontFamily ?? resolveFontFamilyToken(extendConfig.default_font_family ?? undefined), + fontSize: options.fontSize ?? extendConfig.default_font_size ?? undefined, + isMacCodeBlock: options.isMacCodeBlock ?? extendConfig.mac_code_block ?? true, + isShowLineNumber: options.isShowLineNumber ?? extendConfig.show_line_number ?? false, + keepTitle: options.keepTitle ?? extendConfig.keep_title ?? false, + legend: options.legend ?? extendConfig.legend ?? "alt", + primaryColor: options.primaryColor ?? resolveColorToken(extendConfig.default_color ?? undefined), + theme: options.theme ?? extendConfig.default_theme ?? "default", + themeMode: options.themeMode, + }; +} + +export async function renderMarkdownDocument( + markdown: string, + options: RenderMarkdownDocumentOptions = {}, +): Promise { + const resolvedOptions = resolveRenderOptions(options); + const theme = resolvedOptions.theme ?? "default"; + const codeTheme = resolvedOptions.codeTheme ?? "github"; + const style = resolveMarkdownStyle(resolvedOptions); + + const { baseCss, themeCss } = loadThemeCss(theme); + const css = normalizeThemeCss(buildCss(baseCss, themeCss, style)); + const codeThemeCss = loadCodeThemeCss(codeTheme); + + const renderer = initRenderer({ + citeStatus: resolvedOptions.citeStatus ?? false, + countStatus: resolvedOptions.countStatus ?? false, + isMacCodeBlock: resolvedOptions.isMacCodeBlock ?? true, + isShowLineNumber: resolvedOptions.isShowLineNumber ?? false, + legend: resolvedOptions.legend ?? "alt", + themeMode: resolvedOptions.themeMode, + }); + + const { yamlData, markdownContent, readingTime } = renderer.parseFrontMatterAndContent(markdown); + const { html: baseHtml, readingTime: readingTimeResult } = renderMarkdown(markdown, renderer); + + let contentHtml = postProcessHtml(baseHtml, readingTimeResult, renderer); + if (!(resolvedOptions.keepTitle ?? false)) { + contentHtml = removeFirstHeading(contentHtml); + } + + const meta = buildMarkdownDocumentMeta( + markdownContent, + yamlData as Record, + resolvedOptions.defaultTitle, + ); + const html = buildHtmlDocument(meta, css, contentHtml, codeThemeCss); + const inlinedHtml = normalizeInlineCss(await inlineCss(html), style); + + return { + contentHtml, + html: modifyHtmlStructure(inlinedHtml), + meta, + readingTime, + style, + yamlData: yamlData as Record, + }; +} + +export async function renderMarkdownFileToHtml( + inputPath: string, + options: RenderMarkdownDocumentOptions = {}, +): Promise { + const markdown = fs.readFileSync(inputPath, "utf-8"); + const outputPath = path.resolve( + path.dirname(inputPath), + `${path.basename(inputPath, path.extname(inputPath))}.html`, + ); + const result = await renderMarkdownDocument(markdown, { + ...options, + defaultTitle: options.defaultTitle ?? path.basename(outputPath, ".html"), + }); + + let backupPath: string | undefined; + if (fs.existsSync(outputPath)) { + backupPath = `${outputPath}.bak-${formatTimestamp()}`; + fs.renameSync(outputPath, backupPath); + } + + fs.writeFileSync(outputPath, result.html, "utf-8"); + + return { + ...result, + backupPath, + outputPath, + }; +} diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/extend-config.ts b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/extend-config.ts new file mode 100644 index 0000000..b4a0018 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/extend-config.ts @@ -0,0 +1,57 @@ +import fs from "node:fs"; +import { homedir } from "node:os"; +import path from "node:path"; +import type { ExtendConfig } from "./types.js"; + +function extractYamlFrontMatter(content: string): string | null { + const match = content.match(/^---\s*\n([\s\S]*?)\n---\s*$/m); + return match ? match[1]! : null; +} + +function parseExtendYaml(yaml: string): Partial { + const config: Partial = {}; + for (const line of yaml.split("\n")) { + const trimmed = line.trim(); + if (!trimmed || trimmed.startsWith("#")) continue; + const colonIdx = trimmed.indexOf(":"); + if (colonIdx < 0) continue; + const key = trimmed.slice(0, colonIdx).trim(); + let value = trimmed.slice(colonIdx + 1).trim().replace(/^['"]|['"]$/g, ""); + if (value === "null" || value === "") continue; + + if (key === "default_theme") config.default_theme = value; + else if (key === "default_color") config.default_color = value; + else if (key === "default_font_family") config.default_font_family = value; + else if (key === "default_font_size") config.default_font_size = value.endsWith("px") ? value : `${value}px`; + else if (key === "default_code_theme") config.default_code_theme = value; + else if (key === "mac_code_block") config.mac_code_block = value === "true"; + else if (key === "show_line_number") config.show_line_number = value === "true"; + else if (key === "cite") config.cite = value === "true"; + else if (key === "count") config.count = value === "true"; + else if (key === "legend") config.legend = value; + else if (key === "keep_title") config.keep_title = value === "true"; + } + return config; +} + +export function loadExtendConfig(): Partial { + const paths = [ + path.join(process.cwd(), ".baoyu-skills", "baoyu-markdown-to-html", "EXTEND.md"), + path.join( + process.env.XDG_CONFIG_HOME || path.join(homedir(), ".config"), + "baoyu-skills", "baoyu-markdown-to-html", "EXTEND.md" + ), + path.join(homedir(), ".baoyu-skills", "baoyu-markdown-to-html", "EXTEND.md"), + ]; + for (const p of paths) { + try { + const content = fs.readFileSync(p, "utf-8"); + const yaml = extractYamlFrontMatter(content); + if (!yaml) continue; + return parseExtendYaml(yaml); + } catch { + continue; + } + } + return {}; +} diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/extensions/alert.ts b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/extensions/alert.ts new file mode 100644 index 0000000..39785c4 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/extensions/alert.ts @@ -0,0 +1,284 @@ +import type { MarkedExtension, Tokens } from 'marked' + +export interface AlertOptions { + className?: string + variants?: AlertVariantItem[] + withoutStyle?: boolean +} + +export interface AlertVariantItem { + type: string + icon: string + title?: string + titleClassName?: string +} + +function ucfirst(str: string) { + return str.slice(0, 1).toUpperCase() + str.slice(1).toLowerCase() +} + +/** + * https://github.com/bent10/marked-extensions/tree/main/packages/alert + * To support theme, we need to modify the source code. + * A [marked](https://marked.js.org/) extension to support [GFM alerts](https://github.com/orgs/community/discussions/16925). + */ +export function markedAlert(options: AlertOptions = {}): MarkedExtension { + const { className = `markdown-alert`, variants = [], withoutStyle = false } = options + const resolvedVariants = resolveVariants(variants) + + // 提取公共的元数据构建逻辑 + function buildMeta(variantType: string, matchedVariant: AlertVariantItem, fromContainer = false) { + return { + className, + variant: variantType, + icon: matchedVariant.icon, + title: matchedVariant.title ?? ucfirst(variantType), + titleClassName: `${className}-title`, + fromContainer, + } + } + + // 提取公共的渲染逻辑 + function renderAlert(token: any) { + const { meta, tokens = [] } = token + // @ts-expect-error marked renderer context has parser property + const text = this.parser.parse(tokens) + // 新主题系统:使用 CSS 选择器而非内联样式 + let tmpl = `
\n` + tmpl += `

` + if (!withoutStyle) { + // 给 SVG 添加 class,通过 CSS 控制颜色 + tmpl += meta.icon.replace( + `\n` + tmpl += text + tmpl += `

\n` + + return tmpl + } + + return { + walkTokens(token) { + if (token.type !== `blockquote`) + return + + const matchedVariant = resolvedVariants.find(({ type }) => + new RegExp(createSyntaxPattern(type), `i`).test(token.text), + ) + + if (matchedVariant) { + const { type: variantType } = matchedVariant + const typeRegexp = new RegExp(createSyntaxPattern(variantType), `i`) + + Object.assign(token, { + type: `alert`, + meta: buildMeta(variantType, matchedVariant), + }) + + const firstLine = token.tokens?.[0] as Tokens.Paragraph + const firstLineText = firstLine.raw?.replace(typeRegexp, ``).trim() + + if (firstLineText) { + const patternToken = firstLine.tokens[0] as Tokens.Text + + Object.assign(patternToken, { + raw: patternToken.raw.replace(typeRegexp, ``), + text: patternToken.text.replace(typeRegexp, ``), + }) + + if (firstLine.tokens[1]?.type === `br`) { + firstLine.tokens.splice(1, 1) + } + } + else { + token.tokens?.shift() + } + } + }, + extensions: [ + { + name: `alert`, + level: `block`, + renderer: renderAlert, + }, + { + name: `alertContainer`, + level: `block`, + start(src) { + return src.match(/^:::/)?.index + }, + tokenizer(src, _tokens) { + // eslint-disable-next-line regexp/no-super-linear-backtracking + const match = /^:::\s*(\w+)\s*\n([\s\S]*?)\n:::/.exec(src) + + if (match) { + const [raw, variant, content] = match + const matchedVariant = resolvedVariants.find(v => v.type === variant) + if (!matchedVariant) + return + + return { + type: `alert`, + raw, + text: content.trim(), + tokens: this.lexer.blockTokens(content.trim()), + meta: buildMeta(variant, matchedVariant, true), + } + } + }, + renderer: renderAlert, + }, + ], + } +} + +/** + * The default configuration for alert variants. + */ +const defaultAlertVariant: AlertVariantItem[] = [ + { + type: `note`, + icon: ``, + }, + { + type: `info`, + icon: ``, + }, + { + type: `tip`, + icon: ``, + }, + { + type: `important`, + icon: ``, + }, + { + type: `warning`, + icon: ``, + }, + { + type: `caution`, + icon: ``, + }, + // Obsidian-style callouts + { + type: `abstract`, + title: `Abstract`, + icon: ``, + }, + { + type: `summary`, + title: `Summary`, + icon: ``, + }, + { + type: `tldr`, + title: `TL;DR`, + icon: ``, + }, + { + type: `todo`, + title: `Todo`, + icon: ``, + }, + { + type: `success`, + title: `Success`, + icon: ``, + }, + { + type: `done`, + title: `Done`, + icon: ``, + }, + { + type: `question`, + title: `Question`, + icon: ``, + }, + { + type: `help`, + title: `Help`, + icon: ``, + }, + { + type: `faq`, + title: `FAQ`, + icon: ``, + }, + { + type: `failure`, + title: `Failure`, + icon: ``, + }, + { + type: `fail`, + title: `Fail`, + icon: ``, + }, + { + type: `missing`, + title: `Missing`, + icon: ``, + }, + { + type: `danger`, + title: `Danger`, + icon: ``, + }, + { + type: `error`, + title: `Error`, + icon: ``, + }, + { + type: `bug`, + title: `Bug`, + icon: ``, + }, + { + type: `example`, + title: `Example`, + icon: ``, + }, + { + type: `quote`, + title: `Quote`, + icon: ``, + }, + { + type: `cite`, + title: `Cite`, + icon: ``, + }, +] + +/** + * Resolves the variants configuration, combining the provided variants with + * the default variants. + */ +export function resolveVariants(variants: AlertVariantItem[]) { + if (!variants.length) + return defaultAlertVariant + + return Object.values( + [...defaultAlertVariant, ...variants].reduce( + (map, item) => { + map[item.type] = item + return map + }, + {} as { [key: string]: AlertVariantItem }, + ), + ) +} + +/** + * Returns regex pattern to match alert syntax. + */ +export function createSyntaxPattern(type: string) { + return `^(?:\\[!${type}])\\s*?\n*` +} diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/extensions/footnotes.ts b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/extensions/footnotes.ts new file mode 100644 index 0000000..5660b64 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/extensions/footnotes.ts @@ -0,0 +1,89 @@ +import type { MarkedExtension, Tokens } from 'marked' +/** + * A marked extension to support footnotes syntax. + * Syntax: + * This is a footnote reference[^1][^2]. + * + * [^1]: ..... + * [^2]: ..... + */ + +interface MapContent { + index: number + text: string +} +const fnMap = new Map() + +export function markedFootnotes(): MarkedExtension { + return { + extensions: [ + { + name: `footnoteDef`, + level: `block`, + start(src: string) { + fnMap.clear() + return src.match(/^\[\^/)?.index + }, + tokenizer(src: string) { + const match = src.match(/^\[\^(.*)\]:(.*)/) + if (match) { + const [raw, fnId, text] = match + const index = fnMap.size + 1 + fnMap.set(fnId, { index, text }) + return { + type: `footnoteDef`, + raw, + fnId, + index, + text, + } + } + return undefined + }, + renderer(token: Tokens.Generic) { + const { index, text, fnId } = token + const fnInner = ` + ${index}. + ${text} + \u21A9\uFE0E +
` + if (index === 1) { + return ` +

${fnInner}` + } + if (index === fnMap.size) { + return `${fnInner}

` + } + return fnInner + }, + }, + { + name: `footnoteRef`, + level: `inline`, + start(src: string) { + return src.match(/\[\^/)?.index + }, + tokenizer(src: string) { + const match = src.match(/^\[\^(.*?)\]/) + if (match) { + const [raw, fnId] = match + if (fnMap.has(fnId)) { + return { + type: `footnoteRef`, + raw, + fnId, + } + } + } + }, + renderer(token: Tokens.Generic) { + const { fnId } = token + const { index } = fnMap.get(fnId) as MapContent + return ` + \[${index}\] + ` + }, + }, + ], + } +} diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/extensions/index.ts b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/extensions/index.ts new file mode 100644 index 0000000..dcf6c21 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/extensions/index.ts @@ -0,0 +1,10 @@ +// Markdown 扩展导出 +export * from './alert.js' +export * from './footnotes.js' +export * from './infographic.js' +export * from './katex.js' +export * from './markup.js' +export * from './plantuml.js' +export * from './ruby.js' +export * from './slider.js' +export * from './toc.js' diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/extensions/infographic.ts b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/extensions/infographic.ts new file mode 100644 index 0000000..47feedf --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/extensions/infographic.ts @@ -0,0 +1,119 @@ +import type { MarkedExtension } from 'marked' + +interface InfographicOptions { + themeMode?: 'dark' | 'light' +} + +async function renderInfographic(containerId: string, code: string, options?: InfographicOptions) { + if (typeof window === 'undefined') + return + + try { + const { Infographic, setDefaultFont, setFontExtendFactor, exportToSVG } = await import('@antv/infographic') + + setFontExtendFactor(1.1) + setDefaultFont('-apple-system-font, "system-ui", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif') + + const findContainer = (retries = 5, delay = 100) => { + const container = document.getElementById(containerId) + if (container) { + const isDark = options?.themeMode === 'dark' + + // 从 CSS 变量中读取主题颜色 + const root = document.documentElement + const computedStyle = getComputedStyle(root) + const primaryColor = computedStyle.getPropertyValue('--md-primary-color').trim() + const backgroundColor = computedStyle.getPropertyValue('--background').trim() + + // 转换 HSL 格式 + const toHSLString = (variant: string) => { + const vars = variant.split(' ') + if (vars.length === 3) + return `hsl(${vars.join(', ')})` + if (vars.length === 4) + return `hsla(${vars.join(', ')})` + return '' + } + + const instance = new Infographic({ + container, + svg: { + style: { + width: '100%', + height: '100%', + background: isDark ? '#000' : 'transparent', + }, + background: false, + }, + theme: isDark ? 'dark' : 'default', + themeConfig: { + colorPrimary: primaryColor || undefined, + colorBg: toHSLString(backgroundColor) || undefined, + }, + }) + + instance.on('loaded', ({ node }) => { + exportToSVG(node, { removeIds: true }).then((svg) => { + container.replaceChildren(svg) + }) + }) + + instance.render(code) + + return + } + + if (retries > 0) { + setTimeout(() => findContainer(retries - 1, delay), delay) + } + } + + findContainer() + } + catch (error) { + console.error('Failed to render Infographic:', error) + const container = document.getElementById(containerId) + if (container) { + container.innerHTML = `
Infographic 渲染失败: ${error instanceof Error ? error.message : String(error)}
` + } + } +} + +export function markedInfographic(options?: InfographicOptions): MarkedExtension { + const className = 'infographic-diagram' + + return { + extensions: [ + { + name: 'infographic', + level: 'block', + start(src: string) { + return src.match(/^```infographic/m)?.index + }, + tokenizer(src: string) { + const match = /^```infographic\r?\n([\s\S]*?)\r?\n```/.exec(src) + if (match) { + return { + type: 'infographic', + raw: match[0], + text: match[1].trim(), + } + } + }, + renderer(token: any) { + const id = `infographic-${Math.random().toString(36).slice(2, 11)}` + const code = token.text + + renderInfographic(id, code, options) + + return `
正在加载 Infographic...
` + }, + }, + ], + walkTokens(token: any) { + if (token.type === 'code' && token.lang === 'infographic') { + token.type = 'infographic' + } + }, + } +} diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/extensions/katex.ts b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/extensions/katex.ts new file mode 100644 index 0000000..be62590 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/extensions/katex.ts @@ -0,0 +1,162 @@ +import type { MarkedExtension } from 'marked' + +export interface MarkedKatexOptions { + nonStandard?: boolean +} + +const inlineRule = /^(\${1,2})(?!\$)((?:\\.|[^\\\n])*?(?:\\.|[^\\\n$]))\1(?=[\s?!.,:?!。,:]|$)/ +const inlineRuleNonStandard = /^(\${1,2})(?!\$)((?:\\.|[^\\\n])*?(?:\\.|[^\\\n$]))\1/ // Non-standard, even if there are no spaces before and after $ or $$, try to parse + +const blockRule = /^\s{0,3}(\${1,2})[ \t]*\n([\s\S]+?)\n\s{0,3}\1[ \t]*(?:\n|$)/ + +// LaTeX style rules for \( ... \) and \[ ... \] +const inlineLatexRule = /^\\\(([^\\]*(?:\\.[^\\]*)*?)\\\)/ +const blockLatexRule = /^\\\[([^\\]*(?:\\.[^\\]*)*?)\\\]/ + +function createRenderer(display: boolean, withStyle: boolean = true) { + return (token: any) => { + // @ts-expect-error MathJax is a global variable + window.MathJax.texReset() + // @ts-expect-error MathJax is a global variable + const mjxContainer = window.MathJax.tex2svg(token.text, { display }) + const svg = mjxContainer.firstChild + const width = svg.style[`min-width`] || svg.getAttribute(`width`) + svg.removeAttribute(`width`) + + // 行内公式对齐 https://groups.google.com/g/mathjax-users/c/zThKffrrCvE?pli=1 + // 直接覆盖 style 会覆盖 MathJax 的样式,需要手动设置 + // svg.style = `max-width: 300vw !important; display: initial; flex-shrink: 0;` + + if (withStyle) { + svg.style.display = `initial` + svg.style.setProperty(`max-width`, `300vw`, `important`) + svg.style.flexShrink = `0` + svg.style.width = width + } + + if (!display) { + // 新主题系统:使用 class 而非内联样式 + return `${svg.outerHTML}` + } + + return `
${svg.outerHTML}
` + } +} + +function inlineKatex(options: MarkedKatexOptions | undefined, renderer: any) { + const nonStandard = options && options.nonStandard + const ruleReg = nonStandard ? inlineRuleNonStandard : inlineRule + return { + name: `inlineKatex`, + level: `inline`, + start(src: string) { + let index + let indexSrc = src + + while (indexSrc) { + index = indexSrc.indexOf(`$`) + if (index === -1) { + return + } + const f = nonStandard ? index > -1 : index === 0 || indexSrc.charAt(index - 1) === ` ` + if (f) { + const possibleKatex = indexSrc.substring(index) + + if (possibleKatex.match(ruleReg)) { + return index + } + } + + indexSrc = indexSrc.substring(index + 1).replace(/^\$+/, ``) + } + }, + tokenizer(src: string) { + const match = src.match(ruleReg) + if (match) { + return { + type: `inlineKatex`, + raw: match[0], + text: match[2].trim(), + displayMode: match[1].length === 2, + } + } + }, + renderer, + } +} + +function blockKatex(_options: MarkedKatexOptions | undefined, renderer: any) { + return { + name: `blockKatex`, + level: `block`, + tokenizer(src: string) { + const match = src.match(blockRule) + if (match) { + return { + type: `blockKatex`, + raw: match[0], + text: match[2].trim(), + displayMode: match[1].length === 2, + } + } + }, + renderer, + } +} + +function inlineLatexKatex(_options: MarkedKatexOptions | undefined, renderer: any) { + return { + name: `inlineLatexKatex`, + level: `inline`, + start(src: string) { + const index = src.indexOf(`\\(`) + return index !== -1 ? index : undefined + }, + tokenizer(src: string) { + const match = src.match(inlineLatexRule) + if (match) { + return { + type: `inlineLatexKatex`, + raw: match[0], + text: match[1].trim(), + displayMode: false, + } + } + }, + renderer, + } +} + +function blockLatexKatex(_options: MarkedKatexOptions | undefined, renderer: any) { + return { + name: `blockLatexKatex`, + level: `block`, + start(src: string) { + const index = src.indexOf(`\\[`) + return index !== -1 ? index : undefined + }, + tokenizer(src: string) { + const match = src.match(blockLatexRule) + if (match) { + return { + type: `blockLatexKatex`, + raw: match[0], + text: match[1].trim(), + displayMode: true, + } + } + }, + renderer, + } +} + +export function MDKatex(options: MarkedKatexOptions | undefined, withStyle: boolean = true): MarkedExtension { + return { + extensions: [ + inlineKatex(options, createRenderer(false, withStyle)), + blockKatex(options, createRenderer(true, withStyle)), + inlineLatexKatex(options, createRenderer(false, withStyle)), + blockLatexKatex(options, createRenderer(true, withStyle)), + ], + } +} diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/extensions/markup.ts b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/extensions/markup.ts new file mode 100644 index 0000000..0aeac9b --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/extensions/markup.ts @@ -0,0 +1,87 @@ +import type { MarkedExtension } from 'marked' + +/** + * 扩展标记语法: + * - 高亮: ==文本== + * - 下划线: ++文本++ + * - 波浪线: ~文本~ + */ +export function markedMarkup(): MarkedExtension { + return { + extensions: [ + // 高亮语法 ==文本== + { + name: `markup_highlight`, + level: `inline`, + start(src: string) { + return src.match(/==(?!=)/)?.index + }, + tokenizer(src: string) { + const rule = /^==((?:[^=]|=(?!=))+)==/ + const match = rule.exec(src) + if (match) { + return { + type: `markup_highlight`, + raw: match[0], + text: match[1], + } + } + }, + renderer(token: any) { + // 新主题系统:使用 class 而非内联样式 + return `${token.text}` + }, + }, + + // 下划线语法 ++文本++ + { + name: `markup_underline`, + level: `inline`, + start(src: string) { + return src.match(/\+\+(?!\+)/)?.index + }, + tokenizer(src: string) { + const rule = /^\+\+((?:[^+]|\+(?!\+))+)\+\+/ + const match = rule.exec(src) + if (match) { + return { + type: `markup_underline`, + raw: match[0], + text: match[1], + } + } + }, + renderer(token: any) { + // 新主题系统:使用 class 而非内联样式 + return `${token.text}` + }, + }, + + // 波浪线语法 ~文本~ + { + name: `markup_wavyline`, + level: `inline`, + start(src: string) { + // 查找单个 ~ 但不是连续的 ~~ + return src.match(/~(?!~)/)?.index + }, + tokenizer(src: string) { + // 匹配 ~文本~ 但确保不是 ~~文本~~ + const rule = /^~([^~\n]+)~(?!~)/ + const match = rule.exec(src) + if (match) { + return { + type: `markup_wavyline`, + raw: match[0], + text: match[1], + } + } + }, + renderer(token: any) { + // 新主题系统:使用 class 而非内联样式 + return `${token.text}` + }, + }, + ], + } +} diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/extensions/plantuml.ts b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/extensions/plantuml.ts new file mode 100644 index 0000000..6b402f3 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/extensions/plantuml.ts @@ -0,0 +1,289 @@ +import type { MarkedExtension, Tokens } from 'marked' +import { deflateSync } from 'fflate' + +export interface PlantUMLOptions { + /** + * PlantUML 服务器地址 + * @default 'https://www.plantuml.com/plantuml' + */ + serverUrl?: string + /** + * 渲染格式 + * @default 'svg' + */ + format?: `svg` | `png` + /** + * CSS 类名 + * @default 'plantuml-diagram' + */ + className?: string + /** + * 是否内嵌SVG内容(用于微信公众号等不支持外链图片的环境) + * @default false + */ + inlineSvg?: boolean + /** + * 自定义样式 + */ + styles?: { + container?: Record + } +} + +/** + * PlantUML 专用的 6-bit 编码函数 + * 基于官方文档 https://plantuml.com/text-encoding + */ +function encode6bit(b: number): string { + if (b < 10) { + return String.fromCharCode(48 + b) + } + b -= 10 + if (b < 26) { + return String.fromCharCode(65 + b) + } + b -= 26 + if (b < 26) { + return String.fromCharCode(97 + b) + } + b -= 26 + if (b === 0) { + return `-` + } + if (b === 1) { + return `_` + } + return `?` +} + +/** + * 将 3 个字节附加到编码字符串中 + * 基于官方文档 https://plantuml.com/text-encoding + */ +function append3bytes(b1: number, b2: number, b3: number): string { + const c1 = b1 >> 2 + const c2 = ((b1 & 0x3) << 4) | (b2 >> 4) + const c3 = ((b2 & 0xF) << 2) | (b3 >> 6) + const c4 = b3 & 0x3F + let r = `` + r += encode6bit(c1 & 0x3F) + r += encode6bit(c2 & 0x3F) + r += encode6bit(c3 & 0x3F) + r += encode6bit(c4 & 0x3F) + return r +} + +/** + * PlantUML 专用的 base64 编码函数 + * 基于官方文档 https://plantuml.com/text-encoding + */ +function encode64(data: string): string { + let r = `` + for (let i = 0; i < data.length; i += 3) { + if (i + 2 === data.length) { + r += append3bytes(data.charCodeAt(i), data.charCodeAt(i + 1), 0) + } + else if (i + 1 === data.length) { + r += append3bytes(data.charCodeAt(i), 0, 0) + } + else { + r += append3bytes(data.charCodeAt(i), data.charCodeAt(i + 1), data.charCodeAt(i + 2)) + } + } + return r +} + +/** + * 使用 fflate 库进行 Deflate 压缩 + * 按照官方规范进行压缩 + */ +function performDeflate(input: string): string { + try { + // 将字符串转换为字节数组 + const inputBytes = new TextEncoder().encode(input) + + // 使用 fflate 进行 deflate 压缩(最高压缩级别 9) + const compressed = deflateSync(inputBytes, { level: 9 }) + + // 将压缩后的字节数组转换为二进制字符串 + return String.fromCharCode(...compressed) + } + catch (error) { + console.warn(`Deflate compression failed:`, error) + // 如果压缩失败,返回原始输入 + return input + } +} + +/** + * 编码 PlantUML 代码为服务器可识别的格式 + * 按照官方规范:UTF-8 编码 -> Deflate 压缩 -> PlantUML Base64 编码 + */ +function encodePlantUML(plantumlCode: string): string { + try { + // 步骤 1 & 2: UTF-8 编码 + Deflate 压缩 + const deflated = performDeflate(plantumlCode) + + // 步骤 3: PlantUML 专用的 base64 编码 + return encode64(deflated) + } + catch (error) { + // 如果编码失败,回退到简单方案 + console.warn(`PlantUML encoding failed, using fallback:`, error) + const utf8Bytes = new TextEncoder().encode(plantumlCode) + const base64 = btoa(String.fromCharCode(...utf8Bytes)) + return `~1${base64.replace(/\+/g, `-`).replace(/\//g, `_`).replace(/=/g, ``)}` + } +} + +/** + * 生成 PlantUML 图片 URL + */ +function generatePlantUMLUrl(code: string, options: Required): string { + const encoded = encodePlantUML(code) + const formatPath = options.format === `svg` ? `svg` : `png` + return `${options.serverUrl}/${formatPath}/${encoded}` +} + +/** + * 渲染 PlantUML 图表 + */ +function renderPlantUMLDiagram(token: Tokens.Code, options: Required): string { + const { text: code } = token + + // 检查代码是否包含 PlantUML 标记 + const finalCode = (!code.trim().includes(`@start`) || !code.trim().includes(`@end`)) + ? `@startuml\n${code.trim()}\n@enduml` + : code + + const imageUrl = generatePlantUMLUrl(finalCode, options) + + // 如果启用了内嵌SVG且格式是SVG + if (options.inlineSvg && options.format === `svg`) { + // 由于marked是同步的,我们需要返回一个占位符,然后异步替换 + const placeholder = `plantuml-placeholder-${Math.random().toString(36).slice(2, 11)}` + + // 异步获取SVG内容并替换 + fetchSvgContent(imageUrl).then((svgContent) => { + const placeholderElement = document.querySelector(`[data-placeholder="${placeholder}"]`) + if (placeholderElement) { + placeholderElement.outerHTML = createPlantUMLHTML(imageUrl, options, svgContent) + } + }) + + const containerStyles = options.styles.container + ? Object.entries(options.styles.container) + .map(([key, value]) => `${key.replace(/([A-Z])/g, `-$1`).toLowerCase()}: ${value}`) + .join(`; `) + : `` + + return `
+
正在加载PlantUML图表...
+
` + } + + return createPlantUMLHTML(imageUrl, options) +} + +/** + * 获取SVG内容 + */ +async function fetchSvgContent(svgUrl: string): Promise { + try { + const response = await fetch(svgUrl) + if (!response.ok) { + throw new Error(`HTTP ${response.status}`) + } + const svgContent = await response.text() + // 移除SVG根元素的固定尺寸,使其响应式 + return svgContent + // 移除width和height属性 + .replace(/(]*)\swidth="[^"]*"/g, `$1`) + .replace(/(]*)\sheight="[^"]*"/g, `$1`) + // 移除style中的width和height + .replace(/(]*style="[^"]*?)width:[^;]*;?/g, `$1`) + .replace(/(]*style="[^"]*?)height:[^;]*;?/g, `$1`) + } + catch (error) { + console.warn(`Failed to fetch SVG content from ${svgUrl}:`, error) + return `
PlantUML图表加载失败
` + } +} + +/** + * 创建 PlantUML HTML 元素 + */ +function createPlantUMLHTML(imageUrl: string, options: Required, svgContent?: string): string { + const containerStyles = options.styles.container + ? Object.entries(options.styles.container) + .map(([key, value]) => `${key.replace(/([A-Z])/g, `-$1`).toLowerCase()}: ${value}`) + .join(`; `) + : `` + + // 如果有SVG内容,直接嵌入 + if (svgContent) { + return `
+ ${svgContent} +
` + } + + // 否则使用图片链接 + return `
+ PlantUML Diagram +
` +} + +/** + * PlantUML marked 扩展 + */ +export function markedPlantUML(options: PlantUMLOptions = {}): MarkedExtension { + const resolvedOptions: Required = { + serverUrl: options.serverUrl || `https://www.plantuml.com/plantuml`, + format: options.format || `svg`, + className: options.className || `plantuml-diagram`, + inlineSvg: options.inlineSvg || false, + styles: { + container: { + textAlign: `center`, + margin: `16px 8px`, + overflowX: `auto`, + ...options.styles?.container, + }, + }, + } + + return { + extensions: [ + { + name: `plantuml`, + level: `block`, + start(src: string) { + // 匹配 ```plantuml 代码块 + return src.match(/^```plantuml/m)?.index + }, + tokenizer(src: string) { + // 匹配完整的 plantuml 代码块 + const match = /^```plantuml\r?\n([\s\S]*?)\r?\n```/.exec(src) + + if (match) { + const [raw, code] = match + return { + type: `plantuml`, + raw, + text: code.trim(), + } + } + }, + renderer(token: any) { + return renderPlantUMLDiagram(token, resolvedOptions) + }, + }, + ], + walkTokens(token: any) { + // 处理现有的代码块,如果语言是 plantuml 就转换类型 + if (token.type === `code` && token.lang === `plantuml`) { + token.type = `plantuml` + } + }, + } +} diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/extensions/ruby.ts b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/extensions/ruby.ts new file mode 100644 index 0000000..a064b0a --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/extensions/ruby.ts @@ -0,0 +1,125 @@ +import type { MarkedExtension } from 'marked' + +/** + * 注音/拼音标注扩展 + * https://talk.commonmark.org/t/proper-ruby-text-rb-syntax-support-in-markdown/2279 + * https://www.w3.org/TR/ruby/ + * + * 支持的格式: + * 1. [文字]{注音} + * 2. [文字]^(注音) + * + * 分隔符: + * - `・` (中点) + * - `.` (全角句点) + * - `。` (中文句号) + * - `-` (英文减号) + */ +export function markedRuby(): MarkedExtension { + return { + extensions: [ + { + name: `ruby`, + level: `inline`, + start(src: string) { + // 匹配以 [ 开头的格式 + return src.match(/\[/)?.index + }, + tokenizer(src: string) { + // 1. [文字]{注音} + const rule1 = /^\[([^\]]+)\]\{([^}]+)\}/ + let match = rule1.exec(src) + if (match) { + return { + type: `ruby`, + raw: match[0], + text: match[1].trim(), + ruby: match[2].trim(), + format: `basic`, + } + } + + // 2. [文字]^(注音) + const rule2 = /^\[([^\]]+)\]\^\(([^)]+)\)/ + match = rule2.exec(src) + if (match) { + return { + type: `ruby`, + raw: match[0], + text: match[1].trim(), + ruby: match[2].trim(), + format: `basic-hat`, + } + } + + return undefined + }, + renderer(token: any) { + const { text, ruby, format } = token + + // 检查是否有分隔符 + const separatorRegex = /[・.。-]/g + const hasSeparators = separatorRegex.test(ruby) + + if (hasSeparators) { + // 分割注音部分 + const rubyParts = ruby.split(separatorRegex).filter((part: string) => part.trim() !== ``) + + const textChars = text.split(``) + const result = [] + + if (textChars.length >= rubyParts.length) { + // 文字字符数量 >= 注音部分数量 + // 按注音部分数量分割文字 + let currentIndex = 0 + + for (let i = 0; i < rubyParts.length; i++) { + const rubyPart = rubyParts[i] + const remainingChars = textChars.length - currentIndex + const remainingParts = rubyParts.length - i + + // 计算当前部分应该包含多少个字符,默认为 1 + let charCount = 1 + if (remainingParts === 1) { + // 最后一个部分,包含所有剩余字符 + charCount = remainingChars + } + + // 提取当前部分的文字 + const currentText = textChars.slice(currentIndex, currentIndex + charCount).join(``) + + result.push(`${currentText}(${rubyPart})`) + + currentIndex += charCount + } + + // 处理剩余的字符 + if (currentIndex < textChars.length) { + result.push(textChars.slice(currentIndex).join(``)) + } + } + else { + // 文字字符数量 < 注音部分数量 + // 每个字符对应一个注音部分,多余的注音被忽略 + for (let i = 0; i < textChars.length; i++) { + const char = textChars[i] + const rubyPart = rubyParts[i] || `` + + if (rubyPart) { + result.push(`${char}(${rubyPart})`) + } + else { + result.push(char) + } + } + } + + return result.join(``) + } + + return `${text}(${ruby})` + }, + }, + ], + } +} diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/extensions/slider.ts b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/extensions/slider.ts new file mode 100644 index 0000000..f1f1a10 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/extensions/slider.ts @@ -0,0 +1,73 @@ +import type { MarkedExtension, Tokens } from 'marked' + +/** + * A marked extension to support horizontal sliding images. + * Syntax: + */ +export function markedSlider(): MarkedExtension { + return { + extensions: [ + { + name: `horizontalSlider`, + level: `block`, + start(src: string) { + return src.match(/^/ + const match = src.match(rule) + if (match) { + return { + type: `horizontalSlider`, + raw: match[0], + text: match[1], + } + } + return undefined + }, + renderer(token: Tokens.Generic) { + const { text } = token + const imageMatches = text.match(/!\[(.*?)\]\((.*?)\)/g) || [] + + if (imageMatches.length === 0) { + return `` + } + + const images = imageMatches.map((img: string) => { + const altMatch = img.match(/!\[(.*?)\]/) || [] + const srcMatch = img.match(/\]\((.*?)\)/) || [] + const alt = altMatch[1] || `` + const src = srcMatch[1] || `` + + // 新主题系统:不再需要内联样式 + return { src, alt } + }) + + // 使用微信公众号兼容的滑动容器布局 + // 使用微信支持的section标签和特殊样式组合 + + return ` +
+
+
+
+
+ +
+ ${images.map((img: { src: string, alt: string }, _index: number) => `
+ ${img.alt} +

${img.alt}

+
`).join(``)} +
+
+
+
+
+

<<< 左右滑动看更多 >>>

+
+ ` + }, + }, + ], + } +} diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/extensions/toc.ts b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/extensions/toc.ts new file mode 100644 index 0000000..85e44ff --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/extensions/toc.ts @@ -0,0 +1,74 @@ +import type { MarkedExtension } from 'marked' + +/** + * marked 插件:支持 [TOC] 语法,自动生成嵌套目录 + */ +export function markedToc(): MarkedExtension { + let headings: { text: string, depth: number, index: number }[] = [] + + let firstToken = true + + return { + walkTokens(token) { + if (firstToken) { + headings = [] + firstToken = false + } + if (token.type === `heading`) { + const text = token.text || `` + const depth = token.depth || 1 + const index = headings.length + headings.push({ text, depth, index }) + } + }, + extensions: [ + { + name: `toc`, + level: `block`, + start(src) { + // 只匹配独立一行的 [TOC],避免误伤 + const match = src.match(/^\s*\[TOC\]\s*$/m) + return match ? match.index : undefined + }, + tokenizer(src) { + const match = /^\[TOC\]/.exec(src) + if (match) { + return { + type: `toc`, + raw: match[0], + } + } + }, + renderer() { + if (!headings.length) + return `` + let html = `` + + firstToken = true + return html + }, + }, + ], + } +} diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/html-builder.ts b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/html-builder.ts new file mode 100644 index 0000000..3ca61a0 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/html-builder.ts @@ -0,0 +1,142 @@ +import fs from "node:fs"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import type { StyleConfig, HtmlDocumentMeta } from "./types.js"; +import { DEFAULT_STYLE } from "./constants.js"; + +const SCRIPT_DIR = path.dirname(fileURLToPath(import.meta.url)); +const CODE_THEMES_DIR = path.resolve(SCRIPT_DIR, "code-themes"); + +export function buildCss(baseCss: string, themeCss: string, style: StyleConfig = DEFAULT_STYLE): string { + const variables = ` +:root { + --md-primary-color: ${style.primaryColor}; + --md-font-family: ${style.fontFamily}; + --md-font-size: ${style.fontSize}; + --foreground: ${style.foreground}; + --blockquote-background: ${style.blockquoteBackground}; + --md-accent-color: ${style.accentColor}; + --md-container-bg: ${style.containerBg}; +} + +body { + margin: 0; + padding: 24px; + background: #ffffff; +} + +#output { + max-width: 860px; + margin: 0 auto; +} +`.trim(); + + return [variables, baseCss, themeCss].join("\n\n"); +} + +export function loadCodeThemeCss(themeName: string): string { + const filePath = path.join(CODE_THEMES_DIR, `${themeName}.min.css`); + try { + return fs.readFileSync(filePath, "utf-8"); + } catch { + console.error(`Code theme CSS not found: ${filePath}`); + return ""; + } +} + +export function buildHtmlDocument(meta: HtmlDocumentMeta, css: string, html: string, codeThemeCss?: string): string { + const lines = [ + "", + "", + "", + ' ', + ' ', + ` ${meta.title}`, + ]; + if (meta.author) { + lines.push(` `); + } + if (meta.description) { + lines.push(` `); + } + lines.push(` `); + if (codeThemeCss) { + lines.push(` `); + } + lines.push( + "", + "", + '
', + html, + "
", + "", + "" + ); + return lines.join("\n"); +} + +export async function inlineCss(html: string): Promise { + try { + const { default: juice } = await import("juice"); + return juice(html, { + inlinePseudoElements: true, + preserveImportant: true, + resolveCSSVariables: false, + }); + } catch (error) { + const detail = error instanceof Error ? error.message : String(error); + throw new Error( + `Missing dependency "juice" for CSS inlining. Install it first (e.g. "bun add juice" or "npm add juice"). Original error: ${detail}` + ); + } +} + +export function normalizeCssText(cssText: string, style: StyleConfig = DEFAULT_STYLE): string { + return cssText + .replace(/var\(--md-primary-color\)/g, style.primaryColor) + .replace(/var\(--md-font-family\)/g, style.fontFamily) + .replace(/var\(--md-font-size\)/g, style.fontSize) + .replace(/var\(--blockquote-background\)/g, style.blockquoteBackground) + .replace(/var\(--md-accent-color\)/g, style.accentColor) + .replace(/var\(--md-container-bg\)/g, style.containerBg) + .replace(/hsl\(var\(--foreground\)\)/g, "#3f3f3f") + .replace(/--md-primary-color:\s*[^;"']+;?/g, "") + .replace(/--md-font-family:\s*[^;"']+;?/g, "") + .replace(/--md-font-size:\s*[^;"']+;?/g, "") + .replace(/--blockquote-background:\s*[^;"']+;?/g, "") + .replace(/--md-accent-color:\s*[^;"']+;?/g, "") + .replace(/--md-container-bg:\s*[^;"']+;?/g, "") + .replace(/--foreground:\s*[^;"']+;?/g, ""); +} + +export function normalizeInlineCss(html: string, style: StyleConfig = DEFAULT_STYLE): string { + let output = html; + output = output.replace( + /]*)>([\s\S]*?)<\/style>/gi, + (_match, attrs: string, cssText: string) => + `${normalizeCssText(cssText, style)}` + ); + output = output.replace( + /style="([^"]*)"/gi, + (_match, cssText: string) => `style="${normalizeCssText(cssText, style)}"` + ); + output = output.replace( + /style='([^']*)'/gi, + (_match, cssText: string) => `style='${normalizeCssText(cssText, style)}'` + ); + return output; +} + +export function modifyHtmlStructure(htmlString: string): string { + let output = htmlString; + const pattern = + /]*)>([\s\S]*?)(|)<\/li>/i; + while (pattern.test(output)) { + output = output.replace(pattern, "$2$3"); + } + return output; +} + +export function removeFirstHeading(html: string): string { + return html.replace(/]*>[\s\S]*?<\/h[12]>/, ""); +} diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/images.ts b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/images.ts new file mode 100644 index 0000000..f0a3f00 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/images.ts @@ -0,0 +1,127 @@ +import { createHash } from "node:crypto"; +import fs from "node:fs"; +import http from "node:http"; +import https from "node:https"; +import path from "node:path"; + +export interface ImagePlaceholder { + originalPath: string; + placeholder: string; +} + +export interface ResolvedImageInfo extends ImagePlaceholder { + localPath: string; +} + +export function replaceMarkdownImagesWithPlaceholders( + markdown: string, + placeholderPrefix: string, +): { + images: ImagePlaceholder[]; + markdown: string; +} { + const images: ImagePlaceholder[] = []; + let imageCounter = 0; + + const rewritten = markdown.replace(/!\[([^\]]*)\]\(([^)]+)\)/g, (_match, _alt, src) => { + const placeholder = `${placeholderPrefix}${++imageCounter}`; + images.push({ + originalPath: src, + placeholder, + }); + return placeholder; + }); + + return { images, markdown: rewritten }; +} + +export function getImageExtension(urlOrPath: string): string { + const match = urlOrPath.match(/\.(jpg|jpeg|png|gif|webp)(\?|$)/i); + return match ? match[1]!.toLowerCase() : "png"; +} + +export async function downloadFile(url: string, destPath: string): Promise { + return await new Promise((resolve, reject) => { + const protocol = url.startsWith("https://") ? https : http; + const file = fs.createWriteStream(destPath); + + const request = protocol.get(url, { headers: { "User-Agent": "Mozilla/5.0" } }, (response) => { + if (response.statusCode === 301 || response.statusCode === 302) { + const redirectUrl = response.headers.location; + if (redirectUrl) { + file.close(); + fs.unlinkSync(destPath); + void downloadFile(redirectUrl, destPath).then(resolve).catch(reject); + return; + } + } + + if (response.statusCode !== 200) { + file.close(); + fs.unlinkSync(destPath); + reject(new Error(`Failed to download: ${response.statusCode}`)); + return; + } + + response.pipe(file); + file.on("finish", () => { + file.close(); + resolve(); + }); + }); + + request.on("error", (error) => { + file.close(); + fs.unlink(destPath, () => {}); + reject(error); + }); + + request.setTimeout(30_000, () => { + request.destroy(); + reject(new Error("Download timeout")); + }); + }); +} + +export async function resolveImagePath( + imagePath: string, + baseDir: string, + tempDir: string, + logLabel = "baoyu-md", +): Promise { + if (imagePath.startsWith("http://") || imagePath.startsWith("https://")) { + const hash = createHash("md5").update(imagePath).digest("hex").slice(0, 8); + const ext = getImageExtension(imagePath); + const localPath = path.join(tempDir, `remote_${hash}.${ext}`); + + if (!fs.existsSync(localPath)) { + console.error(`[${logLabel}] Downloading: ${imagePath}`); + await downloadFile(imagePath, localPath); + } + return localPath; + } + + if (path.isAbsolute(imagePath)) { + return imagePath; + } + + return path.resolve(baseDir, imagePath); +} + +export async function resolveContentImages( + images: ImagePlaceholder[], + baseDir: string, + tempDir: string, + logLabel = "baoyu-md", +): Promise { + const resolved: ResolvedImageInfo[] = []; + + for (const image of images) { + resolved.push({ + ...image, + localPath: await resolveImagePath(image.originalPath, baseDir, tempDir, logLabel), + }); + } + + return resolved; +} diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/index.ts b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/index.ts new file mode 100644 index 0000000..eeec395 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/index.ts @@ -0,0 +1,10 @@ +export * from "./cli.js"; +export * from "./constants.js"; +export * from "./content.js"; +export * from "./document.js"; +export * from "./extend-config.js"; +export * from "./html-builder.js"; +export * from "./images.js"; +export * from "./renderer.js"; +export * from "./themes.js"; +export * from "./types.js"; diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/render.ts b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/render.ts new file mode 100644 index 0000000..85415d6 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/render.ts @@ -0,0 +1,43 @@ +#!/usr/bin/env npx tsx + +import path from "node:path"; +import { parseArgs, printUsage } from "./cli.js"; +import { renderMarkdownFileToHtml } from "./document.js"; + +async function main(): Promise { + const options = parseArgs(process.argv.slice(2)); + if (!options) { + printUsage(); + process.exit(1); + } + + const inputPath = path.resolve(process.cwd(), options.inputPath); + if (!inputPath.toLowerCase().endsWith(".md")) { + console.error("Input file must end with .md"); + process.exit(1); + } + + const result = await renderMarkdownFileToHtml(inputPath, { + codeTheme: options.codeTheme, + countStatus: options.countStatus, + citeStatus: options.citeStatus, + fontFamily: options.fontFamily, + fontSize: options.fontSize, + isMacCodeBlock: options.isMacCodeBlock, + isShowLineNumber: options.isShowLineNumber, + keepTitle: options.keepTitle, + legend: options.legend, + primaryColor: options.primaryColor, + theme: options.theme, + }); + + if (result.backupPath) { + console.log(`Backup created: ${result.backupPath}`); + } + console.log(`HTML written: ${result.outputPath}`); +} + +main().catch((error) => { + console.error(error); + process.exit(1); +}); diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/renderer.ts b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/renderer.ts new file mode 100644 index 0000000..7a1234c --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/renderer.ts @@ -0,0 +1,434 @@ +import frontMatter from "front-matter"; +import hljs from "highlight.js/lib/core"; +import { marked, type RendererObject, type Tokens } from "marked"; +import readingTime, { type ReadTimeResults } from "reading-time"; +import { unified } from "unified"; +import remarkParse from "remark-parse"; +import remarkCjkFriendly from "remark-cjk-friendly"; +import remarkStringify from "remark-stringify"; + +import { + markedAlert, + markedFootnotes, + markedInfographic, + markedMarkup, + markedPlantUML, + markedRuby, + markedSlider, + markedToc, + MDKatex, +} from "./extensions/index.js"; +import { + COMMON_LANGUAGES, + highlightAndFormatCode, +} from "./utils/languages.js"; +import { macCodeSvg } from "./constants.js"; +import type { IOpts, ParseResult, RendererAPI } from "./types.js"; + +Object.entries(COMMON_LANGUAGES).forEach(([name, lang]) => { + hljs.registerLanguage(name, lang); +}); + +export { hljs }; + +marked.setOptions({ + breaks: true, +}); +marked.use(markedSlider()); + +function escapeHtml(text: string): string { + return text + .replace(/&/g, "&") + .replace(//g, ">") + .replace(/"/g, """) + .replace(/'/g, "'") + .replace(/`/g, "`"); +} + +function buildAddition(): string { + return ` + + `; +} + +function buildFootnoteArray(footnotes: [number, string, string][]): string { + return footnotes + .map(([index, title, link]) => + link === title + ? `[${index}]: ${title}
` + : `[${index}] ${title}: ${link}
` + ) + .join("\n"); +} + +function transform(legend: string, text: string | null, title: string | null): string { + const options = legend.split("-"); + for (const option of options) { + if (option === "alt" && text) { + return text; + } + if (option === "title" && title) { + return title; + } + } + return ""; +} + +function parseFrontMatterAndContent(markdownText: string): ParseResult { + try { + const parsed = frontMatter(markdownText); + const yamlData = parsed.attributes; + const markdownContent = parsed.body; + const readingTimeResult = readingTime(markdownContent); + return { + yamlData: yamlData as Record, + markdownContent, + readingTime: readingTimeResult, + }; + } catch (error) { + console.error("Error parsing front-matter:", error); + return { + yamlData: {}, + markdownContent: markdownText, + readingTime: readingTime(markdownText), + }; + } +} + +export function initRenderer(opts: IOpts = {}): RendererAPI { + const footnotes: [number, string, string][] = []; + let footnoteIndex = 0; + let codeIndex = 0; + const listOrderedStack: boolean[] = []; + const listCounters: number[] = []; + const isBrowser = typeof window !== "undefined"; + + function getOpts(): IOpts { + return opts; + } + + function styledContent(styleLabel: string, content: string, tagName?: string): string { + const tag = tagName ?? styleLabel; + const className = `${styleLabel.replace(/_/g, "-")}`; + const headingAttr = /^h\d$/.test(tag) ? " data-heading=\"true\"" : ""; + return `<${tag} class="${className}"${headingAttr}>${content}`; + } + + function addFootnote(title: string, link: string): number { + const existingFootnote = footnotes.find(([, , existingLink]) => existingLink === link); + if (existingFootnote) { + return existingFootnote[0]; + } + footnotes.push([++footnoteIndex, title, link]); + return footnoteIndex; + } + + function reset(newOpts: Partial): void { + footnotes.length = 0; + footnoteIndex = 0; + setOptions(newOpts); + } + + function setOptions(newOpts: Partial): void { + opts = { ...opts, ...newOpts }; + marked.use(markedAlert()); + if (isBrowser) { + marked.use(MDKatex({ nonStandard: true }, true)); + } + marked.use(markedMarkup()); + marked.use(markedInfographic({ themeMode: opts.themeMode })); + } + + function buildReadingTime(readingTimeResult: ReadTimeResults): string { + if (!opts.countStatus) { + return ""; + } + if (!readingTimeResult.words) { + return ""; + } + return ` +
+

字数 ${readingTimeResult?.words},阅读大约需 ${Math.ceil(readingTimeResult?.minutes)} 分钟

+
+ `; + } + + const buildFootnotes = () => { + if (!footnotes.length) { + return ""; + } + return ( + styledContent("h4", "引用链接") + + styledContent("footnotes", buildFootnoteArray(footnotes), "p") + ); + }; + + const renderer: RendererObject = { + heading({ tokens, depth }: Tokens.Heading) { + const text = this.parser.parseInline(tokens); + const tag = `h${depth}`; + return styledContent(tag, text); + }, + + paragraph({ tokens }: Tokens.Paragraph): string { + const text = this.parser.parseInline(tokens); + const isFigureImage = text.includes(" { + const windowRef = typeof window !== "undefined" ? (window as any) : undefined; + if (windowRef && windowRef.mermaid) { + const mermaid = windowRef.mermaid; + await mermaid.run(); + } else { + const mermaid = await import("mermaid"); + await mermaid.default.run(); + } + }, 0) as any as number; + } + return `
${text}
`; + } + const langText = lang.split(" ")[0]; + const isLanguageRegistered = hljs.getLanguage(langText); + const language = isLanguageRegistered ? langText : "plaintext"; + + const highlighted = highlightAndFormatCode( + text, + language, + hljs, + !!opts.isShowLineNumber + ); + + const span = `${macCodeSvg}`; + let pendingAttr = ""; + if (!isLanguageRegistered && langText !== "plaintext") { + const escapedText = text.replace(/"/g, """); + pendingAttr = ` data-language-pending="${langText}" data-raw-code="${escapedText}" data-show-line-number="${opts.isShowLineNumber}"`; + } + const code = `${highlighted}`; + + return `
${span}${code}
`; + }, + + codespan({ text }: Tokens.Codespan): string { + const escapedText = escapeHtml(text); + return styledContent("codespan", escapedText, "code"); + }, + + list({ ordered, items, start = 1 }: Tokens.List) { + listOrderedStack.push(ordered); + listCounters.push(Number(start)); + const html = items.map((item) => this.listitem(item)).join(""); + listOrderedStack.pop(); + listCounters.pop(); + return styledContent(ordered ? "ol" : "ul", html); + }, + + listitem(token: Tokens.ListItem) { + const ordered = listOrderedStack[listOrderedStack.length - 1]; + const idx = listCounters[listCounters.length - 1]!; + listCounters[listCounters.length - 1] = idx + 1; + const prefix = ordered ? `${idx}. ` : "• "; + let content: string; + try { + content = this.parser.parseInline(token.tokens); + } catch { + content = this.parser + .parse(token.tokens) + .replace(/^]*)?>([\s\S]*?)<\/p>/, "$1"); + } + return styledContent("listitem", `${prefix}${content}`, "li"); + }, + + image({ href, title, text }: Tokens.Image): string { + const newText = opts.legend ? transform(opts.legend, text, title) : ""; + const subText = newText ? styledContent("figcaption", newText) : ""; + const titleAttr = title ? ` title="${title}"` : ""; + return `
${text}${subText}
`; + }, + + link({ href, title, text, tokens }: Tokens.Link): string { + const parsedText = this.parser.parseInline(tokens); + if (/^https?:\/\/mp\.weixin\.qq\.com/.test(href)) { + return `${parsedText}`; + } + if (href === text) { + return parsedText; + } + if (opts.citeStatus) { + const ref = addFootnote(title || text, href); + return `${parsedText}[${ref}]`; + } + return `${parsedText}`; + }, + + strong({ tokens }: Tokens.Strong): string { + return styledContent("strong", this.parser.parseInline(tokens)); + }, + + em({ tokens }: Tokens.Em): string { + return styledContent("em", this.parser.parseInline(tokens)); + }, + + table({ header, rows }: Tokens.Table): string { + const headerRow = header + .map((cell) => { + const text = this.parser.parseInline(cell.tokens); + return styledContent("th", text); + }) + .join(""); + const body = rows + .map((row) => { + const rowContent = row.map((cell) => this.tablecell(cell)).join(""); + return styledContent("tr", rowContent); + }) + .join(""); + return ` +
+ + ${headerRow} + ${body} +
+
+ `; + }, + + tablecell(token: Tokens.TableCell): string { + const text = this.parser.parseInline(token.tokens); + return styledContent("td", text); + }, + + hr(_: Tokens.Hr): string { + return styledContent("hr", ""); + }, + }; + + marked.use({ renderer }); + marked.use(markedMarkup()); + marked.use(markedToc()); + marked.use(markedSlider()); + marked.use(markedAlert({})); + if (isBrowser) { + marked.use(MDKatex({ nonStandard: true }, true)); + } + marked.use(markedFootnotes()); + marked.use( + markedPlantUML({ + inlineSvg: isBrowser, + }) + ); + marked.use(markedInfographic()); + marked.use(markedRuby()); + + return { + buildAddition, + buildFootnotes, + setOptions, + reset, + parseFrontMatterAndContent, + buildReadingTime, + createContainer(content: string) { + return styledContent("container", content, "section"); + }, + getOpts, + }; +} + +function preprocessCjkEmphasis(markdown: string): string { + const processor = unified() + .use(remarkParse) + .use(remarkCjkFriendly); + const tree = processor.parse(markdown); + const extractText = (node: any): string => { + if (node.type === "text") return node.value; + if (node.children) return node.children.map(extractText).join(""); + return ""; + }; + const visit = (node: any, parent?: any, index?: number) => { + if (node.children) { + for (let i = 0; i < node.children.length; i++) { + visit(node.children[i], node, i); + } + } + if (node.type === "strong" && parent && typeof index === "number") { + const text = extractText(node); + parent.children[index] = { type: "html", value: `${text}` }; + } + if (node.type === "emphasis" && parent && typeof index === "number") { + const text = extractText(node); + parent.children[index] = { type: "html", value: `${text}` }; + } + }; + visit(tree); + const stringify = unified().use(remarkStringify); + let result = stringify.stringify(tree); + result = result.replace(/&#x([0-9A-Fa-f]+);/g, (_, hex) => + String.fromCodePoint(parseInt(hex, 16)) + ); + return result; +} + +export function renderMarkdown(raw: string, renderer: RendererAPI): { + html: string; + readingTime: ReadTimeResults; +} { + const { markdownContent, readingTime: readingTimeResult } = + renderer.parseFrontMatterAndContent(raw); + const preprocessed = preprocessCjkEmphasis(markdownContent); + const html = marked.parse(preprocessed) as string; + return { html, readingTime: readingTimeResult }; +} + +export function postProcessHtml( + baseHtml: string, + reading: ReadTimeResults, + renderer: RendererAPI +): string { + let html = baseHtml; + html = renderer.buildReadingTime(reading) + html; + html += renderer.buildFootnotes(); + html += renderer.buildAddition(); + html += ` + + `; + html += ` + + `; + return renderer.createContainer(html); +} diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/themes.ts b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/themes.ts new file mode 100644 index 0000000..9c3dbeb --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/themes.ts @@ -0,0 +1,62 @@ +import fs from "node:fs"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import type { ThemeName } from "./types.js"; + +const SCRIPT_DIR = path.dirname(fileURLToPath(import.meta.url)); +export const THEME_DIR = path.resolve(SCRIPT_DIR, "themes"); +const FALLBACK_THEMES: ThemeName[] = ["default", "grace", "simple"]; + +function stripOutputScope(cssContent: string): string { + let css = cssContent; + css = css.replace(/#output\s*\{/g, "body {"); + css = css.replace(/#output\s+/g, ""); + css = css.replace(/^#output\s*/gm, ""); + return css; +} + +function discoverThemesFromDir(dir: string): string[] { + if (!fs.existsSync(dir)) { + return []; + } + return fs + .readdirSync(dir) + .filter((name) => name.endsWith(".css")) + .map((name) => name.replace(/\.css$/i, "")) + .filter((name) => name.toLowerCase() !== "base"); +} + +function resolveThemeNames(): ThemeName[] { + const localThemes = discoverThemesFromDir(THEME_DIR); + const resolved = localThemes.filter((name) => + fs.existsSync(path.join(THEME_DIR, `${name}.css`)) + ); + return resolved.length ? resolved : FALLBACK_THEMES; +} + +export const THEME_NAMES: ThemeName[] = resolveThemeNames(); + +export function loadThemeCss(theme: ThemeName): { + baseCss: string; + themeCss: string; +} { + const basePath = path.join(THEME_DIR, "base.css"); + const themePath = path.join(THEME_DIR, `${theme}.css`); + + if (!fs.existsSync(basePath)) { + throw new Error(`Missing base CSS: ${basePath}`); + } + + if (!fs.existsSync(themePath)) { + throw new Error(`Missing theme CSS for "${theme}": ${themePath}`); + } + + return { + baseCss: fs.readFileSync(basePath, "utf-8"), + themeCss: fs.readFileSync(themePath, "utf-8"), + }; +} + +export function normalizeThemeCss(css: string): string { + return stripOutputScope(css); +} diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/themes/base.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/themes/base.css new file mode 100644 index 0000000..3ec1fe4 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/themes/base.css @@ -0,0 +1,39 @@ +/** + * MD 基础主题样式 + * 包含所有元素的基础样式和 CSS 变量定义 + */ + +/* ==================== 容器样式 ==================== */ +section, +container { + font-family: var(--md-font-family); + font-size: var(--md-font-size); + line-height: 1.75; + text-align: left; +} + +/* 确保 #output 容器应用基础样式 */ +#output { + font-family: var(--md-font-family); + font-size: var(--md-font-size); + line-height: 1.75; + text-align: left; +} + +/* ==================== Global resets ==================== */ +blockquote { + margin-top: 0; + margin-right: 0; + margin-bottom: 0; + margin-left: 0; +} + +/* 去除第一个元素的 margin-top */ +#output section > :first-child { + margin-top: 0 !important; +} + +.mermaid-diagram .nodeLabel p { + color: unset !important; + letter-spacing: unset !important; +} diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/themes/default.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/themes/default.css new file mode 100644 index 0000000..b9982f6 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/themes/default.css @@ -0,0 +1,434 @@ +/** + * MD 默认主题(经典主题) + * 按 Alt/Option + Shift + F 可格式化 + * 如需使用主题色,请使用 var(--md-primary-color) 代替颜色值 + */ + +/* ==================== 一级标题 ==================== */ +h1 { + display: table; + padding: 0 1em; + border-bottom: 2px solid var(--md-primary-color); + margin: 2em auto 1em; + color: hsl(var(--foreground)); + font-size: calc(var(--md-font-size) * 1.2); + font-weight: bold; + text-align: center; +} + +/* ==================== 二级标题 ==================== */ +h2 { + display: table; + padding: 0 0.2em; + margin: 4em auto 2em; + color: #fff; + background: var(--md-primary-color); + font-size: calc(var(--md-font-size) * 1.2); + font-weight: bold; + text-align: center; +} + +/* ==================== 三级标题 ==================== */ +h3 { + padding-left: 8px; + border-left: 3px solid var(--md-primary-color); + margin: 2em 8px 0.75em 0; + color: hsl(var(--foreground)); + font-size: calc(var(--md-font-size) * 1.1); + font-weight: bold; + line-height: 1.2; +} + +/* ==================== 四级标题 ==================== */ +h4 { + margin: 2em 8px 0.5em; + color: var(--md-primary-color); + font-size: calc(var(--md-font-size) * 1); + font-weight: bold; +} + +/* ==================== 五级标题 ==================== */ +h5 { + margin: 1.5em 8px 0.5em; + color: var(--md-primary-color); + font-size: calc(var(--md-font-size) * 1); + font-weight: bold; +} + +/* ==================== 六级标题 ==================== */ +h6 { + margin: 1.5em 8px 0.5em; + font-size: calc(var(--md-font-size) * 1); + color: var(--md-primary-color); +} + +/* ==================== 段落 ==================== */ +p { + margin: 1.5em 8px; + letter-spacing: 0.1em; + color: hsl(var(--foreground)); +} + +/* ==================== 引用块 ==================== */ +blockquote { + font-style: normal; + padding: 1em; + border-left: 4px solid var(--md-primary-color); + border-radius: 6px; + color: hsl(var(--foreground)); + background: var(--blockquote-background); + margin-bottom: 1em; +} + +blockquote > p { + display: block; + font-size: 1em; + letter-spacing: 0.1em; + color: hsl(var(--foreground)); + margin: 0; +} + +/* ==================== GFM 警告块 ==================== */ +.alert-title-note, +.alert-title-tip, +.alert-title-info, +.alert-title-important, +.alert-title-warning, +.alert-title-caution, +.alert-title-abstract, +.alert-title-summary, +.alert-title-tldr, +.alert-title-todo, +.alert-title-success, +.alert-title-done, +.alert-title-question, +.alert-title-help, +.alert-title-faq, +.alert-title-failure, +.alert-title-fail, +.alert-title-missing, +.alert-title-danger, +.alert-title-error, +.alert-title-bug, +.alert-title-example, +.alert-title-quote, +.alert-title-cite { + display: flex; + align-items: center; + gap: 0.5em; + margin-bottom: 0.5em; +} + +.alert-title-note { + color: #478be6; +} + +.alert-title-tip { + color: #57ab5a; +} + +.alert-title-info { + color: #93c5fd; +} + +.alert-title-important { + color: #986ee2; +} + +.alert-title-warning { + color: #c69026; +} + +.alert-title-caution { + color: #e5534b; +} + +/* Obsidian-style callout colors */ +.alert-title-abstract, +.alert-title-summary, +.alert-title-tldr { + color: #00bfff; +} + +.alert-title-todo { + color: #478be6; +} + +.alert-title-success, +.alert-title-done { + color: #57ab5a; +} + +.alert-title-question, +.alert-title-help, +.alert-title-faq { + color: #c69026; +} + +.alert-title-failure, +.alert-title-fail, +.alert-title-missing { + color: #e5534b; +} + +.alert-title-danger, +.alert-title-error { + color: #e5534b; +} + +.alert-title-bug { + color: #e5534b; +} + +.alert-title-example { + color: #986ee2; +} + +.alert-title-quote, +.alert-title-cite { + color: #9ca3af; +} + +/* GFM Alert SVG 图标颜色 */ +.alert-icon-note { + fill: #478be6; +} + +.alert-icon-tip { + fill: #57ab5a; +} + +.alert-icon-info { + fill: #93c5fd; +} + +.alert-icon-important { + fill: #986ee2; +} + +.alert-icon-warning { + fill: #c69026; +} + +.alert-icon-caution { + fill: #e5534b; +} + +/* Obsidian-style callout icon colors */ +.alert-icon-abstract, +.alert-icon-summary, +.alert-icon-tldr { + fill: #00bfff; +} + +.alert-icon-todo { + fill: #478be6; +} + +.alert-icon-success, +.alert-icon-done { + fill: #57ab5a; +} + +.alert-icon-question, +.alert-icon-help, +.alert-icon-faq { + fill: #c69026; +} + +.alert-icon-failure, +.alert-icon-fail, +.alert-icon-missing { + fill: #e5534b; +} + +.alert-icon-danger, +.alert-icon-error { + fill: #e5534b; +} + +.alert-icon-bug { + fill: #e5534b; +} + +.alert-icon-example { + fill: #986ee2; +} + +.alert-icon-quote, +.alert-icon-cite { + fill: #9ca3af; +} + +/* ==================== 代码块 ==================== */ +pre.code__pre, +.hljs.code__pre { + font-size: 90%; + overflow-x: auto; + border-radius: 8px; + padding: 0 !important; + line-height: 1.5; + margin: 10px 8px; + box-shadow: inset 0 0 10px rgba(0,0,0,0.05); +} + +/* ==================== 图片 ==================== */ +img { + display: block; + max-width: 100%; + margin: 0.1em auto 0.5em; + border-radius: 4px; +} + +/* ==================== 列表 ==================== */ +ol { + padding-left: 1em; + margin-left: 0; + color: hsl(var(--foreground)); +} + +ul { + list-style: circle; + padding-left: 1em; + margin-left: 0; + color: hsl(var(--foreground)); +} + +li { + display: block; + margin: 0.2em 8px; + color: hsl(var(--foreground)); +} + +/* ==================== 脚注 ==================== */ +/* footnotes 在 buildFootnotes() 中渲染为

标签 */ +p.footnotes { + margin: 0.5em 8px; + font-size: 80%; + color: hsl(var(--foreground)); +} + +/* ==================== 图表 ==================== */ +figure { + margin: 1.5em 8px; + color: hsl(var(--foreground)); +} + +figcaption, +.md-figcaption { + text-align: center; + color: #888; + font-size: 0.8em; +} + +/* ==================== 分隔线 ==================== */ +hr { + border-style: solid; + border-width: 2px 0 0; + border-color: rgba(0, 0, 0, 0.1); + -webkit-transform-origin: 0 0; + -webkit-transform: scale(1, 0.5); + transform-origin: 0 0; + transform: scale(1, 0.5); + height: 0.4em; + margin: 1.5em 0; +} + +/* ==================== 行内代码 ==================== */ +code { + font-size: 90%; + color: #d14; + background: rgba(27, 31, 35, 0.05); + padding: 3px 5px; + border-radius: 4px; +} + +/* 代码块内的 code 标签需要特殊处理(覆盖行内 code 样式) */ +pre.code__pre > code, +.hljs.code__pre > code { + display: -webkit-box; + padding: 0.5em 1em 1em; + overflow-x: auto; + text-indent: 0; + color: inherit; + background: none; + white-space: nowrap; + margin: 0; +} + +/* ==================== 强调 ==================== */ +em { + font-style: italic; + font-size: inherit; +} + +/* ==================== 链接 ==================== */ +a { + color: #576b95; + text-decoration: none; +} + +/* ==================== 粗体 ==================== */ +strong { + color: var(--md-primary-color); + font-weight: bold; + font-size: inherit; +} + +/* ==================== 表格 ==================== */ +table { + color: hsl(var(--foreground)); +} + +thead { + font-weight: bold; + color: hsl(var(--foreground)); +} + +th { + border: 1px solid #dfdfdf; + padding: 0.25em 0.5em; + color: hsl(var(--foreground)); + word-break: keep-all; + background: rgba(0, 0, 0, 0.05); +} + +td { + border: 1px solid #dfdfdf; + padding: 0.25em 0.5em; + color: hsl(var(--foreground)); + word-break: keep-all; +} + +/* ==================== KaTeX 公式 ==================== */ +.katex-inline { + max-width: 100%; + overflow-x: auto; +} + +.katex-block { + max-width: 100%; + overflow-x: auto; + -webkit-overflow-scrolling: touch; + padding: 0.5em 0; + text-align: center; +} + +/* ==================== 标记高亮 ==================== */ +.markup-highlight { + background-color: var(--md-primary-color); + padding: 2px 4px; + border-radius: 2px; + color: #fff; +} + +.markup-underline { + text-decoration: underline; + text-decoration-color: var(--md-primary-color); +} + +.markup-wavyline { + text-decoration: underline wavy; + text-decoration-color: var(--md-primary-color); + text-decoration-thickness: 2px; +} diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/themes/grace.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/themes/grace.css new file mode 100644 index 0000000..161e5f4 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/themes/grace.css @@ -0,0 +1,136 @@ +/** + * MD 优雅主题 (@brzhang) + * 在默认主题基础上添加优雅的视觉效果 + */ + +/* ==================== 标题样式 ==================== */ +h1 { + padding: 0.5em 1em; + border-bottom: 2px solid var(--md-primary-color); + font-size: calc(var(--md-font-size) * 1.4); + text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.1); +} + +h2 { + padding: 0.3em 1em; + border-radius: 8px; + font-size: calc(var(--md-font-size) * 1.3); + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); +} + +h3 { + padding-left: 12px; + font-size: calc(var(--md-font-size) * 1.2); + border-left: 4px solid var(--md-primary-color); + border-bottom: 1px dashed var(--md-primary-color); +} + +h4 { + font-size: calc(var(--md-font-size) * 1.1); +} + +h5 { + font-size: var(--md-font-size); +} + +h6 { + font-size: var(--md-font-size); +} + +/* ==================== 引用块 ==================== */ +blockquote { + font-style: italic; + padding: 1em 1em 1em 2em; + border-left: 4px solid var(--md-primary-color); + border-radius: 6px; + color: rgba(0, 0, 0, 0.6); + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05); + margin-bottom: 1em; +} + +.markdown-alert { + font-style: italic; +} + +/* ==================== 代码块 ==================== */ +pre.code__pre, +.hljs.code__pre { + box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.05); +} + +pre.code__pre > code, +.hljs.code__pre > code { + font-family: + 'Fira Code', + Menlo, + Operator Mono, + Consolas, + Monaco, + monospace; +} + +/* ==================== 图片 ==================== */ +img { + border-radius: 8px; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); +} + +figcaption, +.md-figcaption { + text-align: center; + color: #888; + font-size: 0.8em; +} + +/* ==================== 列表 ==================== */ +ol { + padding-left: 1.5em; +} + +ul { + list-style: none; + padding-left: 1.5em; +} + +li { + margin: 0.5em 8px; +} + +/* ==================== 分隔线 ==================== */ +hr { + height: 1px; + border: none; + margin: 2em 0; + background: linear-gradient(to right, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0)); +} + +/* ==================== 表格 ==================== */ +table { + border-collapse: separate; + border-spacing: 0; + border-radius: 8px; + margin: 1em 8px; + color: hsl(var(--foreground)); + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); + overflow: hidden; +} + +thead { + color: #fff; +} + +td { + padding: 0.5em 1em; +} + +/* ==================== 强调 ==================== */ +em { + font-style: italic; + font-size: inherit; +} + +/* ==================== 链接 ==================== */ +a { + color: #576b95; + text-decoration: none; +} diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/themes/modern.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/themes/modern.css new file mode 100644 index 0000000..ccd2cc0 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/themes/modern.css @@ -0,0 +1,465 @@ +/** + * MD 现代主题 (modern) + * 大圆角、药丸形标题、宽松行距、现代感 + * 如需使用主题色,请使用 var(--md-primary-color) 代替颜色值 + */ + +/* ==================== 容器样式覆盖 ==================== */ +section, +container { + font-family: var(--md-font-family); + font-size: var(--md-font-size); + line-height: 2; + letter-spacing: 0px; + font-weight: 400; + background-color: var(--md-container-bg); + border: 1px solid rgba(255, 255, 255, 0.01); + border-radius: 25px; + padding: 12px 12px; +} + +#output { + font-family: var(--md-font-family); + font-size: var(--md-font-size); + line-height: 2; +} + +/* ==================== 一级标题 ==================== */ +h1 { + display: table; + padding: 0.3em 1em; + margin: 20px auto; + color: hsl(var(--foreground)); + background: var(--md-primary-color); + border-radius: 15px; + font-size: 28px; + font-weight: bold; + text-align: center; +} + +/* ==================== 二级标题 ==================== */ +h2 { + display: block; + padding: 0.2em 0; + padding-bottom: 0; + margin: 0 auto 20px; + width: 100%; + color: var(--md-primary-color); + font-size: 20px; + font-weight: bold; + letter-spacing: 0.578px; + line-height: 1.7; + border-bottom: 2px solid var(--md-accent-color); + text-align: left; +} + +/* ==================== 三级标题 ==================== */ +h3 { + padding-left: 10px; + border-left: 4px solid var(--md-primary-color); + border-radius: 2px; + margin: 0 8px 10px; + color: hsl(var(--foreground)); + font-size: 20px; + font-weight: bold; + line-height: 1.2; +} + +/* ==================== 四级标题 ==================== */ +h4 { + margin: 0 8px 10px; + color: var(--md-primary-color); + font-size: 16px; + font-weight: bold; +} + +/* ==================== 五级标题 ==================== */ +h5 { + display: inline-block; + margin: 0 8px 10px; + padding: 4px 12px; + color: hsl(var(--foreground)); + background: rgba(255, 255, 255, 0.7); + border: 1px solid rgb(189, 224, 254); + border-radius: 20px; + font-size: 16px; + font-weight: 500; +} + +/* ==================== 六级标题 ==================== */ +h6 { + margin: 0 8px 10px; + color: var(--md-primary-color); + font-size: 16px; + font-weight: bold; +} + +/* ==================== 段落 ==================== */ +p { + margin: 20px 0; + letter-spacing: 0.1em; + color: hsl(var(--foreground)); + line-height: 2; + letter-spacing: 0px; + font-size: 15px; + font-weight: 400; + word-break: break-all; +} + +/* ==================== 引用块 ==================== */ +blockquote { + font-style: normal; + padding: 15px 0; + margin: 12px 0; + border-left: 7px solid var(--md-accent-color); + border-radius: 10px; + color: hsl(var(--foreground)); + background-color: var(--blockquote-background); +} + +blockquote > p { + display: block; + font-size: 1em; + letter-spacing: 0.1em; + color: hsl(var(--foreground)); + margin: 0; +} + +/* ==================== GFM 警告块 ==================== */ +.alert-title-note, +.alert-title-tip, +.alert-title-info, +.alert-title-important, +.alert-title-warning, +.alert-title-caution, +.alert-title-abstract, +.alert-title-summary, +.alert-title-tldr, +.alert-title-todo, +.alert-title-success, +.alert-title-done, +.alert-title-question, +.alert-title-help, +.alert-title-faq, +.alert-title-failure, +.alert-title-fail, +.alert-title-missing, +.alert-title-danger, +.alert-title-error, +.alert-title-bug, +.alert-title-example, +.alert-title-quote, +.alert-title-cite { + display: flex; + align-items: center; + gap: 0.5em; + margin-bottom: 0.5em; +} + +.alert-title-note { + color: #478be6; +} + +.alert-title-tip { + color: #57ab5a; +} + +.alert-title-info { + color: #93c5fd; +} + +.alert-title-important { + color: #986ee2; +} + +.alert-title-warning { + color: #c69026; +} + +.alert-title-caution { + color: #e5534b; +} + +.alert-title-abstract, +.alert-title-summary, +.alert-title-tldr { + color: #00bfff; +} + +.alert-title-todo { + color: #478be6; +} + +.alert-title-success, +.alert-title-done { + color: #57ab5a; +} + +.alert-title-question, +.alert-title-help, +.alert-title-faq { + color: #c69026; +} + +.alert-title-failure, +.alert-title-fail, +.alert-title-missing { + color: #e5534b; +} + +.alert-title-danger, +.alert-title-error { + color: #e5534b; +} + +.alert-title-bug { + color: #e5534b; +} + +.alert-title-example { + color: #986ee2; +} + +.alert-title-quote, +.alert-title-cite { + color: #9ca3af; +} + +/* GFM Alert SVG 图标颜色 */ +.alert-icon-note { + fill: #478be6; +} + +.alert-icon-tip { + fill: #57ab5a; +} + +.alert-icon-info { + fill: #93c5fd; +} + +.alert-icon-important { + fill: #986ee2; +} + +.alert-icon-warning { + fill: #c69026; +} + +.alert-icon-caution { + fill: #e5534b; +} + +.alert-icon-abstract, +.alert-icon-summary, +.alert-icon-tldr { + fill: #00bfff; +} + +.alert-icon-todo { + fill: #478be6; +} + +.alert-icon-success, +.alert-icon-done { + fill: #57ab5a; +} + +.alert-icon-question, +.alert-icon-help, +.alert-icon-faq { + fill: #c69026; +} + +.alert-icon-failure, +.alert-icon-fail, +.alert-icon-missing { + fill: #e5534b; +} + +.alert-icon-danger, +.alert-icon-error { + fill: #e5534b; +} + +.alert-icon-bug { + fill: #e5534b; +} + +.alert-icon-example { + fill: #986ee2; +} + +.alert-icon-quote, +.alert-icon-cite { + fill: #9ca3af; +} + +/* ==================== 代码块 ==================== */ +pre.code__pre, +.hljs.code__pre { + font-size: 90%; + overflow-x: auto; + border-radius: 10px; + padding: 0 !important; + line-height: 1.5; + margin: 10px 8px; + box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.05); +} + +/* ==================== 图片 ==================== */ +img { + display: block; + max-width: 100%; + margin: 0.1em auto 0.5em; + border-radius: 10px; +} + +/* ==================== 列表 ==================== */ +ol { + padding-left: 1em; + margin-left: 0; + color: hsl(var(--foreground)); + line-height: 2; +} + +ul { + list-style: circle; + padding-left: 1em; + margin-left: 0; + color: hsl(var(--foreground)); + line-height: 2; +} + +li { + display: block; + margin: 0.2em 8px; + color: hsl(var(--foreground)); +} + +/* ==================== 脚注 ==================== */ +p.footnotes { + margin: 0.5em 8px; + font-size: 80%; + color: hsl(var(--foreground)); +} + +/* ==================== 图表 ==================== */ +figure { + margin: 1.5em 8px; + color: hsl(var(--foreground)); +} + +figcaption, +.md-figcaption { + text-align: center; + color: #888; + font-size: 0.8em; +} + +/* ==================== 分隔线 ==================== */ +hr { + border-style: solid; + border-width: 1px 0 0; + border-color: var(--md-accent-color); + margin: 1.5em 0; +} + +/* ==================== 行内代码 ==================== */ +code { + font-size: 90%; + color: #d14; + background: rgba(27, 31, 35, 0.05); + padding: 3px 5px; + border-radius: 4px; +} + +/* 代码块内的 code 标签需要特殊处理(覆盖行内 code 样式) */ +pre.code__pre > code, +.hljs.code__pre > code { + display: -webkit-box; + padding: 0.5em 1em 1em; + overflow-x: auto; + text-indent: 0; + color: inherit; + background: none; + white-space: nowrap; + margin: 0; +} + +/* ==================== 强调 ==================== */ +em { + font-style: italic; + font-size: inherit; +} + +/* ==================== 链接 ==================== */ +a { + color: var(--md-primary-color); + text-decoration: none; +} + +/* ==================== 粗体 ==================== */ +strong { + color: var(--md-primary-color); + font-weight: bold; + font-size: inherit; +} + +/* ==================== 表格 ==================== */ +table { + color: hsl(var(--foreground)); +} + +thead { + font-weight: bold; + color: hsl(var(--foreground)); +} + +th { + border: 1px solid #dfdfdf; + padding: 0.25em 0.5em; + color: hsl(var(--foreground)); + word-break: keep-all; + background: color-mix(in srgb, var(--md-primary-color) 10%, transparent); +} + +td { + border: 1px solid #dfdfdf; + padding: 0.25em 0.5em; + color: hsl(var(--foreground)); + word-break: keep-all; +} + +/* ==================== KaTeX 公式 ==================== */ +.katex-inline { + max-width: 100%; + overflow-x: auto; +} + +.katex-block { + max-width: 100%; + overflow-x: auto; + -webkit-overflow-scrolling: touch; + padding: 0.5em 0; + text-align: center; +} + +/* ==================== 标记高亮 ==================== */ +.markup-highlight { + background-color: var(--md-primary-color); + padding: 2px 4px; + border-radius: 4px; + color: #fff; +} + +.markup-underline { + text-decoration: underline; + text-decoration-color: var(--md-primary-color); +} + +.markup-wavyline { + text-decoration: underline wavy; + text-decoration-color: var(--md-primary-color); + text-decoration-thickness: 2px; +} diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/themes/simple.css b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/themes/simple.css new file mode 100644 index 0000000..a1db867 --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/themes/simple.css @@ -0,0 +1,129 @@ +/** + * MD 简洁主题 (@okooo5km) + * 简洁现代的设计风格 + */ + +/* ==================== 标题样式 ==================== */ +h1 { + padding: 0.5em 1em; + font-size: calc(var(--md-font-size) * 1.4); + text-shadow: 1px 1px 3px rgba(0, 0, 0, 0.05); +} + +h2 { + padding: 0.3em 1.2em; + font-size: calc(var(--md-font-size) * 1.3); + border-radius: 8px 24px 8px 24px; + box-shadow: 0 2px 6px rgba(0, 0, 0, 0.06); +} + +h3 { + padding-left: 12px; + font-size: calc(var(--md-font-size) * 1.2); + border-radius: 6px; + line-height: 2.4em; + border-left: 4px solid var(--md-primary-color); + border-right: 1px solid color-mix(in srgb, var(--md-primary-color) 10%, transparent); + border-bottom: 1px solid color-mix(in srgb, var(--md-primary-color) 10%, transparent); + border-top: 1px solid color-mix(in srgb, var(--md-primary-color) 10%, transparent); + background: color-mix(in srgb, var(--md-primary-color) 8%, transparent); +} + +h4 { + font-size: calc(var(--md-font-size) * 1.1); + border-radius: 6px; +} + +h5 { + font-size: var(--md-font-size); + border-radius: 6px; +} + +h6 { + font-size: var(--md-font-size); + border-radius: 6px; +} + +/* ==================== 引用块 ==================== */ +blockquote { + font-style: italic; + padding: 1em 1em 1em 2em; + color: rgba(0, 0, 0, 0.6); + border-bottom: 0.2px solid rgba(0, 0, 0, 0.04); + border-top: 0.2px solid rgba(0, 0, 0, 0.04); + border-right: 0.2px solid rgba(0, 0, 0, 0.04); +} + +/* GFM Alert 样式覆盖 */ +.markdown-alert-note, +.markdown-alert-tip, +.markdown-alert-info, +.markdown-alert-important, +.markdown-alert-warning, +.markdown-alert-caution { + font-style: italic; +} + +/* ==================== 代码块 ==================== */ +pre.code__pre, +.hljs.code__pre { + border: 1px solid rgba(0, 0, 0, 0.04); +} + +pre.code__pre > code, +.hljs.code__pre > code { + font-family: + 'Fira Code', + Menlo, + Operator Mono, + Consolas, + Monaco, + monospace; +} + +/* ==================== 图片 ==================== */ +img { + border-radius: 8px; + border: 1px solid rgba(0, 0, 0, 0.04); +} + +figcaption, +.md-figcaption { + text-align: center; + color: #888; + font-size: 0.8em; +} + +/* ==================== 列表 ==================== */ +ol { + padding-left: 1.5em; +} + +ul { + list-style: none; + padding-left: 1.5em; +} + +li { + margin: 0.5em 8px; +} + +/* ==================== 分隔线 ==================== */ +hr { + height: 1px; + border: none; + margin: 2em 0; + background: linear-gradient(to right, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0)); +} + +/* ==================== 强调 ==================== */ +em { + font-style: italic; + font-size: inherit; +} + +/* ==================== 链接 ==================== */ +a { + color: #576b95; + text-decoration: none; +} diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/types.ts b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/types.ts new file mode 100644 index 0000000..669f8cb --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/types.ts @@ -0,0 +1,78 @@ +import type { ReadTimeResults } from "reading-time"; + +export type ThemeName = string; + +export interface StyleConfig { + primaryColor: string; + fontFamily: string; + fontSize: string; + foreground: string; + blockquoteBackground: string; + accentColor: string; + containerBg: string; +} + +export interface IOpts { + legend?: string; + citeStatus?: boolean; + countStatus?: boolean; + isMacCodeBlock?: boolean; + isShowLineNumber?: boolean; + themeMode?: "light" | "dark"; +} + +export interface RendererAPI { + reset: (newOpts: Partial) => void; + setOptions: (newOpts: Partial) => void; + getOpts: () => IOpts; + parseFrontMatterAndContent: (markdown: string) => { + yamlData: Record; + markdownContent: string; + readingTime: ReadTimeResults; + }; + buildReadingTime: (reading: ReadTimeResults) => string; + buildFootnotes: () => string; + buildAddition: () => string; + createContainer: (html: string) => string; +} + +export interface ParseResult { + yamlData: Record; + markdownContent: string; + readingTime: ReadTimeResults; +} + +export interface CliOptions { + inputPath: string; + theme: ThemeName; + keepTitle: boolean; + primaryColor?: string; + fontFamily?: string; + fontSize?: string; + codeTheme: string; + isMacCodeBlock: boolean; + isShowLineNumber: boolean; + citeStatus: boolean; + countStatus: boolean; + legend: string; +} + +export interface ExtendConfig { + default_theme: string | null; + default_color: string | null; + default_font_family: string | null; + default_font_size: string | null; + default_code_theme: string | null; + mac_code_block: boolean | null; + show_line_number: boolean | null; + cite: boolean | null; + count: boolean | null; + legend: string | null; + keep_title: boolean | null; +} + +export interface HtmlDocumentMeta { + title: string; + author?: string; + description?: string; +} diff --git a/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/utils/languages.ts b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/utils/languages.ts new file mode 100644 index 0000000..40905af --- /dev/null +++ b/skills/baoyu-post-to-weibo/scripts/vendor/baoyu-md/src/utils/languages.ts @@ -0,0 +1,238 @@ +import type { LanguageFn } from 'highlight.js' +import bash from 'highlight.js/lib/languages/bash' +import c from 'highlight.js/lib/languages/c' +import cpp from 'highlight.js/lib/languages/cpp' +import csharp from 'highlight.js/lib/languages/csharp' +import css from 'highlight.js/lib/languages/css' +import diff from 'highlight.js/lib/languages/diff' +import go from 'highlight.js/lib/languages/go' +import graphql from 'highlight.js/lib/languages/graphql' +import ini from 'highlight.js/lib/languages/ini' +import java from 'highlight.js/lib/languages/java' +import javascript from 'highlight.js/lib/languages/javascript' +import json from 'highlight.js/lib/languages/json' +import kotlin from 'highlight.js/lib/languages/kotlin' +import less from 'highlight.js/lib/languages/less' +import lua from 'highlight.js/lib/languages/lua' +import makefile from 'highlight.js/lib/languages/makefile' +import markdown from 'highlight.js/lib/languages/markdown' +import objectivec from 'highlight.js/lib/languages/objectivec' +import perl from 'highlight.js/lib/languages/perl' +import php from 'highlight.js/lib/languages/php' +import phpTemplate from 'highlight.js/lib/languages/php-template' +import plaintext from 'highlight.js/lib/languages/plaintext' +import python from 'highlight.js/lib/languages/python' +import pythonRepl from 'highlight.js/lib/languages/python-repl' +import r from 'highlight.js/lib/languages/r' +import ruby from 'highlight.js/lib/languages/ruby' +import rust from 'highlight.js/lib/languages/rust' +import scss from 'highlight.js/lib/languages/scss' +import shell from 'highlight.js/lib/languages/shell' +import sql from 'highlight.js/lib/languages/sql' +import swift from 'highlight.js/lib/languages/swift' +import typescript from 'highlight.js/lib/languages/typescript' +import vbnet from 'highlight.js/lib/languages/vbnet' +import wasm from 'highlight.js/lib/languages/wasm' +import xml from 'highlight.js/lib/languages/xml' +import yaml from 'highlight.js/lib/languages/yaml' + +export const COMMON_LANGUAGES: Record = { + bash, + c, + cpp, + csharp, + css, + diff, + go, + graphql, + ini, + java, + javascript, + json, + kotlin, + less, + lua, + makefile, + markdown, + objectivec, + perl, + php, + 'php-template': phpTemplate, + plaintext, + python, + 'python-repl': pythonRepl, + r, + ruby, + rust, + scss, + shell, + sql, + swift, + typescript, + vbnet, + wasm, + xml, + yaml, +} + +// highlight.js CDN 配置 +const HLJS_VERSION = `11.11.1` +const HLJS_CDN_BASE = `https://cdn-doocs.oss-cn-shenzhen.aliyuncs.com/npm/highlightjs/${HLJS_VERSION}` + +// 缓存正在加载的语言 +const loadingLanguages = new Map>() + +/** + * 生成语言包的 CDN URL + */ +function grammarUrlFor(language: string): string { + return `${HLJS_CDN_BASE}/es/languages/${language}.min.js` +} + +/** + * 动态加载并注册语言 + * @param language 语言名称 + * @param hljs highlight.js 实例 + */ +export async function loadAndRegisterLanguage(language: string, hljs: any): Promise { + // 如果已经注册,直接返回 + if (hljs.getLanguage(language)) { + return + } + + // 如果正在加载,等待加载完成 + if (loadingLanguages.has(language)) { + await loadingLanguages.get(language) + return + } + + // 开始加载 + const loadPromise = (async () => { + try { + const module = await import(/* @vite-ignore */ grammarUrlFor(language)) + hljs.registerLanguage(language, module.default) + } + catch (error) { + console.warn(`Failed to load language: ${language}`, error) + throw error + } + finally { + loadingLanguages.delete(language) + } + })() + + loadingLanguages.set(language, loadPromise) + await loadPromise +} + +/** + * 格式化高亮后的代码,处理空格和制表符 + */ +function formatHighlightedCode(html: string, preserveNewlines = false): string { + let formatted = html + // 将 span 之间的空格移到 span 内部 + formatted = formatted.replace(/(]*>[^<]*<\/span>)(\s+)(]*>[^<]*<\/span>)/g, (_: string, span1: string, spaces: string, span2: string) => span1 + span2.replace(/^(]*>)/, `$1${spaces}`)) + formatted = formatted.replace(/(\s+)(]*>)/g, (_: string, spaces: string, span: string) => span.replace(/^(]*>)/, `$1${spaces}`)) + // 替换制表符为4个空格 + formatted = formatted.replace(/\t/g, ` `) + + if (preserveNewlines) { + // 替换换行符为
,并将空格转换为   + formatted = formatted.replace(/\r\n/g, `
`).replace(/\n/g, `
`).replace(/(>[^<]+)|(^[^<]+)/g, (str: string) => str.replace(/\s/g, ` `)) + } + else { + // 只将空格转换为   + formatted = formatted.replace(/(>[^<]+)|(^[^<]+)/g, (str: string) => str.replace(/\s/g, ` `)) + } + + return formatted +} + +/** + * 高亮代码并格式化(支持行号) + * @param text 原始代码文本 + * @param language 语言名称 + * @param hljs highlight.js 实例 + * @param showLineNumber 是否显示行号 + * @returns 格式化后的 HTML + */ +export function highlightAndFormatCode(text: string, language: string, hljs: any, showLineNumber: boolean): string { + let highlighted = `` + + if (showLineNumber) { + const rawLines = text.replace(/\r\n/g, `\n`).split(`\n`) + + const highlightedLines = rawLines.map((lineRaw) => { + const lineHtml = hljs.highlight(lineRaw, { language }).value + const formatted = formatHighlightedCode(lineHtml, false) + return formatted === `` ? ` ` : formatted + }) + + const lineNumbersHtml = highlightedLines.map((_, idx) => `

${idx + 1}
`).join(``) + const codeInnerHtml = highlightedLines.join(`
`) + const codeLinesHtml = `
${codeInnerHtml}
` + const lineNumberColumnStyles = `text-align:right;padding:8px 0;border-right:1px solid rgba(0,0,0,0.04);user-select:none;background:var(--code-bg,transparent);` + + highlighted = ` +
+
${lineNumbersHtml}
+
${codeLinesHtml}
+
+ ` + } + else { + const rawHighlighted = hljs.highlight(text, { language }).value + highlighted = formatHighlightedCode(rawHighlighted, true) + } + + return highlighted +} + +export function highlightCodeBlock(codeBlock: Element, language: string, hljs: any): void { + const rawCode = codeBlock.getAttribute(`data-raw-code`) + const showLineNumber = codeBlock.getAttribute(`data-show-line-number`) === `true` + + if (!rawCode) + return + + const text = rawCode.replace(/"/g, `"`) + + const highlighted = highlightAndFormatCode(text, language, hljs, showLineNumber) + + codeBlock.innerHTML = highlighted + codeBlock.removeAttribute(`data-language-pending`) + codeBlock.removeAttribute(`data-raw-code`) + codeBlock.removeAttribute(`data-show-line-number`) +} + +/** + * 高亮 DOM 中待处理的代码块 + * 查找带有 data-language-pending 属性的代码块,动态加载语言后重新高亮 + * @param hljs highlight.js 实例 + * @param container 容器元素(可选,默认为 document) + */ +export function highlightPendingBlocks(hljs: any, container: Document | Element = document): void { + const pendingBlocks = container.querySelectorAll(`code[data-language-pending]`) + + pendingBlocks.forEach((codeBlock) => { + const language = codeBlock.getAttribute(`data-language-pending`) + if (!language) + return + + if (hljs.getLanguage(language)) { + // 语言已加载,直接高亮 + highlightCodeBlock(codeBlock, language, hljs) + } + else { + // 动态加载语言后重新高亮 + loadAndRegisterLanguage(language, hljs).then(() => { + highlightCodeBlock(codeBlock, language, hljs) + }).catch(() => { + // 加载失败,移除标记 + codeBlock.removeAttribute(`data-language-pending`) + codeBlock.removeAttribute(`data-raw-code`) + codeBlock.removeAttribute(`data-show-line-number`) + }) + } + }) +}