diff --git a/CHANGELOG.md b/CHANGELOG.md index 4254756c..a79b4330 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ The format is based on Keep a Changelog, and this project adheres to Semantic Ve ### Changed +- Add default width classes to markdown tables with 2-5 cols - Updated column headers on NOFO index table - "Top" link on nofo_edit page is always visible - Appearing and disappearing was causing issues diff --git a/bloom_nofos/nofos/nofo.py b/bloom_nofos/nofos/nofo.py index 1f7c0301..d7905ed8 100644 --- a/bloom_nofos/nofos/nofo.py +++ b/bloom_nofos/nofos/nofo.py @@ -103,6 +103,30 @@ def _has_colspan_or_rowspan_not_one(tag): return super().convert_table(el, text, convert_as_inline) + def convert_th(self, el, text, convert_as_inline): + # automatically add width classes to table headers based on number of elements + def _determine_width_class_from_th_siblings(th_count=0): + # Determine the width class based on the number of elements in the first table row + width_class = "" + if th_count == 2: + width_class = "w-50" + elif th_count == 3: + width_class = "w-33" + elif th_count == 4: + width_class = "w-25" + elif th_count == 5: + width_class = "w-20" + + return width_class + + th_count = len(el.parent.find_all("th")) + # Add the class to the text if a class was determined + width_class = _determine_width_class_from_th_siblings(th_count) + if width_class: + text = f"{text.strip()} {{: .{width_class} }}" + + return super().convert_th(el, text, convert_as_inline) + # Create shorthand method for conversion def md(html, **options): diff --git a/bloom_nofos/nofos/test_nofo.py b/bloom_nofos/nofos/test_nofo.py index 2e8cebca..00f4f3db 100644 --- a/bloom_nofos/nofos/test_nofo.py +++ b/bloom_nofos/nofos/test_nofo.py @@ -149,6 +149,53 @@ def test_table_with_nested_html(self): self.assertEqual(md_body.strip(), pretty_html) +class TablesAndStuffInTablesConverterTHSest(TestCase): + def test_table_0_ths(self): + html = "
TD 1TD 2
Cell 1Cell 2
" + expected_markdown = "| TD 1 | TD 2 |\n| --- | --- |\n| Cell 1 | Cell 2 |" + md_body = md(html) + self.assertEqual(md_body.strip(), expected_markdown.strip()) + + def test_table_1_th(self): + html = "
TH 1
Cell 1
" + expected_markdown = "| TH 1 |\n| --- |\n| Cell 1 |" + md_body = md(html) + self.assertEqual(md_body.strip(), expected_markdown.strip()) + + def test_table_2_ths(self): + html = "
TH 1TH 2
Cell 1Cell 2
" + expected_markdown = ( + "| TH 1 {: .w-50 } | TH 2 {: .w-50 } |\n| --- | --- |\n| Cell 1 | Cell 2 |" + ) + md_body = md(html) + self.assertEqual(md_body.strip(), expected_markdown.strip()) + + def test_table_3_ths(self): + html = "
TH 1TH 2TH 3
Cell 1Cell 2Cell 3
" + expected_markdown = "| TH 1 {: .w-33 } | TH 2 {: .w-33 } | TH 3 {: .w-33 } |\n| --- | --- | --- |\n| Cell 1 | Cell 2 | Cell 3 |" + md_body = md(html) + self.assertEqual(md_body.strip(), expected_markdown.strip()) + + def test_table_4_ths(self): + html = "
TH 1TH 2TH 3TH 4
Cell 1Cell 2Cell 3Cell 4
" + expected_markdown = "| TH 1 {: .w-25 } | TH 2 {: .w-25 } | TH 3 {: .w-25 } | TH 4 {: .w-25 } |\n| --- | --- | --- | --- |\n| Cell 1 | Cell 2 | Cell 3 | Cell 4 |" + md_body = md(html) + self.assertEqual(md_body.strip(), expected_markdown.strip()) + + def test_table_5_ths(self): + html = "
TH 1TH 2TH 3TH 4TH 5
Cell 1Cell 2Cell 3Cell 4Cell 5
" + expected_markdown = "| TH 1 {: .w-20 } | TH 2 {: .w-20 } | TH 3 {: .w-20 } | TH 4 {: .w-20 } | TH 5 {: .w-20 } |\n| --- | --- | --- | --- | --- |\n| Cell 1 | Cell 2 | Cell 3 | Cell 4 | Cell 5 |" + md_body = md(html) + self.assertEqual(md_body.strip(), expected_markdown.strip()) + + def test_table_6_ths(self): + # no classnames on this one + html = "
TH 1TH 2TH 3TH 4TH 5TH 6
Cell 1Cell 2Cell 3Cell 4Cell 5Cell 6
" + expected_markdown = "| TH 1 | TH 2 | TH 3 | TH 4 | TH 5 | TH 6 |\n| --- | --- | --- | --- | --- | --- |\n| Cell 1 | Cell 2 | Cell 3 | Cell 4 | Cell 5 | Cell 6 |" + md_body = md(html) + self.assertEqual(md_body.strip(), expected_markdown.strip()) + + class TablesAndStuffInTablesConverterOLSTest(TestCase): maxDiff = None @@ -190,14 +237,6 @@ def test_ol_inside_td_start_not_one(self): md_body = md(html) self.assertEqual(md_body.strip(), pretty_html) - def test_ol_inside_td_start_not_one(self): - html = '
Header
  1. Item 1
  2. Item 2
' - pretty_html = ( - '| Header |\n| --- |\n|
  1. Item 1
  2. Item 2
|' - ) - md_body = md(html) - self.assertEqual(md_body.strip(), pretty_html) - def test_table_with_ol_strip_classes_nested_html(self): html = '

Demonstrates the ability to comply with all applicable privacy and security standards by developing a PII plan that outlines the following:

  • A process for ensuring compliance by all staff performing Navigator activities (as well as those who have access to sensitive information or PII related to your organization’s Navigator activities) with FFE privacy and security standards, especially when using computers, laptops, tablets, smartphones, and other electronic devices.

5 points

' pretty_html = """| Demonstrates the ability to comply with all applicable privacy and security standards by developing a PII plan that outlines the following: | |\n| --- | --- |\n| | 5 points |"""