From f2b844f0a4b500f520d2ab3692005cab669b7802 Mon Sep 17 00:00:00 2001 From: Benjamin Bossan Date: Wed, 25 Jan 2023 12:54:20 +0100 Subject: [PATCH 1/4] Add support for line breaks --- skops/card/_markup.py | 4 ++++ skops/card/tests/examples/toy-example.md | 5 +++++ skops/card/tests/examples/toy-example.md.diff | 3 +++ 3 files changed, 12 insertions(+) diff --git a/skops/card/_markup.py b/skops/card/_markup.py index 7779a675..3e7f1cc2 100644 --- a/skops/card/_markup.py +++ b/skops/card/_markup.py @@ -46,6 +46,7 @@ def __init__(self): "RawInline": self._raw_inline, "RawBlock": self._raw_block, "SoftBreak": self._soft_break, + "LineBreak": self._line_break, "Para": self._para, "Header": self._header, "Image": self._image, @@ -124,6 +125,9 @@ def _soft_break(self, value) -> str: incr = 0 if not self._indent_trace else self._indent_trace[-1] return "\n" + self._get_indent(incr=incr) + def _line_break(self, value) -> str: + return "\n" + def _make_content(self, content): parts = [] for item in content: diff --git a/skops/card/tests/examples/toy-example.md b/skops/card/tests/examples/toy-example.md index 44669f11..a4762972 100644 --- a/skops/card/tests/examples/toy-example.md +++ b/skops/card/tests/examples/toy-example.md @@ -180,3 +180,8 @@ The "id" tag may change in order

Divs are possible

+ +## Line breaks + +A text with +a LineBreak item. diff --git a/skops/card/tests/examples/toy-example.md.diff b/skops/card/tests/examples/toy-example.md.diff index 9c00ed2a..b07b1ef6 100644 --- a/skops/card/tests/examples/toy-example.md.diff +++ b/skops/card/tests/examples/toy-example.md.diff @@ -88,3 +88,6 @@ - + +

Divs are possible

+@@ -186 +218 @@ +-A text with ++A text with From d92f7741b9e84c24fd77d661bf8a4ad4e1d1e26b Mon Sep 17 00:00:00 2001 From: Benjamin Bossan Date: Wed, 25 Jan 2023 14:22:26 +0100 Subject: [PATCH 2/4] Make parser work with older pandoc versions Tested and works with the following pandoc versions: - 2.0 - 2.2 - 2.5 - 2.19 - 3.0 Main change was with (afaict) pandoc 2.5, which changed handling of tables. Now there are two table implementations, old and new, which differ slightly. Minimum pandoc version has been decreased to 2.0. --- skops/card/_markup.py | 52 ++++++++++++++++++++++++++++++++++++------- skops/card/_parser.py | 2 +- 2 files changed, 45 insertions(+), 9 deletions(-) diff --git a/skops/card/_markup.py b/skops/card/_markup.py index 3e7f1cc2..233f42fe 100644 --- a/skops/card/_markup.py +++ b/skops/card/_markup.py @@ -189,7 +189,16 @@ def _code(item: tuple[Any, str]) -> str: _, txt = item return f"`{txt}`" - def _table_cols(self, items) -> list[str]: + def _table_cols_old(self, items) -> list[str]: # pragma: no cover + # pandoc < 2.5 + columns = [] + for (content,) in items: + column = self.__call__(content) + columns.append(column) + return columns + + def _table_cols_new(self, items) -> list[str]: + # pandoc >= 2.5 columns = [] fn = self.__call__ for item in items: @@ -198,7 +207,20 @@ def _table_cols(self, items) -> list[str]: columns.append(column) return columns - def _table_body(self, items) -> list[list[str]]: + def _table_body_old(self, items) -> list[list[str]]: # pragma: no cover + body = [] + for row_items in items: + row = [] + for col_row_item in row_items: + if not col_row_item: + content = "" + else: + content = col_row_item[0] + row.append(self.__call__(content)) + body.append(row) + return body + + def _table_body_new(self, items) -> list[list[str]]: body = [] fn = self.__call__ for _, row_items in items: @@ -209,20 +231,34 @@ def _table_body(self, items) -> list[list[str]]: body.append(row) return body - def _table(self, item) -> str: + def _table_old(self, item) -> tuple[list[str], list[list[str]]]: # pragma: no cover + # pandoc < 2.5 + _, _, _, thead, tbody = item + columns = self._table_cols_old(thead) + body = self._table_body_old(tbody) + return columns, body + + def _table_new(self, item) -> tuple[list[str], list[list[str]]]: + # pandoc >= 2.5 # attr capt specs thead tbody tfoot _, _, _, thead, tbody, _ = item - # header (_, thead_bodies) = thead (attr, thead_body) = thead_bodies[0] # multiple headers? - - columns = self._table_cols(thead_body) - + columns = self._table_cols_new(thead_body) # rows # attr rhc hd bd _, _, _, trows = tbody[0] # multiple groups of rows? - body = self._table_body(trows) + body = self._table_body_new(trows) + return columns, body + + def _table(self, item) -> str: + if len(item) == 6: + # pandoc >= 2.5 + columns, body = self._table_new(item) + else: # pragma: no cover + # pandoc < 2.5 + columns, body = self._table_old(item) table: Mapping[str, Sequence[Any]] if not body: diff --git a/skops/card/_parser.py b/skops/card/_parser.py index 86d4f120..06fbc29f 100644 --- a/skops/card/_parser.py +++ b/skops/card/_parser.py @@ -22,7 +22,7 @@ from ._markup import Markdown, PandocItem -PANDOC_MIN_VERSION = "2.9.0" +PANDOC_MIN_VERSION = "2.0" class PandocParser: From bdcbfe655819522a72149b5147554996bee4e341 Mon Sep 17 00:00:00 2001 From: Benjamin Bossan Date: Wed, 25 Jan 2023 14:37:13 +0100 Subject: [PATCH 3/4] Change CI to install pandoc with apt --- .github/workflows/build-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index 7920721e..513ce6d1 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -63,7 +63,7 @@ jobs: else pip install "scikit-learn~=${{ matrix.sklearn_version }}"; fi if [ ${{ matrix.os }} == "ubuntu-latest" ]; - then wget -q https://github.com/jgm/pandoc/releases/download/2.19.2/pandoc-2.19.2-1-amd64.deb && sudo dpkg -i pandoc-2.19.2-1-amd64.deb; + then sudo apt install pandoc && pandoc --version; fi python --version pip --version From 927ab0f82d054ce7a96cc29f5973be9ff5e48264 Mon Sep 17 00:00:00 2001 From: Benjamin Bossan Date: Wed, 25 Jan 2023 15:05:10 +0100 Subject: [PATCH 4/4] Fix line coverage report issue So the table change actually happens after 2.9, not 2.5 as I first expected. Therefore, given that we now install pandoc via apt on CI, which uses 2.9, the old table implementation is covered, not the new one. I thus moved around the pragmas to the new implementation. --- skops/card/_markup.py | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/skops/card/_markup.py b/skops/card/_markup.py index 233f42fe..32f94b36 100644 --- a/skops/card/_markup.py +++ b/skops/card/_markup.py @@ -189,16 +189,14 @@ def _code(item: tuple[Any, str]) -> str: _, txt = item return f"`{txt}`" - def _table_cols_old(self, items) -> list[str]: # pragma: no cover - # pandoc < 2.5 + def _table_cols_old(self, items) -> list[str]: columns = [] for (content,) in items: column = self.__call__(content) columns.append(column) return columns - def _table_cols_new(self, items) -> list[str]: - # pandoc >= 2.5 + def _table_cols_new(self, items) -> list[str]: # pragma: no cover columns = [] fn = self.__call__ for item in items: @@ -207,7 +205,7 @@ def _table_cols_new(self, items) -> list[str]: columns.append(column) return columns - def _table_body_old(self, items) -> list[list[str]]: # pragma: no cover + def _table_body_old(self, items) -> list[list[str]]: body = [] for row_items in items: row = [] @@ -220,7 +218,7 @@ def _table_body_old(self, items) -> list[list[str]]: # pragma: no cover body.append(row) return body - def _table_body_new(self, items) -> list[list[str]]: + def _table_body_new(self, items) -> list[list[str]]: # pragma: no cover body = [] fn = self.__call__ for _, row_items in items: @@ -231,15 +229,15 @@ def _table_body_new(self, items) -> list[list[str]]: body.append(row) return body - def _table_old(self, item) -> tuple[list[str], list[list[str]]]: # pragma: no cover - # pandoc < 2.5 + def _table_old(self, item) -> tuple[list[str], list[list[str]]]: + # pandoc < 2.10 _, _, _, thead, tbody = item columns = self._table_cols_old(thead) body = self._table_body_old(tbody) return columns, body - def _table_new(self, item) -> tuple[list[str], list[list[str]]]: - # pandoc >= 2.5 + def _table_new(self, item) -> tuple[list[str], list[list[str]]]: # pragma: no cover + # pandoc >= 2.10 # attr capt specs thead tbody tfoot _, _, _, thead, tbody, _ = item # header @@ -253,10 +251,10 @@ def _table_new(self, item) -> tuple[list[str], list[list[str]]]: return columns, body def _table(self, item) -> str: - if len(item) == 6: + if len(item) == 6: # pragma: no cover # pandoc >= 2.5 columns, body = self._table_new(item) - else: # pragma: no cover + else: # pandoc < 2.5 columns, body = self._table_old(item)