diff --git a/src/assets/example/theme-css.txt b/src/assets/example/theme-css.txt index 9c04218..35d0c83 100644 --- a/src/assets/example/theme-css.txt +++ b/src/assets/example/theme-css.txt @@ -33,29 +33,53 @@ blockquote { /* 引用段落样式 */ blockquote_p { } -/* GFM 警告块 */ -markdown-alert { +/* GFM note 样式 */ +blockquote_note { } -/* GFM 警告块标题 */ -markdown-alert-title { +/* GFM tip 样式 */ +blockquote_tip { } -/* GFM 警告块内容,抵消 p 默认的 margin */ -markdown-alert-content-wrapper { +/* GFM important 样式 */ +blockquote_important { } -/* GFM note */ -markdown-alert-title-note { +/* GFM warning 样式 */ +blockquote_warning { } -/* GFM tip */ -markdown-alert-title-tip { +/* GFM caution 样式 */ +blockquote_caution { } -/* GFM important */ -markdown-alert-title-important { +/* GFM 通用标题 */ +blockquote_title { } -/* GFM warning */ -markdown-alert-title-warning { +/* GFM note 标题 */ +blockquote_title_note { } -/* GFM caution */ -markdown-alert-title-caution { +/* GFM tip 标题 */ +blockquote_title_tip { +} +/* GFM important 标题 */ +blockquote_title_important { +} +/* GFM warning 标题 */ +blockquote_title_warning { +} +/* GFM caution 标题 */ +blockquote_title_caution { +} +/* GFM note 段落样式 */ +blockquote_p_note { +} +/* GFM tip 段落样式 */ +blockquote_p_tip { +} +/* GFM important 段落样式 */ +blockquote_p_important { +} +/* GFM warning 段落样式 */ +blockquote_p_warning { +} +/* GFM caution 段落样式 */ +blockquote_p_caution { } /* 段落样式 */ p { diff --git a/src/config/theme.ts b/src/config/theme.ts index 842fafe..d4934ca 100644 --- a/src/config/theme.ts +++ b/src/config/theme.ts @@ -10,7 +10,7 @@ const defaultTheme: Theme = { }, block: { // 一级标题 - 'h1': { + h1: { 'display': `table`, 'padding': `0 1em`, 'border-bottom': `2px solid var(--md-primary-color)`, @@ -22,7 +22,7 @@ const defaultTheme: Theme = { }, // 二级标题 - 'h2': { + h2: { 'display': `table`, 'padding': `0 0.2em`, 'margin': `4em auto 2em`, @@ -34,7 +34,7 @@ const defaultTheme: Theme = { }, // 三级标题 - 'h3': { + h3: { 'padding-left': `8px`, 'border-left': `3px solid var(--md-primary-color)`, 'margin': `2em 8px 0.75em 0`, @@ -45,7 +45,7 @@ const defaultTheme: Theme = { }, // 四级标题 - 'h4': { + h4: { 'margin': `2em 8px 0.5em`, 'color': `var(--md-primary-color)`, 'font-size': `1em`, @@ -53,7 +53,7 @@ const defaultTheme: Theme = { }, // 五级标题 - 'h5': { + h5: { 'margin': `1.5em 8px 0.5em`, 'color': `var(--md-primary-color)`, 'font-size': `1em`, @@ -61,14 +61,14 @@ const defaultTheme: Theme = { }, // 六级标题 - 'h6': { + h6: { 'margin': `1.5em 8px 0.5em`, 'font-size': `1em`, 'color': `var(--md-primary-color)`, }, // 段落 - 'p': { + p: { 'margin': `1.5em 8px`, 'letter-spacing': `0.1em`, 'color': `var(--el-text-color-regular)`, @@ -76,7 +76,7 @@ const defaultTheme: Theme = { }, // 引用 - 'blockquote': { + blockquote: { 'font-style': `normal`, 'border-left': `none`, 'padding': `1em`, @@ -87,57 +87,73 @@ const defaultTheme: Theme = { }, // 引用内容 - 'blockquote_p': { + blockquote_p: { 'display': `block`, 'font-size': `1em`, 'letter-spacing': `0.1em`, 'color': `var(--el-text-color-regular)`, }, - // GFM 警告块 - 'markdown-alert': { - 'font-style': `normal`, - 'border-left': `none`, - 'padding': `1em`, - 'border-radius': `8px`, - 'background': `var(--blockquote-background)`, - 'margin': `2em 8px`, + blockquote_note: { + }, + + blockquote_tip: { + }, + + blockquote_important: { + }, + + blockquote_warning: { + }, + + blockquote_caution: { }, // GFM 警告块标题 - 'markdown-alert-title': { + blockquote_title: { 'display': `flex`, 'align-items': `center`, 'gap': `0.5em`, + 'margin-bottom': `0.5em`, }, - // GFM 警告块内容,抵消 p 默认的 margin - 'markdown-alert-content-wrapper': { - margin: `-1em -8px -1.5em;`, - }, - - 'markdown-alert-title-note': { + blockquote_title_note: { color: `#478be6`, }, - 'markdown-alert-title-tip': { + blockquote_title_tip: { color: `#57ab5a`, }, - 'markdown-alert-title-important': { + blockquote_title_important: { color: `#986ee2`, }, - 'markdown-alert-title-warning': { + blockquote_title_warning: { color: `#c69026`, }, - 'markdown-alert-title-caution': { + blockquote_title_caution: { color: `#e5534b`, }, + blockquote_p_note: { + }, + + blockquote_p_tip: { + }, + + blockquote_p_important: { + }, + + blockquote_p_warning: { + }, + + blockquote_p_caution: { + }, + // 代码块 - 'code_pre': { + code_pre: { 'font-size': `14px`, 'overflow-x': `auto`, 'border-radius': `8px`, @@ -147,14 +163,14 @@ const defaultTheme: Theme = { }, // 行内代码 - 'code': { + code: { 'margin': 0, 'white-space': `nowrap`, 'font-family': `Menlo, Operator Mono, Consolas, Monaco, monospace`, }, // 图片 - 'image': { + image: { 'display': `block`, 'width': `100% !important`, 'margin': `0.1em auto 0.5em`, @@ -162,32 +178,32 @@ const defaultTheme: Theme = { }, // 有序列表 - 'ol': { + ol: { 'padding-left': `1em`, 'margin-left': `0`, 'color': `var(--el-text-color-regular)`, }, // 无序列表 - 'ul': { + ul: { 'list-style': `circle`, 'padding-left': `1em`, 'margin-left': `0`, 'color': `var(--el-text-color-regular)`, }, - 'footnotes': { + footnotes: { 'margin': `0.5em 8px`, 'font-size': `80%`, 'color': `var(--el-text-color-regular)`, }, - 'figure': { + figure: { margin: `1.5em 8px`, color: `var(--el-text-color-regular)`, }, - 'hr': { + hr: { 'border-style': `solid`, 'border-width': `1px 0 0`, 'border-color': `rgba(0,0,0,0.1)`, diff --git a/src/types/index.ts b/src/types/index.ts index 28742e4..cd05de4 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -2,7 +2,8 @@ import type { PropertiesHyphen } from 'csstype' import type { Token } from 'marked' -export type Block = `h1` | `h2` | `h3` | `h4` | `h5` | `h6` | `p` | `blockquote` | `blockquote_p` | `code_pre` | `code` | `image` | `ol` | `ul` | `footnotes` | `figure` | `hr` +type GFMBlock = `blockquote_note` | `blockquote_tip` | `blockquote_important` | `blockquote_warning` | `blockquote_caution` | `blockquote_title` | `blockquote_title_note` | `blockquote_title_tip` | `blockquote_title_important` | `blockquote_title_warning` | `blockquote_title_caution` | `blockquote_p` | `blockquote_p_note` | `blockquote_p_tip` | `blockquote_p_important` | `blockquote_p_warning` | `blockquote_p_caution` +export type Block = `h1` | `h2` | `h3` | `h4` | `h5` | `h6` | `p` | `blockquote` | `blockquote_p` | `code_pre` | `code` | `image` | `ol` | `ul` | `footnotes` | `figure` | `hr` | GFMBlock export type Inline = `listitem` | `codespan` | `link` | `wx_link` | `strong` | `table` | `thead` | `td` | `footnote` | `figcaption` | `em` interface CustomCSSProperties { @@ -14,8 +15,8 @@ export type ExtendedProperties = PropertiesHyphen & CustomCSSProperties export interface Theme { base: ExtendedProperties - block: Record - inline: Record + block: Record + inline: Record } export interface IOpts { @@ -41,7 +42,7 @@ export interface IConfigOption { export interface AlertOptions { className?: string variants?: AlertVariantItem[] - theme?: Theme + styles?: ThemeStyles } /** diff --git a/src/utils/MDAlert.ts b/src/utils/MDAlert.ts index 03108c4..3aa5a54 100644 --- a/src/utils/MDAlert.ts +++ b/src/utils/MDAlert.ts @@ -29,6 +29,8 @@ export default function markedAlert(options: AlertOptions = {}): MarkedExtension } = matchedVariant const typeRegexp = new RegExp(createSyntaxPattern(variantType), `i`) + const { styles } = options + Object.assign(token, { type: `alert`, meta: { @@ -37,16 +39,17 @@ export default function markedAlert(options: AlertOptions = {}): MarkedExtension icon, title, titleClassName, - style: { - ...options.theme?.block[className], - ...options.theme?.block[`${className}-${variantType}`], + wrapperStyle: { + ...styles?.blockquote, + ...styles?.[`blockquote_${variantType}` as keyof typeof styles], }, titleStyle: { - ...options.theme?.block[titleClassName], - ...options.theme?.block[`${titleClassName}-${variantType}`], + ...styles?.blockquote_title, + ...styles?.[`blockquote_title_${variantType}` as keyof typeof styles], }, - contentWrapperStyle: { - margin: options.theme?.block[`${className}-content-wrapper`]?.margin, + contentStyle: { + ...styles?.blockquote_p, + ...styles?.[`blockquote_p_${variantType}` as keyof typeof styles], }, }, }) @@ -76,15 +79,17 @@ export default function markedAlert(options: AlertOptions = {}): MarkedExtension name: `alert`, level: `block`, renderer({ meta, tokens = [] }) { - let tmpl = `
\n` - tmpl += `

` + let text = this.parser.parse(tokens) + text = text.replace(/

/g, `

`) + let tmpl = `

\n` + tmpl += `

` tmpl += meta.icon.replace( `\n` - tmpl += `${this.parser.parse(tokens)}` + tmpl += text tmpl += `

\n` return tmpl diff --git a/src/utils/index.ts b/src/utils/index.ts index c072d38..f4fb685 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -34,7 +34,7 @@ export function customizeTheme(theme: Theme, options: { export function customCssWithTemplate(jsonString: Partial>, color: string, theme: Theme) { const newTheme = customizeTheme(theme, { color }) - const mergeProperties = (target: Record, source: Partial>, keys: T[]) => { + const mergeProperties = (target: Record, source: Partial>, keys: T[]) => { keys.forEach((key) => { if (source[key]) { target[key] = Object.assign(target[key] || {}, source[key]) @@ -42,7 +42,7 @@ export function customCssWithTemplate(jsonString: Partial): void { opts = { ...opts, ...newOpts } styleMapping = buildTheme(opts) - marked.use(markedAlert({ theme: opts.theme })) + marked.use(markedAlert({ styles: styleMapping })) } const buildFootnotes = () => {