@@ -32,9 +32,9 @@ def description(self) -> str:
3232 def order (self ) -> int :
3333 value = self .metadata .get ("order" , 9999 )
3434 try :
35- return int (value )
35+ return float (value )
3636 except (TypeError , ValueError ):
37- return 9999
37+ return 9999.0
3838
3939
4040def load_markdown_document (path , * , url_path = None , slug = None , path_parts = None ) -> ContentDocument :
@@ -107,6 +107,10 @@ def render_markdown(markdown_text: str) -> str:
107107 f"<pre><code{ class_attr } >{ html .escape (chr (10 ).join (code_lines ))} </code></pre>"
108108 )
109109 continue
110+ if _is_table_start (lines , index ):
111+ table_html , index = _render_table (lines , index )
112+ blocks .append (table_html )
113+ continue
110114 if stripped .startswith ("#" ):
111115 level = min (len (stripped ) - len (stripped .lstrip ("#" )), 6 )
112116 heading = stripped [level :].strip ()
@@ -187,9 +191,53 @@ def _parse_frontmatter_value(raw_value: str):
187191 return int (raw_value )
188192 except ValueError :
189193 pass
194+ try :
195+ return float (raw_value )
196+ except ValueError :
197+ pass
190198 return raw_value
191199
192200
201+ def _is_table_start (lines : list [str ], index : int ) -> bool :
202+ if index + 1 >= len (lines ):
203+ return False
204+ header = lines [index ].strip ()
205+ separator = lines [index + 1 ].strip ()
206+ if "|" not in header or "|" not in separator :
207+ return False
208+ separator_cells = [cell .strip () for cell in separator .strip ("|" ).split ("|" )]
209+ if not separator_cells or any (not cell for cell in separator_cells ):
210+ return False
211+ return all (re .fullmatch (r":?-{3,}:?" , cell ) for cell in separator_cells )
212+
213+
214+ def _render_table (lines : list [str ], index : int ) -> tuple [str , int ]:
215+ header_cells = _split_table_row (lines [index ])
216+ index += 2 # header + separator
217+ body_rows = []
218+ while index < len (lines ):
219+ current = lines [index ].strip ()
220+ if not current or "|" not in current :
221+ break
222+ body_rows .append (_split_table_row (lines [index ]))
223+ index += 1
224+
225+ header_html = "" .join (f"<th>{ _render_inline (cell )} </th>" for cell in header_cells )
226+ body_html = "" .join (
227+ "<tr>" + "" .join (f"<td>{ _render_inline (cell )} </td>" for cell in row ) + "</tr>"
228+ for row in body_rows
229+ )
230+ table = f"<table><thead><tr>{ header_html } </tr></thead>"
231+ if body_rows :
232+ table += f"<tbody>{ body_html } </tbody>"
233+ table += "</table>"
234+ return table , index
235+
236+
237+ def _split_table_row (line : str ) -> list [str ]:
238+ return [cell .strip () for cell in line .strip ().strip ("|" ).split ("|" )]
239+
240+
193241def _extract_excerpt (markdown_text : str ) -> str :
194242 for paragraph in markdown_text .split ("\n \n " ):
195243 cleaned = paragraph .strip ()
0 commit comments