@@ -35,6 +35,7 @@ export default class CodeBlock extends ParagraphBase {
3535 this . customParser = { } ;
3636 this . wrap = config . wrap ; // 超出是否换行
3737 this . lineNumber = config . lineNumber ; // 是否显示行号
38+ this . indentedCodeBlock = typeof config . indentedCodeBlock === 'undefined' ? true : config . indentedCodeBlock ; // 是否支持缩进代码块
3839 if ( config && config . customRenderer ) {
3940 this . customLang = Object . keys ( config . customRenderer ) . map ( ( lang ) => lang . toLowerCase ( ) ) ;
4041 this . customParser = { ...config . customRenderer } ;
@@ -196,9 +197,66 @@ export default class CodeBlock extends ParagraphBase {
196197 return cacheCode ;
197198 }
198199
200+ /**
201+ * 获取缩进代码块语法的正则
202+ */
203+ $getIndentedCodeReg ( ) {
204+ const ret = {
205+ begin : '(?:^|\\n\\s*\\n)(?: {4}|\\t)' ,
206+ end : '(?=$|\\n( {0,3}[^ \\t\\n]|\\n[^ \\t\\n]))' ,
207+ content : '([\\s\\S]+?)' ,
208+ } ;
209+ return new RegExp ( ret . begin + ret . content + ret . end , 'g' ) ;
210+ }
211+
212+ /**
213+ * 生成缩进代码块(没有行号、没有代码高亮)
214+ */
215+ $getIndentCodeBlock ( str ) {
216+ if ( ! this . indentedCodeBlock ) {
217+ return str ;
218+ }
219+ return this . $recoverCodeInIndent ( str ) . replace ( this . $getIndentedCodeReg ( ) , ( match , code ) => {
220+ const lineCount = ( match . match ( / \n / g) || [ ] ) . length - 1 ;
221+ const sign = this . $engine . md5 ( match ) ;
222+ const html = `<pre data-sign="${ sign } " data-lines="${ lineCount } ">${ escapeHTMLSpecialChar (
223+ code . replace ( / \n ( { 4 } | \t ) / g, '\n' ) ,
224+ ) } </pre>`;
225+ // return this.getCacheWithSpace(this.pushCache(html), match, true);
226+ return this . pushCache ( html , sign , lineCount ) ;
227+ } ) ;
228+ }
229+
230+ /**
231+ * 预处理缩进代码块,将缩进代码块里的高亮代码块和行内代码进行占位处理
232+ */
233+ $replaceCodeInIndent ( str ) {
234+ if ( ! this . indentedCodeBlock ) {
235+ return str ;
236+ }
237+ return str . replace ( this . $getIndentedCodeReg ( ) , ( match ) => {
238+ return match . replace ( / ` / g, '~~~IndentCode' ) ;
239+ } ) ;
240+ }
241+
242+ /**
243+ * 恢复预处理的内容
244+ */
245+ $recoverCodeInIndent ( str ) {
246+ if ( ! this . indentedCodeBlock ) {
247+ return str ;
248+ }
249+ return str . replace ( this . $getIndentedCodeReg ( ) , ( match ) => {
250+ return match . replace ( / ~ ~ ~ I n d e n t C o d e / g, '`' ) ;
251+ } ) ;
252+ }
253+
199254 beforeMakeHtml ( str , sentenceMakeFunc , markdownParams ) {
200255 let $str = str ;
201256
257+ // 预处理缩进代码块
258+ $str = this . $replaceCodeInIndent ( $str ) ;
259+
202260 $str = $str . replace ( this . RULE . reg , ( match , leadingContent , lang , code ) => {
203261 let $code = code ;
204262 const { sign, lines } = this . computeLines ( match , leadingContent , code ) ;
@@ -262,6 +320,10 @@ export default class CodeBlock extends ParagraphBase {
262320 } ) ;
263321 $str = $str . replace ( / ~ ~ n o t ~ i n l i n e C o d e / g, '\\`' ) ;
264322 }
323+
324+ // 处理缩进代码块
325+ $str = this . $getIndentCodeBlock ( $str ) ;
326+
265327 return $str ;
266328 }
267329
0 commit comments