44from textual .app import App , ComposeResult
55from textual .content import Content
66from textual .reactive import reactive
7- from textual .widgets import Static , TextArea
7+ from textual .widgets import Footer , Pretty , Static , TextArea
88
99
1010class MarkupPlayground (App ):
1111
1212 TITLE = "Markup Playground"
1313 CSS = """
14- Screen {
15- & > * {
16- margin: 0 1;
17- height: 1fr;
18- }
14+ Screen {
1915 layout: vertical;
2016 #editor {
21- width: 2fr ;
17+ width: 1fr ;
2218 height: 1fr;
2319 border: tab $foreground 50%;
2420 padding: 1;
@@ -33,7 +29,7 @@ class MarkupPlayground(App):
3329 height: 1fr;
3430 border: tab $foreground 50%;
3531 padding: 1;
36- margin: 1 0 0 1;
32+ margin: 1 1 0 1;
3733 &:focus {
3834 border: tab $primary;
3935 }
@@ -48,28 +44,57 @@ class MarkupPlayground(App):
4844 }
4945 overflow-y: auto;
5046 }
51- #results {
52-
47+ #results {
5348 padding: 1 1;
49+ width: 1fr;
50+ }
51+ #spans-container {
52+ border: tab $success;
53+ overflow-y: auto;
54+ margin: 0 1;
55+ }
56+ #spans {
57+ padding: 1 1;
58+ width: 1fr;
59+ }
60+ HorizontalGroup {
61+ height: 1fr;
5462 }
5563 }
5664 """
5765 AUTO_FOCUS = "#editor"
5866
67+ BINDINGS = [
68+ ("f1" , "toggle('show_variables')" , "Variables" ),
69+ ("f2" , "toggle('show_spans')" , "Spans" ),
70+ ]
5971 variables : reactive [dict [str , object ]] = reactive ({})
6072
73+ show_variables = reactive (False )
74+ show_spans = reactive (False )
75+
6176 def compose (self ) -> ComposeResult :
6277 with containers .HorizontalGroup ():
6378 yield (editor := TextArea (id = "editor" ))
6479 yield (variables := TextArea ("" , id = "variables" , language = "json" ))
6580 editor .border_title = "Markup"
6681 variables .border_title = "Variables (JSON)"
6782
68- with containers .VerticalScroll (
69- id = "results-container" , can_focus = False
70- ) as container :
71- yield Static (id = "results" )
72- container .border_title = "Output"
83+ with containers .HorizontalGroup ():
84+ with containers .VerticalScroll (id = "results-container" ) as container :
85+ yield Static (id = "results" )
86+ container .border_title = "Output"
87+ with containers .VerticalScroll (id = "spans-container" ) as container :
88+ yield Pretty ([], id = "spans" )
89+ container .border_title = "Spans"
90+
91+ yield Footer ()
92+
93+ def watch_show_variables (self , show_variables : bool ) -> None :
94+ self .query_one ("#variables" ).display = show_variables
95+
96+ def watch_show_spans (self , show_spans : bool ) -> None :
97+ self .query_one ("#spans-container" ).display = show_spans
7398
7499 @on (TextArea .Changed , "#editor" )
75100 def on_markup_changed (self , event : TextArea .Changed ) -> None :
@@ -78,13 +103,16 @@ def on_markup_changed(self, event: TextArea.Changed) -> None:
78103 def update_markup (self ) -> None :
79104 results = self .query_one ("#results" , Static )
80105 editor = self .query_one ("#editor" , TextArea )
106+ spans = self .query_one ("#spans" , Pretty )
81107 try :
82108 content = Content .from_markup (editor .text , ** self .variables )
83109 results .update (content )
84- except Exception as error :
110+ spans .update (content .spans )
111+ except Exception :
85112 from rich .traceback import Traceback
86113
87114 results .update (Traceback ())
115+ spans .update ([])
88116
89117 self .query_one ("#results-container" ).add_class ("-error" ).scroll_end (
90118 animate = False
0 commit comments