release: 发布 v0.5.1
新增能力:内置 4 套红头、3 套正式文档和 3 套标书主题,支持主题推荐页边距、页面装饰、页眉页脚和页码;增加结构化公文、项目报告及标书 Front Matter,内置 Fandol 中文字体、两份教程和 14 份主题示例。 桌面工作流:重组更多菜单,增加新建、保存、另存为快捷键和未保存确认;另存为后跟随新路径,主题示例自动切换主题,Desktop 发行包完整携带教程、示例与字体。 问题修复:修正红头标题居中与正式文档字体;围栏代码按正文宽度自动换行,长内容安全断行,至少两行即可在当前页分页,并统一保留 8px 左侧内容留白;Docker Web 镜像正确打包 samples。 兼容与部署:未声明主题推荐设置时继续使用 16mm 默认页边距;Web 隐藏不适用的另存为。正式镜像 yixiong/md-to-pdf:v0.5.1 内容 ID 为 sha256:72f519a69bfd6cb2f6df30c2be938e58ceb6f20e4748a32551874de3d436b276,Compose 健康运行。 验证结果:最终修复前 65 个测试文件、286 项测试通过,最终代码块与主题定向测试 27 项通过;全项目类型检查、生产构建和 git diff --check 通过。容器检出 14 套主题、17 份 Markdown,代码块回归 PDF 为 2 页且无越界。NSIS SHA-256 为 676CCE73D782B0B15AC6BC68F253CFBC4740383583E4DAA98F746EDF9999C5CC,ZIP SHA-256 为 82BF6ADF1200604F145CC86FA3ED193955CF6741EBEE3DF8953483515CFF621F。
This commit is contained in:
@@ -3,12 +3,14 @@ import { footnote } from "@mdit/plugin-footnote";
|
||||
import { katex } from "@mdit/plugin-katex";
|
||||
import { tasklist } from "@mdit/plugin-tasklist";
|
||||
import type {
|
||||
DocumentProfile,
|
||||
MarkdownDocumentMetadata,
|
||||
RenderedMarkdownDocument,
|
||||
ThemeFeature
|
||||
} from "@md-to-pdf/core";
|
||||
import {
|
||||
classifyDocumentLink,
|
||||
documentProfileSchema,
|
||||
isSafeDocumentLink
|
||||
} from "@md-to-pdf/core";
|
||||
import {
|
||||
@@ -22,6 +24,7 @@ import type { Options as MarkdownItOptions } from "markdown-it";
|
||||
import type Renderer from "markdown-it/lib/renderer.mjs";
|
||||
import type Token from "markdown-it/lib/token.mjs";
|
||||
import sanitizeHtml from "sanitize-html";
|
||||
import { renderDocumentStructure } from "./render-document-structure.js";
|
||||
|
||||
export const RENDERER_VERSION = 1;
|
||||
|
||||
@@ -350,7 +353,11 @@ export function renderMarkdown(
|
||||
options.language ?? "zh-CN",
|
||||
extractFirstHeading(parsed.content)
|
||||
);
|
||||
const articleHtml = `<article id="write" class="markdown-body" lang="${escapeAttribute(metadata.language)}">${bodyHtml}</article>`;
|
||||
const structure = renderDocumentStructure(metadata);
|
||||
const profileAttribute = structure
|
||||
? ` data-document-profile="${structure.profile}"`
|
||||
: "";
|
||||
const articleHtml = `<article id="write" class="markdown-body" lang="${escapeAttribute(metadata.language)}"${profileAttribute}>${structure?.prefixHtml ?? ""}${bodyHtml}${structure?.suffixHtml ?? ""}</article>`;
|
||||
|
||||
return {
|
||||
rendererVersion: RENDERER_VERSION,
|
||||
@@ -405,10 +412,30 @@ function normalizeMetadata(
|
||||
author: readString(data.author),
|
||||
subject: readString(data.subject) || readString(data.description),
|
||||
keywords: readStringList(data.keywords ?? data.tags),
|
||||
language: readString(data.language ?? data.lang) || fallbackLanguage
|
||||
language: readString(data.language ?? data.lang) || fallbackLanguage,
|
||||
...(data.document === undefined
|
||||
? {}
|
||||
: { document: normalizeDocumentProfile(data.document) })
|
||||
};
|
||||
}
|
||||
|
||||
function normalizeDocumentProfile(value: unknown): DocumentProfile {
|
||||
const parsed = documentProfileSchema.safeParse(value);
|
||||
if (parsed.success) {
|
||||
return parsed.data;
|
||||
}
|
||||
|
||||
const details = parsed.error.issues
|
||||
.map((issue) => {
|
||||
const path = ["document", ...issue.path].join(".");
|
||||
return `${path}:${issue.message}`;
|
||||
})
|
||||
.join(";");
|
||||
throw new MarkdownDocumentParseError(
|
||||
`文档结构配置无效:${details}`
|
||||
);
|
||||
}
|
||||
|
||||
function readString(value: unknown): string {
|
||||
if (typeof value === "string") {
|
||||
return value.trim();
|
||||
|
||||
Reference in New Issue
Block a user