11import type { Block , ExtendedProperties , Inline , Theme } from '@md/shared/types'
2+
23import type { PropertiesHyphen } from 'csstype'
34
5+ import { selectorComments } from '@md/shared'
6+ import { css2json , downloadFile } from '@md/shared/utils'
7+
48/**
59 * 自定义主题
610 * @param theme - 基础主题
@@ -60,27 +64,32 @@ export function customCssWithTemplate(jsonString: Partial<Record<Block | Inline,
6064 `blockquote` ,
6165 `blockquote_note` ,
6266 `blockquote_tip` ,
67+ `blockquote_info` ,
6368 `blockquote_important` ,
6469 `blockquote_warning` ,
6570 `blockquote_caution` ,
6671 `blockquote_p` ,
6772 `blockquote_p_note` ,
6873 `blockquote_p_tip` ,
74+ `blockquote_p_info` ,
6975 `blockquote_p_important` ,
7076 `blockquote_p_warning` ,
7177 `blockquote_p_caution` ,
7278 `blockquote_title` ,
7379 `blockquote_title_note` ,
7480 `blockquote_title_tip` ,
81+ `blockquote_title_info` ,
7582 `blockquote_title_important` ,
7683 `blockquote_title_warning` ,
7784 `blockquote_title_caution` ,
7885 `image` ,
7986 `ul` ,
8087 `ol` ,
88+ `footnotes` ,
89+ `figure` ,
8190 `block_katex` ,
8291 ]
83- const inlineKeys : Inline [ ] = [ `listitem` , `codespan` , `link` , `wx_link` , `strong` , `table` , `thead` , `td` , `footnote` , `figcaption` , `em` , `inline_katex` ]
92+ const inlineKeys : Inline [ ] = [ `listitem` , `codespan` , `link` , `wx_link` , `strong` , `table` , `thead` , `td` , `footnote` , `figcaption` , `em` , `inline_katex` , `markup_highlight` , `markup_underline` , `markup_wavyline` ]
8493
8594 mergeProperties ( newTheme . block , jsonString , blockKeys )
8695 mergeProperties ( newTheme . inline , jsonString , inlineKeys )
@@ -95,3 +104,150 @@ export function customCssWithTemplate(jsonString: Partial<Record<Block | Inline,
95104export function getStyleString ( style : ExtendedProperties ) : string {
96105 return Object . entries ( style ?? { } ) . map ( ( [ key , value ] ) => `${ key } : ${ value } ` ) . join ( `; ` )
97106}
107+
108+ export function generateThemeCSS ( theme : Theme ) : string {
109+ const cssLines : string [ ] = [ ]
110+
111+ // 添加注释说明
112+ cssLines . push ( `/**` )
113+ cssLines . push ( ` * 按 Alt/Option + Shift + F 可格式化` )
114+ cssLines . push ( ` * 如需使用主题色,请使用 var(--md-primary-color) 代替颜色值` )
115+ cssLines . push ( ` * 如:color: var(--md-primary-color);` )
116+ cssLines . push ( ` */` )
117+ cssLines . push ( `` )
118+
119+ // 生成基础样式(顶层容器)
120+ cssLines . push ( `/* 顶层容器样式 */` )
121+ cssLines . push ( `container {` )
122+ cssLines . push ( `}` )
123+ cssLines . push ( `` )
124+
125+ // 生成块级元素样式
126+ Object . entries ( theme . block ) . forEach ( ( [ selector , styles ] ) => {
127+ if ( selector !== `container` ) {
128+ const comment = selectorComments [ selector as Block | Inline ] || `${ selector } 样式`
129+ cssLines . push ( `/* ${ comment } */` )
130+ cssLines . push ( `${ selector } {` )
131+ Object . entries ( styles ) . forEach ( ( [ property , value ] ) => {
132+ if ( value ) {
133+ cssLines . push ( ` ${ property } : ${ value } ;` )
134+ }
135+ } )
136+ cssLines . push ( `}` )
137+ cssLines . push ( `` )
138+ }
139+ } )
140+
141+ // 生成内联元素样式
142+ Object . entries ( theme . inline ) . forEach ( ( [ selector , styles ] ) => {
143+ const comment = selectorComments [ selector as Block | Inline ] || `${ selector } 样式`
144+ cssLines . push ( `/* ${ comment } */` )
145+ cssLines . push ( `${ selector } {` )
146+ Object . entries ( styles ) . forEach ( ( [ property , value ] ) => {
147+ if ( value ) {
148+ cssLines . push ( ` ${ property } : ${ value } ;` )
149+ }
150+ } )
151+ cssLines . push ( `}` )
152+ cssLines . push ( `` )
153+ } )
154+
155+ return cssLines . join ( `\n` )
156+ }
157+
158+ /**
159+ * 导出合并后的主题CSS
160+ * @param customCSS - 用户自定义的CSS内容
161+ * @param baseTheme - 基础主题
162+ * @param primaryColor - 主色调
163+ * @param fontSize - 字体大小
164+ * @param fileName - 导出文件名
165+ */
166+ export function exportMergedTheme (
167+ customCSS : string ,
168+ baseTheme : Theme ,
169+ primaryColor : string ,
170+ fontSize : number ,
171+ fileName : string = `merged-theme` ,
172+ ) : void {
173+ // 将自定义CSS转换为JSON格式
174+ const customThemeJson = css2json ( customCSS )
175+
176+ // 使用基础主题和自定义样式合并
177+ const customizedTheme = customizeTheme ( baseTheme , {
178+ fontSize,
179+ color : primaryColor ,
180+ } )
181+
182+ // 使用模板合并自定义CSS
183+ const mergedTheme = customCssWithTemplate (
184+ customThemeJson ,
185+ primaryColor ,
186+ customizedTheme ,
187+ )
188+
189+ // 生成最终的CSS内容
190+ const finalCSS = generateMergedThemeCSS ( mergedTheme )
191+
192+ // 下载文件
193+ downloadFile ( finalCSS , `${ fileName } .css` , `text/css` )
194+ }
195+
196+ /**
197+ * 生成合并后主题的完整CSS
198+ * @param theme - 合并后的主题对象
199+ * @returns CSS字符串
200+ */
201+ function generateMergedThemeCSS ( theme : Theme ) : string {
202+ const cssLines : string [ ] = [ ]
203+
204+ // 添加文件头注释
205+ cssLines . push ( `/**` )
206+ cssLines . push ( ` * 导出的合并主题CSS` )
207+ cssLines . push ( ` * 包含内置主题和自定义样式的完整合并版本` )
208+ cssLines . push ( ` * 生成时间: ${ new Date ( ) . toLocaleString ( `zh-CN` ) } ` )
209+ cssLines . push ( ` */` )
210+ cssLines . push ( `` )
211+
212+ // 添加CSS变量定义
213+ cssLines . push ( `:root {` )
214+ Object . entries ( theme . base ) . forEach ( ( [ property , value ] ) => {
215+ cssLines . push ( ` ${ property } : ${ value } ;` )
216+ } )
217+ cssLines . push ( `}` )
218+ cssLines . push ( `` )
219+
220+ // 生成块级元素样式
221+ Object . entries ( theme . block ) . forEach ( ( [ selector , styles ] ) => {
222+ if ( Object . keys ( styles ) . length > 0 ) {
223+ const comment = selectorComments [ selector as Block | Inline ] || `${ selector } 样式`
224+ cssLines . push ( `/* ${ comment } */` )
225+ cssLines . push ( `${ selector } {` )
226+ Object . entries ( styles ) . forEach ( ( [ property , value ] ) => {
227+ if ( value ) {
228+ cssLines . push ( ` ${ property } : ${ value } ;` )
229+ }
230+ } )
231+ cssLines . push ( `}` )
232+ cssLines . push ( `` )
233+ }
234+ } )
235+
236+ // 生成内联元素样式
237+ Object . entries ( theme . inline ) . forEach ( ( [ selector , styles ] ) => {
238+ if ( Object . keys ( styles ) . length > 0 ) {
239+ const comment = selectorComments [ selector as Block | Inline ] || `${ selector } 样式`
240+ cssLines . push ( `/* ${ comment } */` )
241+ cssLines . push ( `${ selector } {` )
242+ Object . entries ( styles ) . forEach ( ( [ property , value ] ) => {
243+ if ( value ) {
244+ cssLines . push ( ` ${ property } : ${ value } ;` )
245+ }
246+ } )
247+ cssLines . push ( `}` )
248+ cssLines . push ( `` )
249+ }
250+ } )
251+
252+ return cssLines . join ( `\n` )
253+ }
0 commit comments