feat(creator-studio): dialog-driven table/math/footnote, theme quote, code language picker
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
7c33482be7
commit
7885f42cff
14 files changed
+1005
-54
No files matched your search
@@ -2,8 +2,8 @@
|
||||
* 正文块的 HTML 片段。
|
||||
*
|
||||
* 这些块都由服务端再次清洗(FrontSubmitSave 的 wp_kses_post),因此这里只负责
|
||||
* 生成符合前台渲染习惯的结构:代码块沿用 enlighter 的既有高亮约定,脚注与公式
|
||||
* 使用主题前台已有的渲染口径,目录使用文章目录树识别标题的 data-nav 结构。
|
||||
* 生成符合前台渲染习惯的结构:代码块沿用 enlighter 的既有高亮约定,引用沿用
|
||||
* 主题的 .quote_q 结构,目录使用文章目录树识别标题的占位结构。
|
||||
*
|
||||
* @package Jio
|
||||
*/
|
||||
@@ -24,27 +24,71 @@ export function dividerMarkup(): string {
|
||||
return '<hr><p></p>';
|
||||
}
|
||||
|
||||
/**
|
||||
* 代码块:沿用前台 enlighter 的高亮标记,未选择语言时按通用代码展示。
|
||||
*/
|
||||
export function codeBlockMarkup(): string {
|
||||
export type CodeLanguage = { value: string; label: string };
|
||||
|
||||
/** 常用语言;与前台 enlighter 的语言标识保持一致。 */
|
||||
export const CODE_LANGUAGES: CodeLanguage[] = [
|
||||
{ value: 'generic', label: __('通用', 'jio') },
|
||||
{ value: 'javascript', label: 'JavaScript' },
|
||||
{ value: 'typescript', label: 'TypeScript' },
|
||||
{ value: 'php', label: 'PHP' },
|
||||
{ value: 'python', label: 'Python' },
|
||||
{ value: 'java', label: 'Java' },
|
||||
{ value: 'go', label: 'Go' },
|
||||
{ value: 'rust', label: 'Rust' },
|
||||
{ value: 'csharp', label: 'C#' },
|
||||
{ value: 'cpp', label: 'C++' },
|
||||
{ value: 'sql', label: 'SQL' },
|
||||
{ value: 'json', label: 'JSON' },
|
||||
{ value: 'bash', label: 'Shell' },
|
||||
{ value: 'css', label: 'CSS' },
|
||||
{ value: 'html', label: 'HTML' },
|
||||
{ value: 'markdown', label: 'Markdown' },
|
||||
];
|
||||
|
||||
/** 语言值 → 展示名;未知值原样返回。 */
|
||||
export function codeLabel(language: string): string {
|
||||
return CODE_LANGUAGES.find((item) => item.value === language)?.label || language;
|
||||
}
|
||||
|
||||
/** 代码块:语言写在 data 属性里,前台 enlighter 与编辑器标签共用。 */
|
||||
export function codeBlockMarkup(language = 'generic', code = ''): string {
|
||||
const body = code !== '' ? escapeHtml(code) : escapeHtml(__('在此输入代码', 'jio'));
|
||||
return (
|
||||
'<pre class="enlighter-pre"><code class="gl" data-enlighter-language="generic">' +
|
||||
escapeHtml(__('在此输入代码', 'jio')) +
|
||||
`<pre class="enlighter-pre" data-enlighter-language="${escapeHtml(language)}"><code class="gl" data-enlighter-language="${escapeHtml(language)}">` +
|
||||
body +
|
||||
'</code></pre><p></p>'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 表格:3×3 带表头,方便作者直接在单元格里改写。
|
||||
*/
|
||||
export function tableMarkup(): string {
|
||||
const cell = (tag: string, text: string): string => `<${tag}>${escapeHtml(text)}</${tag}>`;
|
||||
const header = `<tr>${[1, 2, 3].map((i) => cell('th', `${__('列', 'jio')} ${i}`)).join('')}</tr>`;
|
||||
const rows = [1, 2]
|
||||
.map(() => `<tr>${[1, 2, 3].map(() => cell('td', '')).join('')}</tr>`)
|
||||
.join('');
|
||||
return `<table class="jio-content-table"><thead>${header}</thead><tbody>${rows}</tbody></table><p></p>`;
|
||||
export type TableOptions = {
|
||||
rows: number;
|
||||
cols: number;
|
||||
header: boolean;
|
||||
striped: boolean;
|
||||
};
|
||||
|
||||
/** 带尺寸参数的表格;首行可选表头,隔行变色写入 class。 */
|
||||
export function tableMarkup({ rows, cols, header, striped }: TableOptions): string {
|
||||
const totalRows = Math.max(1, Math.min(20, rows));
|
||||
const totalCols = Math.max(1, Math.min(10, cols));
|
||||
const cellsFor = (tag: 'th' | 'td'): string =>
|
||||
Array.from({ length: totalCols }, (_, column) =>
|
||||
`<${tag}>${tag === 'th' ? escapeHtml(`${__('列', 'jio')} ${column + 1}`) : ''}</${tag}>`
|
||||
).join('');
|
||||
|
||||
let body = '';
|
||||
if (header) {
|
||||
body += `<thead><tr>${cellsFor('th')}</tr></thead>`;
|
||||
}
|
||||
const bodyRows = Math.max(1, header ? totalRows - 1 : totalRows);
|
||||
body += `<tbody>${Array.from({ length: bodyRows }, () => `<tr>${cellsFor('td')}</tr>`).join('')}</tbody>`;
|
||||
|
||||
const classes = ['jio-content-table'];
|
||||
if (striped) {
|
||||
classes.push('is-striped');
|
||||
}
|
||||
return `<table class="${classes.join(' ')}">${body}</table><p></p>`;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -52,15 +96,35 @@ export function tableMarkup(): string {
|
||||
* 因此这里只放一个占位标记,读者端不会看到裸露的标记文本。
|
||||
*/
|
||||
export function tocMarkup(): string {
|
||||
return `<div class="jio-toc-placeholder"></div><p></p>`;
|
||||
return '<div class="jio-toc-placeholder"></div><p></p>';
|
||||
}
|
||||
|
||||
/** 注释:Markdown 脚注语法,前台由文章渲染流程转成编号脚注。 */
|
||||
export function footnoteMarkup(): string {
|
||||
return '<p>[^1]<br>[^1]: ' + escapeHtml(__('注释内容', 'jio')) + '</p>';
|
||||
/** 注释:Markdown 脚注语法,前台渲染成编号脚注列表。 */
|
||||
export function footnoteMarkup(note: string): string {
|
||||
const text = note.trim() || __('注释内容', 'jio');
|
||||
return `<p>[^1]<br>[^1]: ${escapeHtml(text)}</p>`;
|
||||
}
|
||||
|
||||
/** 公式:行内 LaTeX,包在主题可识别的公式容器里。 */
|
||||
export function mathMarkup(): string {
|
||||
return `<span class="jio-math">E = mc^2</span>`;
|
||||
export type MathOptions = { formula: string; display: boolean };
|
||||
|
||||
/** 公式:行内或独占一行,数据保存在 .jio-math 容器里。 */
|
||||
export function mathMarkup({ formula, display }: MathOptions): string {
|
||||
const className = display ? 'jio-math jio-math--block' : 'jio-math';
|
||||
const body = `<span class="${className}">${escapeHtml(formula.trim())}</span>`;
|
||||
return display ? `<p>${body}</p>` : body;
|
||||
}
|
||||
|
||||
export type QuoteColor = '' | 'qe_wzk_c-red' | 'qe_wzk_lan' | 'qe_wzk_lv';
|
||||
|
||||
/**
|
||||
* 引用:沿用主题的 .quote_q 结构(.quote-mce 提供左侧引号标记),
|
||||
* 颜色通过主题已有的 qe_wzk_* 类切换。
|
||||
*/
|
||||
export function quoteMarkup(content: string, color: QuoteColor): string {
|
||||
const classes = ['quote_q', 'quote-mce'];
|
||||
if (color) {
|
||||
classes.push(color);
|
||||
}
|
||||
const inner = content.trim() !== '' ? `<p>${content}</p>` : '<p></p>';
|
||||
return `<div class="${classes.join(' ')}"><div>${inner}</div></div><p></p>`;
|
||||
}
|
||||
Reference in new issue
Block a user