feat: i18n for container custom block

This commit is contained in:
YunYouJun 2025-07-13 20:27:15 +08:00
parent 068bcd1801
commit 53050885d4
11 changed files with 65 additions and 63 deletions

View File

@ -107,9 +107,6 @@ export default defineValaxyConfig<ThemeConfig>({
tip: {
icon: 'i-carbon-thumbs-up',
text: 'ヒント',
langs: {
'zh-CN': '提示',
},
},
warning: {
icon: 'i-carbon-warning-alt',

View File

@ -47,9 +47,6 @@ export default defineValaxyConfig<ThemeConfig>({
tip: {
icon: 'i-carbon-thumbs-up',
text: 'ヒント',
langs: {
'zh-CN': '提示',
},
},
warning: {
icon: 'i-carbon-warning-alt',

View File

@ -6,9 +6,11 @@ import 'valaxy/client/styles/common/index.scss'
import 'vitepress/dist/client/theme-default/styles/vars.css'
import 'vitepress/dist/client/theme-default/styles/icons.css'
// with custom block title
import 'valaxy/client/styles/components/custom-block.scss'
// import 'vitepress/dist/client/theme-default/styles/base.css'
// import 'vitepress/dist/client/theme-default/styles/utils.css'
import 'vitepress/dist/client/theme-default/styles/components/custom-block.css'
// import 'vitepress/dist/client/theme-default/styles/components/custom-block.css'
import 'vitepress/dist/client/theme-default/styles/components/vp-code.css'
import 'vitepress/dist/client/theme-default/styles/components/vp-code-group.css'
import 'vitepress/dist/client/theme-default/styles/components/vp-doc.css'

View File

@ -8,9 +8,10 @@ $c-primary: #0078e7 !default;
);
// override the default style of star-markdown-css
@use "./animations/index.scss" as *;
@use "./common/button.scss" as *;
@use "./common/markdown.scss" as *;
// valaxy client styles
@use 'valaxy/client/styles/components/code.scss' as *;
@use 'valaxy/client/styles/components/code-group.scss' as *;
@use 'valaxy/client/styles/components/custom-block.scss' as *;
@use "./animations/index.scss" as *;

View File

@ -0,0 +1,16 @@
<script setup lang="ts">
// import { useValaxyI18n } from 'valaxy'
import { useI18n } from 'vue-i18n'
defineProps<{
title: string
}>()
const { t } = useI18n()
</script>
<template>
<span>
{{ t(title) }}
</span>
</template>

View File

@ -110,3 +110,10 @@ time:
tooltip:
last_updated: Last updated
blocks:
tip: TIP
warning: WARNING
danger: DANGER
info: INFO
details: DETAILS

View File

@ -109,3 +109,10 @@ time:
tooltip:
last_updated: 最后更新于
blocks:
tip: 提示
warning: 注意
danger: 警告
info: 信息
details: 详情

View File

@ -1,6 +1,5 @@
/* stylelint-disable no-descending-specificity */
.custom-block-title {
margin-bottom: -0.4rem;
margin-bottom: 0.4rem !important;
font-weight: 600;
display: flex;
align-items: center;

View File

@ -4,9 +4,6 @@
import type { MarkdownItAsync } from 'markdown-it-async'
import type Token from 'markdown-it/lib/token.mjs'
import type {
Options,
} from './preWrapper'
import container from 'markdown-it-container'
import {
extractTitle,
@ -20,7 +17,8 @@ type ContainerArgs = [
},
]
function createContainer(classes: string, { icon, color, text: defaultTitle, langs }: BlockItem = {}, md: MarkdownItAsync): ContainerArgs {
function createContainer(key: string, block: BlockItem = {}, md: MarkdownItAsync): ContainerArgs {
const classes = key
return [
container,
classes,
@ -33,16 +31,10 @@ function createContainer(classes: string, { icon, color, text: defaultTitle, lan
const info = token.info.trim().slice(classes.length).trim()
let iconTag = ''
if (icon)
iconTag = `<i class="icon ${icon}" ${color ? `style="color: ${color}"` : ''}></i>`
if (block.icon)
iconTag = `<i class="icon ${block.icon}" ${block.color ? `style="color: ${block.color}"` : ''}></i>`
let titleWithLang = `<span lang="en">${info || defaultTitle}</span>`
if (langs) {
Object.keys(langs).forEach((lang) => {
titleWithLang += `<span lang="${lang}">${info || langs[lang]}</span>`
})
}
const title = md.renderInline(titleWithLang, {})
const title = `<ValaxyContainerBlockTitle title="blocks.${key}" />`
const titleClass
= `custom-block-title${info ? '' : ' custom-block-title-default'}`
@ -62,10 +54,6 @@ export interface BlockItem {
text?: string
icon?: string
color?: string
/**
* for i18n
*/
langs?: { [key: string]: string }
}
export interface Blocks {
@ -76,49 +64,35 @@ export interface Blocks {
details?: BlockItem
}
export type ContainerOptions = Blocks & Partial<Options>
export interface ContainerOptions {
blocks?: Blocks
languages?: string[]
}
const defaultBlocksOptions: ContainerOptions = {
const defaultBlocksOptions: Blocks = {
tip: {
text: 'TIP',
langs: {
'zh-CN': '提示',
},
},
warning: {
text: 'WARNING',
langs: {
'zh-CN': '注意',
},
},
danger: {
text: 'DANGER',
langs: {
'zh-CN': '警告',
},
},
info: {
text: 'INFO',
langs: {
'zh-CN': '信息',
},
},
details: {
text: 'Details',
langs: {
'zh-CN': '详情',
},
},
}
export function containerPlugin(md: MarkdownItAsync, containerOptions: ContainerOptions = {}) {
const blockKeys = new Set(Object.keys(Object.assign(defaultBlocksOptions, containerOptions)))
const blockKeys = new Set(Object.keys(Object.assign({}, defaultBlocksOptions, containerOptions.blocks)))
blockKeys.forEach((optionKey) => {
const option: BlockItem = {
...defaultBlocksOptions[optionKey as keyof Blocks],
...(containerOptions[optionKey as keyof Blocks] || {}),
}
const key = optionKey as keyof Blocks
const userOption = containerOptions.blocks?.[key] || {}
const option: BlockItem = Object.assign({}, defaultBlocksOptions[key], userOption)
md.use(...createContainer(optionKey, option, md))
})
@ -132,7 +106,7 @@ export function containerPlugin(md: MarkdownItAsync, containerOptions: Container
tokens[idx].nesting === 1 ? `<div class="vp-raw">\n` : `</div>\n`,
})
const languages = containerOptions.siteConfig?.languages || ['zh-CN', 'en']
const languages = containerOptions.languages || ['zh-CN', 'en']
languages.forEach((lang) => {
md.use(container, lang, {
render: (tokens: Token[], idx: number) =>

View File

@ -2,11 +2,9 @@
import type MarkdownIt from 'markdown-it'
import type { SiteConfig } from '../../../../../types'
import type { MarkdownEnv } from '../../env'
import type { ThemeOptions } from '../../types'
export interface Options {
codeCopyButtonTitle: string
theme: ThemeOptions
siteConfig?: SiteConfig
}
@ -66,7 +64,7 @@ export function preWrapperPlugin(md: MarkdownIt, options: Options) {
return (
`<div class="language-${lang}${active}${codeHeightLimitClass}">`
+ `<button title="${options.codeCopyButtonTitle}" class="copy"></button>`
+ `<button title="${options.codeCopyButtonTitle || 'Copy code'}" class="copy"></button>`
+ `<span class="lang">${lang}</span>`
+ `${rawCode}`
+ '<button class="collapse"></button>'

View File

@ -6,35 +6,36 @@ import type { TocPluginOptions } from '@mdit-vue/plugin-toc'
import type MarkdownIt from 'markdown-it'
import type { MarkdownItAsync } from 'markdown-it-async'
import type Token from 'markdown-it/lib/token.mjs'
import type { ResolvedValaxyOptions } from '../../options'
import type { UserSiteConfig } from '../../../types'
import type { ResolvedValaxyOptions } from '../../options'
import type { ThemeOptions } from './types'
import {
headersPlugin,
} from '@mdit-vue/plugin-headers'
import { sfcPlugin } from '@mdit-vue/plugin-sfc'
import { titlePlugin } from '@mdit-vue/plugin-title'
import { tocPlugin } from '@mdit-vue/plugin-toc'
import { slugify } from '@mdit-vue/shared'
import { cssI18nContainer } from 'css-i18n'
import anchorPlugin from 'markdown-it-anchor'
import attrsPlugin from 'markdown-it-attrs'
import attrsPlugin from 'markdown-it-attrs'
import { full as emojiPlugin } from 'markdown-it-emoji'
import footnotePlugin from 'markdown-it-footnote'
// https://www.npmjs.com/package/markdown-it-image-figures
import imageFigures from 'markdown-it-image-figures'
import TaskLists from 'markdown-it-task-lists'
import TaskLists from 'markdown-it-task-lists'
import { groupIconMdPlugin } from 'vitepress-plugin-group-icons'
import { linkPlugin } from './plugins/link'
import { containerPlugin } from './plugins/markdown-it/container'
import { footnoteTooltipPlugin } from './plugins/markdown-it/footnoteTooltip'
import { highlightLinePlugin } from './plugins/markdown-it/highlightLines'
import Katex from './plugins/markdown-it/katex'
import Katex from './plugins/markdown-it/katex'
import { lineNumberPlugin } from './plugins/markdown-it/lineNumbers'
import { preWrapperPlugin } from './plugins/markdown-it/preWrapper'
import { snippetPlugin } from './plugins/markdown-it/snippet'
@ -49,7 +50,7 @@ export async function setupMarkdownPlugins(
) {
const mdOptions = options?.config.markdown || {}
const theme = mdOptions.theme ?? defaultCodeTheme
const siteConfig = options?.config.siteConfig || {}
const siteConfig: UserSiteConfig = options?.config.siteConfig || {}
if (mdOptions.preConfig)
mdOptions.preConfig(md)
@ -59,9 +60,12 @@ export async function setupMarkdownPlugins(
.use(preWrapperPlugin, { theme, siteConfig })
.use(snippetPlugin, options?.userRoot)
.use(containerPlugin, {
siteConfig,
...mdOptions.blocks,
languages: siteConfig.languages,
...mdOptions?.container,
blocks: {
...mdOptions.blocks,
...mdOptions.container?.blocks,
},
})
.use(cssI18nContainer, {
languages: options?.config.siteConfig.languages,