Skip to content

Commit

Permalink
Switch from mkdocs to mdbook
Browse files Browse the repository at this point in the history
In 28c9263 I introduced automatic
linkification of option references in rule documentation,
which automatically converted the following:

    ## Options

    * `namespace-packages`

to:

    ## Options

    * [`namespace-packages`]

    [`namespace-packages`]: ../../settings#namespace-packages

While the above is a correct CommonMark[1] link definition,
what I was missing was that we used mkdocs for our documentation
generation, which as it turns out uses a non-CommonMark-compliant
Markdown parser, namely Python-Markdown[2], which contrary to CommonMark
doesn't support link definitions containing code tags.[3]
Mkdocs doesn't support CommonMark[4][5].

This commit therefore switches our documentation to use mdbook[6]
instead, which uses the pulldown-cmark[7] CommonMark implementation,
sparing us from having to deal with such parser idiosyncracies.

[1]: https://commonmark.org/
[2]: https://github.com/Python-Markdown/markdown/
[3]: Python-Markdown/markdown#280
[4]: mkdocs/mkdocs#361
[5]: mkdocs/mkdocs#1835
[6]: https://github.com/rust-lang/mdBook
[7]: https://github.com/raphlinus/pulldown-cmark
  • Loading branch information
not-my-profile committed Feb 13, 2023
1 parent 3a607b9 commit 8da870d
Show file tree
Hide file tree
Showing 12 changed files with 58 additions and 117 deletions.
14 changes: 7 additions & 7 deletions .github/workflows/docs.yaml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
name: mkdocs
name: mdbook

on:
release:
types: [published]
workflow_dispatch:

jobs:
mkdocs:
mdbook:
runs-on: ubuntu-latest
env:
CF_API_TOKEN_EXISTS: ${{ secrets.CF_API_TOKEN != '' }}
Expand All @@ -18,16 +18,16 @@ jobs:
- uses: Swatinem/rust-cache@v1
- name: "Install dependencies"
run: |
pip install -r docs/requirements.txt
- name: "Copy README File"
cargo install mdbook
- name: "Generate the website"
run: |
python scripts/transform_readme.py --target mkdocs
python scripts/generate_mkdocs.py
mkdocs build --strict
python scripts/generate_book.py
cd docs && mdbook build
- name: "Deploy to Cloudflare Pages"
if: ${{ env.CF_API_TOKEN_EXISTS == 'true' }}
uses: cloudflare/wrangler-action@2.0.0
with:
apiToken: ${{ secrets.CF_API_TOKEN }}
accountId: ${{ secrets.CF_ACCOUNT_ID }}
command: pages publish site --project-name=ruff-docs --branch ${GITHUB_HEAD_REF} --commit-hash ${GITHUB_SHA}
command: pages publish docs/book/ --project-name=ruff-docs --branch ${GITHUB_HEAD_REF} --commit-hash ${GITHUB_SHA}
4 changes: 0 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# Local cache
.ruff_cache
crates/ruff/resources/test/cpython
mkdocs.yml
.overrides

###
Expand Down Expand Up @@ -160,9 +159,6 @@ venv.bak/
# Rope project settings
.ropeproject

# mkdocs documentation
/site

# mypy
.mypy_cache/
.dmypy.json
Expand Down
14 changes: 7 additions & 7 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Welcome! We're happy to have you here. Thank you in advance for your contributio
- [Example: Adding a new lint rule](#example-adding-a-new-lint-rule)
- [Rule naming convention](#rule-naming-convention)
- [Example: Adding a new configuration option](#example-adding-a-new-configuration-option)
- [MkDocs](#mkdocs)
- [mdBook](#mdbook)
- [Release Process](#release-process)
- [Benchmarks](#benchmarks)

Expand Down Expand Up @@ -181,21 +181,21 @@ lives in `crates/ruff/src/flake8_to_ruff/converter.rs`.

Finally, regenerate the documentation and generated code with `cargo dev generate-all`.

## MkDocs
## mdBook

To preview any changes to the documentation locally:

1. Install MkDocs and Material for MkDocs with:
1. Install mdBook with:
```shell
pip install -r docs/requirements.txt
cargo install mdbook
```
2. Generate the MkDocs site with:
2. Generate the markdown files with:
```shell
python scripts/generate_mkdocs.py
python scripts/generate_book.py
```
3. Run the development server with:
```shell
mkdocs serve
cd docs && mdbook serve
```

The documentation should then be available locally at
Expand Down
4 changes: 2 additions & 2 deletions crates/ruff_dev/src/generate_docs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pub struct Args {
}

pub fn main(args: &Args) -> Result<()> {
let out_dir = Path::new("docs/rules");
let out_dir = Path::new("docs/src/rules");
if !args.dry_run {
fs::create_dir_all(out_dir)?;
}
Expand Down Expand Up @@ -74,7 +74,7 @@ fn process_documentation(documentation: &str, out: &mut String) {

let anchor = option.rsplit('.').next().unwrap();
out.push_str(&format!("* [`{option}`]\n"));
after.push_str(&format!("[`{option}`]: ../../settings#{anchor}"));
after.push_str(&format!("[`{option}`]: ../settings.html#{anchor}"));

continue;
}
Expand Down
5 changes: 2 additions & 3 deletions docs/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
*
!assets
!requirements.txt
book
src
10 changes: 10 additions & 0 deletions docs/SUMMARY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Summary

- [Overview](./index.md)
- [Installation And Usage](./installation-and-usage.md)
- [Configuration](./configuration.md)
- [Rules](./rules.md)
- [Settings](./settings.md)
- [Editor Integrations](./editor-integrations.md)
- [FAQ](./faq.md)
- [Contributing](./contributing.md)
13 changes: 13 additions & 0 deletions docs/book.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[book]
authors = ["The Ruff Developers"]
language = "en"
multilingual = false
src = "src"
title = "Ruff Documentation"

[output.html]
git-repository-url = "https://github.com/charliermarsh/ruff"

[output.html.fold]
enable = true
level = 0
3 changes: 0 additions & 3 deletions docs/requirements.txt

This file was deleted.

File renamed without changes
1 change: 1 addition & 0 deletions docs/theme/head.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<script src="https://cdn.usefathom.com/script.js" data-site="DUAEBFLB" defer></script>
53 changes: 0 additions & 53 deletions mkdocs.template.yml

This file was deleted.

54 changes: 16 additions & 38 deletions scripts/generate_mkdocs.py → scripts/generate_book.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
"""Generate an MkDocs-compatible `docs` and `mkdocs.yml` from the README.md."""
"""Generate the Markdown files for mdbook in `docs/src`."""
import argparse
import shutil
import subprocess
from pathlib import Path

import yaml

SECTIONS: list[tuple[str, str]] = [
("Overview", "index.md"),
("Installation and Usage", "installation-and-usage.md"),
Expand All @@ -20,14 +18,9 @@
"This README is also available as [documentation](https://beta.ruff.rs/docs/)."
)

FATHOM_SCRIPT: str = (
'<script src="https://cdn.usefathom.com/script.js" data-site="DUAEBFLB" defer>'
"</script>"
)


def main() -> None:
"""Generate an MkDocs-compatible `docs` and `mkdocs.yml`."""
"""Generate the Markdown files for mdbook in `docs/src`."""

subprocess.run(["cargo", "dev", "generate-docs"], check=True)

Expand All @@ -46,12 +39,24 @@ def main() -> None:
"rules/",
)

docs_path = Path("docs")
docs_path = Path("docs/src")
docs_path.mkdir(parents=True, exist_ok=True)

with (docs_path.parent / "SUMMARY.md").open("r") as f:
text = f.read()

rules_item = "- [Rules](./rules.md)\n"
assert rules_item in text
rule_items = (f" - [{f.stem}](rules/{f.name})\n" for f in sorted(docs_path.joinpath("rules").iterdir()))
text = text.replace(rules_item, rules_item + "".join(rule_items))

with (docs_path / "SUMMARY.md").open("w") as f:
f.write(text)

# Split the README.md into sections.
for title, filename in SECTIONS:
with docs_path.joinpath(filename).open("w+") as f:
f.write(f"# {title}\n")
block = content.split(f"<!-- Begin section: {title} -->")
if len(block) != 2:
msg = f"Section {title} not found in README.md"
Expand All @@ -67,37 +72,10 @@ def main() -> None:
# Copy the CONTRIBUTING.md.
shutil.copy("CONTRIBUTING.md", docs_path / "contributing.md")

# Add the nav section to mkdocs.yml.
with Path("mkdocs.template.yml").open(encoding="utf8") as fp:
config = yaml.safe_load(fp)
config["nav"] = [
{"Overview": "index.md"},
{"Installation and Usage": "installation-and-usage.md"},
{"Configuration": "configuration.md"},
{"Rules": "rules.md"},
{"Settings": "settings.md"},
{"Editor Integrations": "editor-integrations.md"},
{"FAQ": "faq.md"},
{"Contributing": "contributing.md"},
]
config["extra"] = {"analytics": {"provider": "fathom"}}

Path(".overrides/partials/integrations/analytics").mkdir(
parents=True,
exist_ok=True,
)
with Path(".overrides/partials/integrations/analytics/fathom.html").open(
"w+",
) as fp:
fp.write(FATHOM_SCRIPT)

with Path("mkdocs.yml").open("w+") as fp:
yaml.safe_dump(config, fp)


if __name__ == "__main__":
parser = argparse.ArgumentParser(
description="Generate an MkDocs-compatible `docs` and `mkdocs.yml`.",
description=__doc__,
)
args = parser.parse_args()
main()

0 comments on commit 8da870d

Please sign in to comment.