sphinx-tabular 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (26) hide show
  1. sphinx_tabular-0.1.0/PKG-INFO +127 -0
  2. sphinx_tabular-0.1.0/README.md +91 -0
  3. sphinx_tabular-0.1.0/pyproject.toml +69 -0
  4. sphinx_tabular-0.1.0/setup.cfg +4 -0
  5. sphinx_tabular-0.1.0/src/sphinx_tabular/__init__.py +42 -0
  6. sphinx_tabular-0.1.0/src/sphinx_tabular/directive.py +148 -0
  7. sphinx_tabular-0.1.0/src/sphinx_tabular/formulas.py +1572 -0
  8. sphinx_tabular-0.1.0/src/sphinx_tabular/html.py +36 -0
  9. sphinx_tabular-0.1.0/src/sphinx_tabular/markup.py +107 -0
  10. sphinx_tabular-0.1.0/src/sphinx_tabular/model.py +40 -0
  11. sphinx_tabular-0.1.0/src/sphinx_tabular/normalize.py +76 -0
  12. sphinx_tabular-0.1.0/src/sphinx_tabular/parser.py +104 -0
  13. sphinx_tabular-0.1.0/src/sphinx_tabular/render_nodes.py +159 -0
  14. sphinx_tabular-0.1.0/src/sphinx_tabular/static/sphinx-tabular.css +454 -0
  15. sphinx_tabular-0.1.0/src/sphinx_tabular/static/sphinx-tabular.js +79 -0
  16. sphinx_tabular-0.1.0/src/sphinx_tabular.egg-info/PKG-INFO +127 -0
  17. sphinx_tabular-0.1.0/src/sphinx_tabular.egg-info/SOURCES.txt +24 -0
  18. sphinx_tabular-0.1.0/src/sphinx_tabular.egg-info/dependency_links.txt +1 -0
  19. sphinx_tabular-0.1.0/src/sphinx_tabular.egg-info/requires.txt +15 -0
  20. sphinx_tabular-0.1.0/src/sphinx_tabular.egg-info/top_level.txt +1 -0
  21. sphinx_tabular-0.1.0/tests/test_bad_input_validation.py +89 -0
  22. sphinx_tabular-0.1.0/tests/test_basic_build.py +99 -0
  23. sphinx_tabular-0.1.0/tests/test_external_file.py +28 -0
  24. sphinx_tabular-0.1.0/tests/test_formulas.py +1348 -0
  25. sphinx_tabular-0.1.0/tests/test_normalize.py +78 -0
  26. sphinx_tabular-0.1.0/tests/test_parser.py +57 -0
@@ -0,0 +1,127 @@
1
+ Metadata-Version: 2.4
2
+ Name: sphinx-tabular
3
+ Version: 0.1.0
4
+ Summary: Sphinx directives for CSV-powered tabular authoring.
5
+ Author: Your Name
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/deepthinker2001/sphinx-tabular
8
+ Project-URL: Documentation, https://deepthinker2001.github.io/sphinx-tabular/
9
+ Project-URL: Repository, https://github.com/deepthinker2001/sphinx-tabular
10
+ Project-URL: Issues, https://github.com/deepthinker2001/sphinx-tabular/issues
11
+ Keywords: sphinx,documentation,csv,tables,restructuredtext,myst
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Framework :: Sphinx
14
+ Classifier: Framework :: Sphinx :: Extension
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: Topic :: Documentation
17
+ Classifier: Topic :: Documentation :: Sphinx
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Programming Language :: Python :: 3.14
23
+ Requires-Python: >=3.12
24
+ Description-Content-Type: text/markdown
25
+ Requires-Dist: sphinx>=9.1
26
+ Requires-Dist: docutils>=0.20
27
+ Requires-Dist: myst-parser>=5
28
+ Provides-Extra: dev
29
+ Requires-Dist: pytest; extra == "dev"
30
+ Requires-Dist: build; extra == "dev"
31
+ Requires-Dist: twine; extra == "dev"
32
+ Provides-Extra: docs
33
+ Requires-Dist: sphinx>=9.1; python_version >= "3.12" and extra == "docs"
34
+ Requires-Dist: sphinx-book-theme; extra == "docs"
35
+ Requires-Dist: sphinx-design>=0.7.0; extra == "docs"
36
+
37
+ # sphinx-tabular
38
+
39
+ ## Features
40
+
41
+ - Sphinx extension.
42
+ - Uses standard CSV file format.
43
+ - Easily merge table cells with `<` and `^`.
44
+ - Support reStructuredText and Markdown.
45
+ - Support for inline table data and external files.
46
+ - Optional sticky header support for one or more header rows.
47
+ - Provides a minimal set of spreadsheet formulas.
48
+ - Set table cell alignment and per-cell alignment in both horizontal and vertical directions.
49
+ - Set custom cell text and background colors.
50
+ - Custom status pill.
51
+ - Support for Font Awesome and Bootstrip icons if installed by your theme.
52
+
53
+
54
+
55
+ # Installation
56
+
57
+ `pip install sphinx-tabular`
58
+
59
+
60
+ # conf.py
61
+
62
+ ```bash
63
+ extensions = [
64
+ ...,
65
+ 'sphinx_tabular',
66
+ ...,
67
+ ]
68
+ ```
69
+
70
+ ## Directives
71
+
72
+ RST, external file:
73
+
74
+ ```RST
75
+ .. rcsv-table:: Title
76
+ :file: table.rcsv
77
+ ```
78
+
79
+ RST, inline data.
80
+
81
+ ```RST
82
+ .. rcsv-table:: Title
83
+
84
+ Col 1, Row 1
85
+ Col 2, Row 2
86
+ ```
87
+
88
+ MD, external file:
89
+
90
+ ```RST
91
+ .. rcsv-table:: Title
92
+ :file: table.rcsv
93
+ ```
94
+
95
+ MD, inline data.
96
+
97
+ ```RST
98
+ .. rcsv-table:: Title
99
+
100
+ Col 1, Row 1
101
+ Col 2, Row 2
102
+ ```
103
+
104
+
105
+ ## Merging Cells
106
+
107
+ Columns
108
+
109
+ ```RST
110
+ .. rcsv-table:: Title
111
+
112
+ Merged,<
113
+ Unmerged, Unmerged
114
+ ```
115
+
116
+ Rows
117
+
118
+ ```RST
119
+ .. rcsv-table:: Title
120
+
121
+ Merged,Unmerged
122
+ ^, Unmerged
123
+ ```
124
+
125
+
126
+
127
+
@@ -0,0 +1,91 @@
1
+ # sphinx-tabular
2
+
3
+ ## Features
4
+
5
+ - Sphinx extension.
6
+ - Uses standard CSV file format.
7
+ - Easily merge table cells with `<` and `^`.
8
+ - Support reStructuredText and Markdown.
9
+ - Support for inline table data and external files.
10
+ - Optional sticky header support for one or more header rows.
11
+ - Provides a minimal set of spreadsheet formulas.
12
+ - Set table cell alignment and per-cell alignment in both horizontal and vertical directions.
13
+ - Set custom cell text and background colors.
14
+ - Custom status pill.
15
+ - Support for Font Awesome and Bootstrip icons if installed by your theme.
16
+
17
+
18
+
19
+ # Installation
20
+
21
+ `pip install sphinx-tabular`
22
+
23
+
24
+ # conf.py
25
+
26
+ ```bash
27
+ extensions = [
28
+ ...,
29
+ 'sphinx_tabular',
30
+ ...,
31
+ ]
32
+ ```
33
+
34
+ ## Directives
35
+
36
+ RST, external file:
37
+
38
+ ```RST
39
+ .. rcsv-table:: Title
40
+ :file: table.rcsv
41
+ ```
42
+
43
+ RST, inline data.
44
+
45
+ ```RST
46
+ .. rcsv-table:: Title
47
+
48
+ Col 1, Row 1
49
+ Col 2, Row 2
50
+ ```
51
+
52
+ MD, external file:
53
+
54
+ ```RST
55
+ .. rcsv-table:: Title
56
+ :file: table.rcsv
57
+ ```
58
+
59
+ MD, inline data.
60
+
61
+ ```RST
62
+ .. rcsv-table:: Title
63
+
64
+ Col 1, Row 1
65
+ Col 2, Row 2
66
+ ```
67
+
68
+
69
+ ## Merging Cells
70
+
71
+ Columns
72
+
73
+ ```RST
74
+ .. rcsv-table:: Title
75
+
76
+ Merged,<
77
+ Unmerged, Unmerged
78
+ ```
79
+
80
+ Rows
81
+
82
+ ```RST
83
+ .. rcsv-table:: Title
84
+
85
+ Merged,Unmerged
86
+ ^, Unmerged
87
+ ```
88
+
89
+
90
+
91
+
@@ -0,0 +1,69 @@
1
+ [build-system]
2
+ requires = ["setuptools>=69", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "sphinx-tabular"
7
+ version = "0.1.0"
8
+ description = "Sphinx directives for CSV-powered tabular authoring."
9
+ readme = "README.md"
10
+ requires-python = ">=3.12"
11
+ license = "MIT"
12
+ authors = [
13
+ { name = "Your Name" }
14
+ ]
15
+ keywords = [
16
+ "sphinx",
17
+ "documentation",
18
+ "csv",
19
+ "tables",
20
+ "restructuredtext",
21
+ "myst",
22
+ ]
23
+ classifiers = [
24
+ "Development Status :: 3 - Alpha",
25
+ "Framework :: Sphinx",
26
+ "Framework :: Sphinx :: Extension",
27
+ "Intended Audience :: Developers",
28
+ "Topic :: Documentation",
29
+ "Topic :: Documentation :: Sphinx",
30
+ "Programming Language :: Python :: 3",
31
+ "Programming Language :: Python :: 3.11",
32
+ "Programming Language :: Python :: 3.12",
33
+ "Programming Language :: Python :: 3.13",
34
+ "Programming Language :: Python :: 3.14",
35
+ ]
36
+
37
+ dependencies = [
38
+ "sphinx>=9.1",
39
+ "docutils>=0.20",
40
+ "myst-parser>=5",
41
+ ]
42
+
43
+ [project.optional-dependencies]
44
+ dev = [
45
+ "pytest",
46
+ "build",
47
+ "twine",
48
+ ]
49
+
50
+ docs = [
51
+ "sphinx>=9.1; python_version >= '3.12'",
52
+ "sphinx-book-theme",
53
+ "sphinx-design>=0.7.0",
54
+ ]
55
+
56
+ [project.urls]
57
+ Homepage = "https://github.com/deepthinker2001/sphinx-tabular"
58
+ Documentation = "https://deepthinker2001.github.io/sphinx-tabular/"
59
+ Repository = "https://github.com/deepthinker2001/sphinx-tabular"
60
+ Issues = "https://github.com/deepthinker2001/sphinx-tabular/issues"
61
+
62
+ [tool.setuptools.packages.find]
63
+ where = ["src"]
64
+
65
+ [tool.setuptools.package-data]
66
+ sphinx_tabular = ["static/*.css", "static/*.js"]
67
+
68
+ [tool.pytest.ini_options]
69
+ testpaths = ["tests"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,42 @@
1
+ from __future__ import annotations
2
+
3
+ from pathlib import Path
4
+
5
+ from .directive import McsvTableDirective, RcsvTableDirective
6
+
7
+ from docutils import nodes
8
+
9
+ from .html import depart_entry_html, visit_entry_html
10
+
11
+ def setup(app):
12
+ # Needed for .mcsv cell parsing.
13
+ app.setup_extension("myst_parser")
14
+
15
+ app.add_directive("rcsv-table", RcsvTableDirective)
16
+ app.add_directive("mcsv-table", McsvTableDirective)
17
+
18
+ app.add_node(
19
+ nodes.entry,
20
+ override=True,
21
+ html=(visit_entry_html, depart_entry_html),
22
+ )
23
+
24
+ app.add_config_value("sphinx_tabular_strict", False, "env")
25
+
26
+ app.connect("builder-inited", _copy_static_assets)
27
+ app.add_css_file("sphinx-tabular.css")
28
+ app.add_js_file("sphinx-tabular.js")
29
+
30
+ return {
31
+ "version": "0.1.0",
32
+ "parallel_read_safe": True,
33
+ "parallel_write_safe": True,
34
+ }
35
+
36
+
37
+
38
+
39
+ def _copy_static_assets(app):
40
+ static_src = Path(__file__).parent / "static"
41
+ if str(static_src) not in app.config.html_static_path:
42
+ app.config.html_static_path.append(str(static_src))
@@ -0,0 +1,148 @@
1
+ from __future__ import annotations
2
+
3
+ from pathlib import Path
4
+
5
+ from docutils.parsers.rst import directives
6
+ from sphinx.errors import ExtensionError
7
+ from sphinx.util.docutils import SphinxDirective
8
+
9
+ from .normalize import normalize_rows
10
+ from .parser import RcsvParseError, parse_csv_with_quote_tracking
11
+ from .render_nodes import build_table_node
12
+ from docutils import nodes
13
+ from sphinx.util import logging
14
+
15
+ logger = logging.getLogger(__name__)
16
+
17
+ class BaseTabularDirective(SphinxDirective):
18
+ has_content = True
19
+ required_arguments = 0
20
+ optional_arguments = 1
21
+ final_argument_whitespace = True
22
+
23
+ markup = "rst"
24
+ directive_name = "tabular-table"
25
+ dialect_class = "sphinx-tabular"
26
+
27
+ option_spec = {
28
+ "file": directives.unchanged_required,
29
+ "header-rows": directives.nonnegative_int,
30
+ "width": directives.unchanged,
31
+ "widths": directives.unchanged,
32
+ "class": directives.class_option,
33
+ "text-align": directives.unchanged,
34
+ "vertical-align": directives.unchanged,
35
+ "sticky-header": directives.flag,
36
+ "sticky-offset": directives.unchanged,
37
+ "strict": directives.flag,
38
+ }
39
+ def _is_strict(self) -> bool:
40
+ return bool(
41
+ "strict" in self.options
42
+ or getattr(self.config, "sphinx_tabular_strict", False)
43
+ )
44
+
45
+
46
+ def _warn_or_raise(self, message: str) -> list[nodes.Node]:
47
+ if self._is_strict():
48
+ raise ExtensionError(message)
49
+
50
+ source, line = self.get_source_info()
51
+
52
+ logger.warning(
53
+ "sphinx-tabular: %s",
54
+ message,
55
+ location=(source, line),
56
+ )
57
+
58
+ return []
59
+
60
+ def run(self):
61
+ caption = self.arguments[0] if self.arguments else None
62
+
63
+ has_file = "file" in self.options
64
+ has_inline_content = any(line.strip() for line in self.content)
65
+
66
+ strict = bool(
67
+ "strict" in self.options
68
+ or getattr(self.config, "sphinx_tabular_strict", False)
69
+ )
70
+
71
+ if has_file and has_inline_content:
72
+ return self._warn_or_raise(
73
+ f"{self.directive_name}: specify either :file: or inline content, not both"
74
+ )
75
+
76
+ if not has_file and not has_inline_content:
77
+ return self._warn_or_raise(
78
+ f"{self.directive_name}: specify either :file: or inline content"
79
+ )
80
+
81
+ if has_file:
82
+ rel_file = self.options["file"]
83
+
84
+ doc_dir = Path(self.env.doc2path(self.env.docname)).parent
85
+ source_path = (doc_dir / rel_file).resolve()
86
+
87
+ if not source_path.exists():
88
+ return self._warn_or_raise(
89
+ f"{self.directive_name}: file not found: {rel_file}"
90
+ )
91
+
92
+ self.env.note_dependency(str(source_path))
93
+ text = source_path.read_text(encoding="utf-8")
94
+ source = str(source_path)
95
+ else:
96
+ text = "\n".join(self.content)
97
+ source = self.env.doc2path(self.env.docname)
98
+
99
+
100
+ try:
101
+ raw_rows = parse_csv_with_quote_tracking(text)
102
+ rows = normalize_rows(
103
+ raw_rows,
104
+ source=source,
105
+ strict=strict,
106
+ directive_name=self.directive_name,
107
+ warning_docname=self.env.docname,
108
+ warning_line_offset=self.content_offset - 1,
109
+ )
110
+ except RcsvParseError as exc:
111
+ return self._warn_or_raise(f"{self.directive_name}: {exc}")
112
+ except ValueError as exc:
113
+ return self._warn_or_raise(f"{self.directive_name}: {exc}")
114
+
115
+ classes = [
116
+ "sphinx-tabular",
117
+ self.dialect_class,
118
+ ]
119
+ classes.extend(self.options.get("class", []))
120
+
121
+ if "sticky-header" in self.options:
122
+ classes.append("sphinx-tabular-sticky-header")
123
+
124
+ table = build_table_node(
125
+ rows,
126
+ directive=self,
127
+ source=source,
128
+ markup=self.markup,
129
+ caption=caption,
130
+ header_rows=self.options.get("header-rows", 0),
131
+ table_classes=classes,
132
+ table_width=self.options.get("width"),
133
+ sticky_offset=self.options.get("sticky-offset"),
134
+ )
135
+
136
+ return [table]
137
+
138
+
139
+ class RcsvTableDirective(BaseTabularDirective):
140
+ markup = "rst"
141
+ directive_name = "rcsv-table"
142
+ dialect_class = "sphinx-tabular-rcsv"
143
+
144
+
145
+ class McsvTableDirective(BaseTabularDirective):
146
+ markup = "myst"
147
+ directive_name = "mcsv-table"
148
+ dialect_class = "sphinx-tabular-mcsv"