Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .codespellrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[codespell]
# 'sav' is the SPSS file extension, used by read_spss()
ignore-words-list = sav
skip = ./.git,./.venv,./site,./uv.lock,./.ruff_cache,./.pytest_cache,./*.egg-info,./src/*.egg-info,./tests/fixtures/encoding,*.xlsx,*.feather,*.parquet,*.orc,*.dta,*.xpt,*.h5
27 changes: 27 additions & 0 deletions .github/workflows/documentation.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: Deploy documentation

on:
push:
branches: [master]
workflow_dispatch:

permissions:
contents: write

jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
# git-authors and git-revision-date-localized need the full history
fetch-depth: 0

- name: Install uv
uses: astral-sh/setup-uv@v5

- name: Deploy to GitHub Pages
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
uv run mkdocs gh-deploy --force
11 changes: 6 additions & 5 deletions .github/workflows/workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ jobs:
run:
runs-on: ${{ matrix.os }}
strategy:
matrix:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
steps:
- uses: actions/checkout@master
- uses: actions/checkout@v4

- name: Install uv and set the python version
uses: astral-sh/setup-uv@v5
Expand All @@ -19,11 +19,12 @@ jobs:
run: |
uv run pytest --cov=mkdocs_table_reader_plugin --cov-report=xml

# Upload once per run, from a single matrix job
- name: Upload coverage to Codecov
if: contains(env.USING_COVERAGE, matrix.python-version) && github.ref == 'refs/heads/master'
uses: codecov/codecov-action@v4
if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.13' && github.ref == 'refs/heads/master'
uses: codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN }}
file: ./coverage.xml
files: ./coverage.xml
flags: unittests
fail_ci_if_error: true
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Changelog

Releases before 4.0.1 are described in the [GitHub releases](https://github.com/timvink/mkdocs-table-reader-plugin/releases).

## 4.0.1

Bug fixes:

- Two reader tags on the same line are now two tables. The tag pattern matched greedily, so it swallowed everything between the first and the last tag on a line, and then failed to parse the result.
- An `=` inside an argument value no longer breaks parsing. `{{ read_csv('a=b.csv') }}`, `sep='='` and `na_values=['a=1']` all raised a `SyntaxError` before.
- A comma inside a dict argument no longer breaks parsing, so `dtype={'a': 'str', 'b': 'int'}` works. Lists and tuples already worked.
- `convert_to_md_table()` no longer escapes pipe characters in the DataFrame you pass in. When a `mkdocs-macros-plugin` user rendered the same DataFrame twice, the second table showed doubly escaped pipes.

Project maintenance:

- The documentation site now deploys on every push to `master`. It was deployed by hand, and had fallen behind the readers added in 4.0.0.
- Coverage is uploaded to Codecov again. The upload step tested an environment variable that was never set, so it never ran.
- `enabled` is included in `schema.json`, so editors stop flagging it as an unknown option.
51 changes: 30 additions & 21 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,46 +7,55 @@ Thanks for considering to contribute to this project! Some guidelines:
- This package tries to be as simple as possible for the user (hide any complexity from the user). Options are only added when there is clear value to the majority of users.
- When issues or pull requests are not going to be resolved or merged, they should be closed as soon as possible. This is kinder than deciding this after a long period. Our issue tracker should reflect work to be done.

## Testing
## Development setup

Make sure to install an editable version before running tests:
This project uses [uv](https://docs.astral.sh/uv/). Install the project and its development dependencies with:

```python
pip install -r tests/test_requirements.txt
pip install -e .
pytest --cov=mkdocs_table_reader_plugin --cov-report term-missing tests
```bash
uv sync
```

If it makes sense, writing tests for your PRs is always appreciated and will help get them merged.
## Testing

Run the unit tests and the linter with:

```bash
make test
```

In addition, this project uses pyflakes for static code checking:
Or separately:

```python
pip install pyflakes
pyflakes tests/ mkdocs_table_reader_plugin/
```bash
uv run pytest --cov=mkdocs_table_reader_plugin --cov-report term-missing tests
uv run ruff check src/ tests/
```

#### Code Style
If it makes sense, writing tests for your PRs is always appreciated and will help get them merged.

### Code Style

Make sure your code *roughly* follows [PEP-8](https://www.python.org/dev/peps/pep-0008/) and keeps things consistent with the rest of the code.
Make sure your code *roughly* follows [PEP-8](https://www.python.org/dev/peps/pep-0008/) and keeps things consistent with the rest of the code. `ruff` is configured in `pyproject.toml` and fixes what it can automatically.

We use google-style docstrings.

## Documentation

They need to be deployed manually:
Preview the documentation site locally with:

```bash
mkdocs gh-deploy --force
make serve_docs
```

Every push to `master` deploys the site to GitHub Pages through the `documentation.yml` workflow. You can also deploy by hand with `make deploy_docs`.

## Release

Update `setup.py`.
1. Update `__version__` in `src/mkdocs_table_reader_plugin/__init__.py` and add an entry to `CHANGELOG.md`.
2. Commit, then tag and push:

```bash
git tag <version>
git push origin <version>
```
```bash
git tag v<version>
git push origin master --tags
```

Then manually create a github release to trigger publishing to pypi.
3. Create a GitHub release for the tag. That triggers the `pythonpublish.yml` workflow, which runs the tests and publishes to PyPI.
12 changes: 7 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@

setup:
pip install -r tests/test_requirements.txt
pip install -e .
uv sync

test:
pyflakes tests/ mkdocs_table_reader_plugin/
pytest --cov=mkdocs_table_reader_plugin --cov-report term-missing tests
uv run ruff check src/ tests/
uv run pytest --cov=mkdocs_table_reader_plugin --cov-report term-missing tests

serve_docs:
uv run mkdocs serve

deploy_docs:
mkdocs gh-deploy --force
uv run mkdocs gh-deploy --force
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ In your markdown files you can now use:
Where the path is relative to the location of your project's `mkdocs.yml` file, _or_ your project's `docs/` directory, _or_ the location of your markdown source file (all 3 possible locations will be searched, in that order).

- There are [readers](https://timvink.github.io/mkdocs-table-reader-plugin/readers/) available for many common table formats, like `.csv`, `.fwf`, `.json`, `.xls`, `.xlsx`, `.yaml`, `.feather`, `.tsv`, `.parquet`, `.orc`, `.html` and `.xml`, as well as HDF5, SPSS, SAS and Stata files. There is also the `read_raw()` reader that will allow you to insert tables (or other content) already in markdown format.
- `table-reader` is compatible with [`mkdocs-macros-plugin`](https://mkdocs-macros-plugin.readthedocs.io/en/latest/). This enables further automation like filtering tables or inserting directories of tables. See the documentation on [compatibility with macros plugin](howto/use_jinja2.md) for more examples.
- `table-reader` is compatible with [`mkdocs-macros-plugin`](https://mkdocs-macros-plugin.readthedocs.io/en/latest/). This enables further automation like filtering tables or inserting directories of tables. See the documentation on [compatibility with macros plugin](https://timvink.github.io/mkdocs-table-reader-plugin/howto/use_jinja2/) for more examples.

## Documentation and how-to guides

Expand Down
6 changes: 6 additions & 0 deletions docs/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@
"markdownDescription": "https://timvink.github.io/mkdocs-table-reader-plugin/options/",
"type": "object",
"properties": {
"enabled": {
"title": "Enables you to deactivate this plugin.",
"markdownDescription": "https://timvink.github.io/mkdocs-table-reader-plugin/options/#enabled",
"type": "boolean",
"default": true
},
"data_path": {
"title": "Additional path to search",
"markdownDescription": "https://timvink.github.io/mkdocs-table-reader-plugin/options/#data_path",
Expand Down
7 changes: 2 additions & 5 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,8 @@ lint.ignore = ['D104'
,'E722'
,'D104'
,'E402'
,"UP038" # UP038 Use `X | Y` in `isinstance` call instead of `(X, Y)`
]

# Exclude files in tests dir
lint.exclude = [
".bzr",
".direnv",
Expand Down Expand Up @@ -112,10 +110,9 @@ target-version = "py310"
# Always autofix
fix = true

[tool.uv]
dev-dependencies = [
[dependency-groups]
dev = [
"click>=8.1.8",
"codecov>=2.1.13",
# used by pd.read_html() and pd.read_xml()
"lxml>=5",
"mkdocs-git-authors-plugin>=0.9.4",
Expand Down
2 changes: 1 addition & 1 deletion src/mkdocs_table_reader_plugin/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "4.0.0"
__version__ = "4.0.1"
3 changes: 2 additions & 1 deletion src/mkdocs_table_reader_plugin/markdown.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,9 @@ def escape(value):
value = replace_newlines(value)
return value

df.columns = [escape(c) for c in df.columns]
# Escape a copy, so that a DataFrame passed in by a macros user is left alone
df = df.map(escape)
df.columns = [escape(c) for c in df.columns]

return df.to_markdown(**markdown_kwargs)

Expand Down
6 changes: 3 additions & 3 deletions src/mkdocs_table_reader_plugin/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,17 +48,17 @@ def on_config(self, config, **kwargs):
mkdocs_config=config, plugin_config=self.config
)
for reader in self.config.get("select_readers")
if reader in self.config.get("select_readers", [])
}

# Regex pattern for tags like {{ read_csv(..) }}, for all selected readers at once,
# so that every page is scanned only once, no matter how many readers are selected.
# match group 1: to extract any leading whitespace
# match group 2: to extract the reader
# match group 3: to extract the arguments (positional and keywords)
# match group 3: to extract the arguments (positional and keywords). Matched
# lazily, so that two tags on the same line are two matches instead of one.
# Note that a reader never matches when none are selected
self.tag_pattern = re.compile(
r"( *)\{\{\s+(%s)\((.+)\)\s+\}\}" % "|".join(self.readers or ["(?!)"]), # noqa: UP031
r"( *)\{\{\s+(%s)\((.+?)\)\s+\}\}" % "|".join(self.readers or ["(?!)"]), # noqa: UP031
flags=re.IGNORECASE,
)

Expand Down
Loading
Loading