11import type { ExtensionAuto , YENodeSpec } from '../../../../core' ;
22import { nodeTypeFactory } from '../../../../utils/schema' ;
33
4+ export const CodeBlockNodeAttr = {
5+ Lang : 'data-language' ,
6+ Markup : 'data-markup' ,
7+ } as const ;
8+
49export const codeBlockNodeName = 'code_block' ;
5- export const codeBlockLangAttr = 'data-language' ;
10+ /** @deprecated Use __CodeBlockNodeAttr__ instead */
11+ export const codeBlockLangAttr = CodeBlockNodeAttr . Lang ;
612export const codeBlockType = nodeTypeFactory ( codeBlockNodeName ) ;
713
814export type CodeBlockSpecsOptions = {
@@ -13,7 +19,10 @@ export const CodeBlockSpecs: ExtensionAuto<CodeBlockSpecsOptions> = (builder, op
1319 builder . addNode ( codeBlockNodeName , ( ) => ( {
1420 view : opts . nodeview ,
1521 spec : {
16- attrs : { [ codeBlockLangAttr ] : { default : 'text' } } ,
22+ attrs : {
23+ [ CodeBlockNodeAttr . Lang ] : { default : '' } ,
24+ [ CodeBlockNodeAttr . Markup ] : { default : '```' } ,
25+ } ,
1726 content : 'text*' ,
1827 group : 'block' ,
1928 code : true ,
@@ -25,13 +34,13 @@ export const CodeBlockSpecs: ExtensionAuto<CodeBlockSpecsOptions> = (builder, op
2534 tag : 'pre' ,
2635 preserveWhitespace : 'full' ,
2736 getAttrs : ( node ) => ( {
28- [ codeBlockLangAttr ] :
29- ( node as Element ) . getAttribute ( codeBlockLangAttr ) || '' ,
37+ [ CodeBlockNodeAttr . Lang ] :
38+ ( node as Element ) . getAttribute ( CodeBlockNodeAttr . Lang ) || '' ,
3039 } ) ,
3140 } ,
3241 ] ,
3342 toDOM ( { attrs} ) {
34- return [ 'pre' , attrs [ codeBlockLangAttr ] ? attrs : { } , [ 'code' , 0 ] ] ;
43+ return [ 'pre' , attrs , [ 'code' , 0 ] ] ;
3544 } ,
3645 } ,
3746 fromYfm : {
@@ -43,11 +52,14 @@ export const CodeBlockSpecs: ExtensionAuto<CodeBlockSpecsOptions> = (builder, op
4352 } ,
4453 } ,
4554 toYfm : ( state , node ) => {
46- state . write ( '```' + ( node . attrs [ codeBlockLangAttr ] || '' ) + '\n' ) ;
55+ const lang : string = node . attrs [ CodeBlockNodeAttr . Lang ] ;
56+ const markup : string = node . attrs [ CodeBlockNodeAttr . Markup ] ;
57+
58+ state . write ( markup + lang + '\n' ) ;
4759 state . text ( node . textContent , false ) ;
4860 // Add a newline to the current content before adding closing marker
4961 state . write ( '\n' ) ;
50- state . write ( '```' ) ;
62+ state . write ( markup ) ;
5163 state . closeBlock ( node ) ;
5264 } ,
5365 } ) ) ;
@@ -60,7 +72,17 @@ export const CodeBlockSpecs: ExtensionAuto<CodeBlockSpecsOptions> = (builder, op
6072 name : codeBlockNodeName ,
6173 type : 'block' ,
6274 noCloseToken : true ,
63- getAttrs : ( tok ) => ( { [ codeBlockLangAttr ] : tok . info || '' } ) ,
75+ getAttrs : ( tok ) => {
76+ const attrs : Record < string , string > = {
77+ [ CodeBlockNodeAttr . Markup ] : tok . markup ,
78+ } ;
79+ if ( tok . info ) {
80+ // like in markdown-it
81+ // https://github.com/markdown-it/markdown-it/blob/d07d585b6b15aaee2bc8f7a54b994526dad4dbc5/lib/renderer.mjs#L36-L37
82+ attrs [ CodeBlockNodeAttr . Lang ] = tok . info . split ( / ( \s + ) / g) [ 0 ] ;
83+ }
84+ return attrs ;
85+ } ,
6486 prepareContent : removeNewLineAtEnd , // content of fence blocks contains extra \n at the end
6587 } ,
6688 } ,
0 commit comments