33
44Tag base class, including rendering logic
55"""
6+
67from typing import Optional , TypeVar
78
89from . import __util as util
10+ from .__render_options import FullOptions , Options
911from .__types import AttributeType , ChildrenType
1012
11- SelfType = TypeVar (' SelfType' , bound = ' Tag' )
13+ SelfType = TypeVar (" SelfType" , bound = " Tag" )
1214
1315
1416class Tag :
1517 """
1618 Base tag class
1719 """
20+
1821 def __init__ (
1922 self ,
2023 * children : ChildrenType ,
@@ -23,26 +26,32 @@ def __init__(
2326 """
2427 Create a new tag instance
2528 """
26- self .children = util .flatten_list (list (children ))
29+ flattened , options = util .flatten_children (list (children ))
30+ self .children = flattened
2731 """Children of this tag"""
2832
2933 self .attributes = util .filter_attributes (attributes )
3034 """Attributes of this tag"""
3135
36+ self .options = options
37+ """Render options specified for this element"""
38+
3239 def __call__ (
3340 self : SelfType ,
3441 * children : ChildrenType ,
3542 ** attributes : AttributeType ,
36- ) -> ' SelfType' :
43+ ) -> " SelfType" :
3744 """
3845 Create a new tag instance derived from this tag. Its children and
3946 attributes are based on this original tag, but with additional children
4047 appended and additional attributes unioned.
4148 """
42- new_children = self .children + util .flatten_list (list (children ))
49+ flattened , options = util .flatten_children (list (children ))
50+ new_children = self .children + flattened
4351 new_attributes = util .dict_union (self .attributes , attributes )
52+ new_options = self .options .union (options )
4453
45- return self .__class__ (* new_children , ** new_attributes )
54+ return self .__class__ (* new_children , new_options , ** new_attributes )
4655
4756 def __iter__ (self ) -> None :
4857 """
@@ -59,7 +68,7 @@ def _get_tag_name(self) -> str:
5968 """
6069 Returns the name of the tag
6170 """
62- return type (self ).__name__ .removesuffix ('_' )
71+ return type (self ).__name__ .removesuffix ("_" )
6372
6473 def _get_default_attributes (
6574 self ,
@@ -94,18 +103,35 @@ def _escape_children(self) -> bool:
94103 """
95104 return True
96105
97- def _render (self , indent : int ) -> list [str ]:
106+ def _render (self , indent : str , options : FullOptions ) -> list [str ]:
98107 """
99108 Renders tag and its children to a list of strings where each string is
100- a single line of output
109+ a single line of output.
110+
111+ Parameters
112+ ----------
113+ indent : str
114+ string to use for indentation
115+ options : FullOptions
116+ rendering options
117+
118+ Returns
119+ -------
120+ list[str]
121+ list of lines of output
101122 """
102- attributes = util .filter_attributes (util .dict_union (
103- self ._get_default_attributes (self .attributes ),
104- self .attributes ,
105- ))
123+ # Determine what the options for this element are
124+ options = options .union (self .options )
125+
126+ attributes = util .filter_attributes (
127+ util .dict_union (
128+ self ._get_default_attributes (self .attributes ),
129+ self .attributes ,
130+ )
131+ )
106132
107133 # Tag and attributes
108- opening = f"{ ' ' * indent } <{ self ._get_tag_name ()} "
134+ opening = f"{ indent } <{ self ._get_tag_name ()} "
109135
110136 # Add pre-content
111137 if (pre := self ._get_tag_pre_content ()) is not None :
@@ -126,19 +152,20 @@ def _render(self, indent: int) -> list[str]:
126152 util .render_children (
127153 self .children ,
128154 self ._escape_children (),
129- indent + 2 ,
155+ indent + options .indent ,
156+ options ,
130157 )
131158 )
132159 # Closing tag
133- out .append (f"{ ' ' * indent } </{ self ._get_tag_name ()} >" )
160+ out .append (f"{ indent } </{ self ._get_tag_name ()} >" )
134161
135162 return out
136163
137164 def render (self ) -> str :
138165 """
139166 Render this tag and its contents to a string
140167 """
141- return ' \n ' .join (self ._render (0 ))
168+ return " \n " .join (self ._render ("" , Options . default () ))
142169
143170 def __str__ (self ) -> str :
144171 return self .render ()
@@ -151,32 +178,36 @@ class SelfClosingTag(Tag):
151178 """
152179 Self-closing tags don't contain child elements
153180 """
181+
154182 def __init__ (self , ** attributes : AttributeType ) -> None :
155183 # Self-closing tags don't allow children
156184 super ().__init__ (** attributes )
157185
158- def _render (self , indent : int ) -> list [str ]:
186+ def _render (self , indent : str , options : FullOptions ) -> list [str ]:
159187 """
160188 Renders tag and its children to a list of strings where each string is
161189 a single line of output
162190 """
163- attributes = util .filter_attributes (util .dict_union (
164- self ._get_default_attributes (self .attributes ),
165- self .attributes ,
166- ))
191+ attributes = util .filter_attributes (
192+ util .dict_union (
193+ self ._get_default_attributes (self .attributes ),
194+ self .attributes ,
195+ )
196+ )
167197 if len (attributes ):
168198 return [
169- f"{ ' ' * indent } <{ self ._get_tag_name ()} "
199+ f"{ indent } <{ self ._get_tag_name ()} "
170200 f"{ util .render_tag_attributes (attributes )} />"
171201 ]
172202 else :
173- return [f"{ ' ' * indent } <{ self ._get_tag_name ()} />" ]
203+ return [f"{ indent } <{ self ._get_tag_name ()} />" ]
174204
175205
176206class WhitespaceSensitiveTag (Tag ):
177207 """
178208 Whitespace-sensitive tags are tags where whitespace needs to be respected.
179209 """
210+
180211 def __init__ (
181212 self ,
182213 * children : ChildrenType ,
@@ -193,25 +224,30 @@ def __call__( # type: ignore
193224 attributes |= {}
194225 return super ().__call__ (* children , ** attributes )
195226
196- def _render (self , indent : int ) -> list [str ]:
197- attributes = util .filter_attributes (util .dict_union (
198- self ._get_default_attributes (self .attributes ),
199- self .attributes ,
200- ))
227+ def _render (self , indent : str , options : FullOptions ) -> list [str ]:
228+ attributes = util .filter_attributes (
229+ util .dict_union (
230+ self ._get_default_attributes (self .attributes ),
231+ self .attributes ,
232+ )
233+ )
201234
202235 # Tag and attributes
203- output = f"{ ' ' * indent } <{ self ._get_tag_name ()} "
236+ output = f"{ indent } <{ self ._get_tag_name ()} "
204237
205238 if len (attributes ):
206239 output += f" { util .render_tag_attributes (attributes )} >"
207240 else :
208241 output += ">"
209242
210- output += '\n ' .join (util .render_children (
211- self .children ,
212- self ._escape_children (),
213- 0 ,
214- ))
243+ output += "\n " .join (
244+ util .render_children (
245+ self .children ,
246+ self ._escape_children (),
247+ "" ,
248+ options ,
249+ )
250+ )
215251
216252 output += f"</{ self ._get_tag_name ()} >"
217253 return output .splitlines ()
0 commit comments