1
1
import type { Block , ExtendedProperties , Inline , Theme } from '@md/shared/types'
2
+
2
3
import type { PropertiesHyphen } from 'csstype'
3
4
5
+ import { selectorComments } from '@md/shared'
6
+ import { css2json , downloadFile } from '@md/shared/utils'
7
+
4
8
/**
5
9
* 自定义主题
6
10
* @param theme - 基础主题
@@ -60,27 +64,32 @@ export function customCssWithTemplate(jsonString: Partial<Record<Block | Inline,
60
64
`blockquote` ,
61
65
`blockquote_note` ,
62
66
`blockquote_tip` ,
67
+ `blockquote_info` ,
63
68
`blockquote_important` ,
64
69
`blockquote_warning` ,
65
70
`blockquote_caution` ,
66
71
`blockquote_p` ,
67
72
`blockquote_p_note` ,
68
73
`blockquote_p_tip` ,
74
+ `blockquote_p_info` ,
69
75
`blockquote_p_important` ,
70
76
`blockquote_p_warning` ,
71
77
`blockquote_p_caution` ,
72
78
`blockquote_title` ,
73
79
`blockquote_title_note` ,
74
80
`blockquote_title_tip` ,
81
+ `blockquote_title_info` ,
75
82
`blockquote_title_important` ,
76
83
`blockquote_title_warning` ,
77
84
`blockquote_title_caution` ,
78
85
`image` ,
79
86
`ul` ,
80
87
`ol` ,
88
+ `footnotes` ,
89
+ `figure` ,
81
90
`block_katex` ,
82
91
]
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` ]
84
93
85
94
mergeProperties ( newTheme . block , jsonString , blockKeys )
86
95
mergeProperties ( newTheme . inline , jsonString , inlineKeys )
@@ -95,3 +104,150 @@ export function customCssWithTemplate(jsonString: Partial<Record<Block | Inline,
95
104
export function getStyleString ( style : ExtendedProperties ) : string {
96
105
return Object . entries ( style ?? { } ) . map ( ( [ key , value ] ) => `${ key } : ${ value } ` ) . join ( `; ` )
97
106
}
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