@@ -23,6 +23,10 @@ def _paragraph(value):
2323 return {"type" : "paragraph" , "content" : [_text (value )]}
2424
2525
26+ def _paragraph_with (* inline_nodes ):
27+ return {"type" : "paragraph" , "content" : list (inline_nodes )}
28+
29+
2630def test_document_to_markdown_golden_covers_supported_nodes ():
2731 image = captioned_image (
2832 "https://example.com/image.png" ,
@@ -161,6 +165,86 @@ def test_document_to_markdown_golden_covers_supported_nodes():
161165 ]
162166
163167
168+ def test_document_to_markdown_renders_text_color ():
169+ document = {
170+ "type" : "doc" ,
171+ "content" : [
172+ _paragraph_with (
173+ _text ("c" , [{"type" : "textStyle" , "attrs" : {"color" : "#ff00ff" }}])
174+ )
175+ ],
176+ }
177+ markdown , unsupported = document_to_markdown (document )
178+ assert unsupported == []
179+ assert markdown == '[c]{style="color:#ff00ff"}\n '
180+
181+
182+ def test_document_to_markdown_renders_highlight ():
183+ document = {
184+ "type" : "doc" ,
185+ "content" : [
186+ _paragraph_with (
187+ _text ("h" , [{"type" : "highlight" , "attrs" : {"color" : "#ffff00" }}])
188+ )
189+ ],
190+ }
191+ markdown , unsupported = document_to_markdown (document )
192+ assert unsupported == []
193+ assert markdown == '[h]{style="background-color:#ffff00"}\n '
194+
195+
196+ def test_document_to_markdown_renders_combined_color_and_highlight ():
197+ document = {
198+ "type" : "doc" ,
199+ "content" : [
200+ _paragraph_with (
201+ _text (
202+ "both" ,
203+ [
204+ {"type" : "textStyle" , "attrs" : {"color" : "#fff" }},
205+ {"type" : "highlight" , "attrs" : {"color" : "#000" }},
206+ ],
207+ )
208+ )
209+ ],
210+ }
211+ markdown , unsupported = document_to_markdown (document )
212+ assert unsupported == []
213+ assert markdown == '[both]{style="color:#fff; background-color:#000"}\n '
214+
215+
216+ @pytest .mark .parametrize (
217+ "mark" ,
218+ [
219+ {"type" : "textStyle" , "attrs" : {}},
220+ {"type" : "highlight" , "attrs" : {"color" : 1 }},
221+ {"type" : "textStyle" , "attrs" : {"color" : "#fff" , "extra" : True }},
222+ ],
223+ )
224+ def test_document_to_markdown_treats_malformed_style_mark_as_opaque (mark ):
225+ document = {
226+ "type" : "doc" ,
227+ "content" : [_paragraph_with (_text ("c" , [mark ]))],
228+ }
229+ markdown , unsupported = document_to_markdown (document )
230+ assert len (unsupported ) == 1
231+ assert markdown .startswith ("<!-- python-substack-node:v1 " )
232+
233+
234+ def test_color_and_highlight_round_trip_through_markdown ():
235+ markdown = (
236+ 'A [colorized]{style="color:#ff00ff"} and '
237+ '[highlighted]{style="background-color:#ffff00"} word'
238+ )
239+ post = Post ("T" , "" , user_id = 1 )
240+ post .from_markdown (markdown )
241+
242+ rendered , unsupported = document_to_markdown (post .draft_body )
243+
244+ assert unsupported == []
245+ assert markdown_to_doc (rendered ) == post .draft_body ["content" ]
246+
247+
164248def test_full_feature_fixture_round_trips_exactly ():
165249 fixture = Path (__file__ ).parent / "fixtures" / "full_features.md"
166250 post = Post ("Feature complete" , "" , user_id = 1 )
0 commit comments