@@ -127,6 +127,35 @@ describe("loss-aware reverse Markdown conversion", () => {
127127 expect ( reverse ( [ { type : "paywall" } , { type : "paywall" } ] ) . unsupported_nodes ) . toContainEqual ( expect . objectContaining ( { type : "paywall" } ) ) ;
128128 expect ( reverse ( [ { type : "ordered_list" , attrs : { order : 1_000_000_000 } , content : [ { type : "list_item" , content : [ paragraph ( text ( "A" ) ) ] } ] } ] ) . status ) . toBe ( "partial" ) ;
129129 } ) ;
130+ it ( "treats the editor's default textAlign: null as lossless and still reports real alignment" , ( ) => {
131+ const aligned = ( align : unknown ) => ( { attrs : { textAlign : align } } ) ;
132+ const editorDoc = [
133+ { type : "heading" , attrs : { level : 2 , textAlign : null } , content : [ text ( "Title" ) ] } ,
134+ { ...paragraph ( text ( "Body " ) , text ( "bold" , [ { type : "bold" } ] ) ) , ...aligned ( null ) } ,
135+ { type : "blockquote" , content : [ { ...paragraph ( text ( "Quoted" ) ) , ...aligned ( null ) } ] } ,
136+ ] ;
137+ const result = reverse ( editorDoc ) ;
138+ expect ( result . status ) . toBe ( "converted" ) ;
139+ expect ( result . unsupported_nodes ) . toEqual ( [ ] ) ;
140+ expect ( result . markdown ) . toBe ( "## Title\n\nBody **bold**\n\n> Quoted\n" ) ;
141+ for ( const align of [ "center" , "right" , "" ] ) {
142+ const partial = reverse ( [ { ...paragraph ( text ( "x" ) ) , ...aligned ( align ) } ] ) ;
143+ expect ( partial . status ) . toBe ( "partial" ) ;
144+ expect ( partial . unsupported_nodes ) . toContainEqual ( expect . objectContaining ( { path : "/content/0/attrs" , type : "paragraph" } ) ) ;
145+ }
146+ expect ( reverse ( [ { type : "heading" , attrs : { level : 2 , textAlign : "center" } , content : [ text ( "T" ) ] } ] ) . status ) . toBe ( "partial" ) ;
147+ expect ( reverse ( [ { ...paragraph ( text ( "x" ) ) , attrs : { textAlign : null , indent : 1 } } ] ) . status ) . toBe ( "partial" ) ;
148+ } ) ;
149+
150+ it ( "exports a body captured from the editor, with textAlign: null, as converted" , ( ) => {
151+ const fixture = JSON . parse ( readFileSync ( new URL ( "./fixtures/footnotes-editor.json" , import . meta. url ) , "utf8" ) ) ;
152+ const withEditorDefaults = JSON . parse ( JSON . stringify ( fixture . document ) , ( key , value ) =>
153+ value && typeof value === "object" && value . type === "paragraph" ? { ...value , attrs : { textAlign : null } } : value ) ;
154+ const result = prosemirrorToMarkdown ( JSON . stringify ( withEditorDefaults ) ) ;
155+ expect ( result . status ) . toBe ( "converted" ) ;
156+ expect ( convertMarkdown ( result . markdown ! ) . document ) . toEqual ( fixture . document ) ;
157+ } ) ;
158+
130159 it ( "exports editor footnotes and reimports the identical structure" , ( ) => {
131160 const fixture = JSON . parse ( readFileSync ( new URL ( "./fixtures/footnotes-editor.json" , import . meta. url ) , "utf8" ) ) ;
132161 const result = prosemirrorToMarkdown ( JSON . stringify ( fixture . document ) ) ;
0 commit comments