@@ -324,19 +324,116 @@ def show_overview_table(
324324 print (df )
325325
326326
327+ def create_html_table (dest : Path ) -> None :
328+ from bokeh .io import output_file , save
329+ from bokeh .layouts import column
330+ from bokeh .models import (
331+ ColumnDataSource ,
332+ DataTable ,
333+ TableColumn ,
334+ Div ,
335+ StringFormatter ,
336+ NumberFormatter ,
337+ HTMLTemplateFormatter ,
338+ InlineStyleSheet ,
339+ )
340+
341+ dest .parent .mkdir (parents = True , exist_ok = True )
342+
343+ df = get_overview_df ()
344+
345+ df ["possible_discontinuities" ] = df ["possible_discontinuities" ].apply (
346+ lambda x : "✓" if x else ""
347+ )
348+
349+ def get_formatter (col : str ):
350+ """Get the appropriate formatter for the column."""
351+ if col not in df .columns :
352+ return HTMLTemplateFormatter (
353+ template = """
354+ <a href="https://github.com/Benchmarking-Initiative/Benchmark-Models-PEtab/tree/master/Benchmark-Models/<%= value %>"><%= value %></a>
355+ """
356+ )
357+ if pd .api .types .is_integer_dtype (df [col ].dtype ):
358+ return NumberFormatter (text_align = "right" )
359+ if col in ["reference_uris" , "sbml4humans_urls" ]:
360+ return HTMLTemplateFormatter (
361+ template = """
362+ <%
363+ if (Array.isArray(value)) {
364+ urls = value;
365+ } else {
366+ const sanitizedValue = value.replace(/'/g, '"');
367+ const urls = JSON.parse(sanitizedValue);
368+ console.log('Parsed JSON:', urls);
369+ }
370+ for (let i = 0; i < urls.length; i++) {
371+ %>
372+ <a href="<%= urls[i] %>" target="_blank"><%= urls[i] %></a>
373+ <% } %>
374+ """
375+ )
376+
377+ return StringFormatter ()
378+
379+ columns = [
380+ TableColumn (
381+ field = col ,
382+ title = markdown_columns .get (col , col ),
383+ formatter = get_formatter (col ),
384+ width = len (col ),
385+ )
386+ for col in df .reset_index ().columns
387+ ]
388+
389+ source = ColumnDataSource (df )
390+
391+ css = InlineStyleSheet (
392+ css = """
393+ .slick-header-column {
394+ background-color: #f4f4f4;
395+ font-weight: bold;
396+ }
397+ """
398+ )
399+
400+ data_table = DataTable (
401+ source = source ,
402+ columns = columns ,
403+ sortable = True ,
404+ sizing_mode = "stretch_both" ,
405+ )
406+ data_table .stylesheets .append (css )
407+
408+ heading = Div (text = "<h1>Benchmark Problems</h1>" )
409+
410+ layout = column (heading , data_table , sizing_mode = "stretch_both" )
411+ output_file (dest , title = "Benchmark Problems" )
412+ save (layout )
413+
414+
327415def main ():
328416 parser = argparse .ArgumentParser (
329417 description = "Show overview table for benchmark PEtab problems"
330418 )
331- parser .add_argument (
419+ group1 = parser .add_mutually_exclusive_group ()
420+ group1 .add_argument (
332421 "--markdown" , action = "store_true" , help = "Output in markdown format"
333422 )
334- parser .add_argument (
423+ group1 .add_argument (
335424 "--update" ,
336425 action = "store_true" ,
337426 help = "Update the README.md file with the overview table" ,
338427 )
339428
429+ group2 = parser .add_mutually_exclusive_group ()
430+ group2 .add_argument (
431+ "--html-file" , help = "Output the overview table to an HTML file"
432+ )
433+
340434 args = parser .parse_args ()
341435
342- show_overview_table (markdown = args .markdown , update_readme = args .update )
436+ if args .html_file :
437+ create_html_table (dest = Path (args .html_file ))
438+ else :
439+ show_overview_table (markdown = args .markdown , update_readme = args .update )
0 commit comments