Skip to content

Commit b84511a

Browse files
committed
docs: update lander; add to dev tool
1 parent 07e9a76 commit b84511a

File tree

3 files changed

+207
-41
lines changed

3 files changed

+207
-41
lines changed

new_docs/docs/index.md

Lines changed: 43 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,48 @@ pip install mplhep
1616

1717
Here's a quick example showing the primary functionality
1818

19+
=== "Default"
20+
21+
```python
22+
# mkdocs: render
23+
# The mkdocs commands are auto hidden # mkdocs: hide
24+
import matplotlib.pyplot as plt
25+
import mplhep as mh
26+
import numpy as np
27+
np.random.seed(42)
28+
# Set the plotting style
29+
mh.style.use() # Style reset to default
30+
31+
# Create a plot
32+
fig, ax = plt.subplots()
33+
# Plot a pre-binned histogram
34+
mh.histplot(*np.histogram(np.random.normal(0, 1, 1000)), ax=ax, label="Data")
35+
# Add appropriate labels
36+
txt_obj = mh.add_text("Default", loc='over left')
37+
mh.append_text("matplotlib style", txt_obj, loc='right')
38+
```
39+
40+
=== "PLOTHIST"
41+
42+
```python
43+
# mkdocs: render
44+
import matplotlib.pyplot as plt
45+
import mplhep as mh
46+
import numpy as np
47+
np.random.seed(42)
48+
# Set the plotting style
49+
mh.style.use("PLOTHIST")
50+
51+
# Create a plot
52+
fig, ax = plt.subplots()
53+
# Plot a pre-binned histogram
54+
mh.histplot(*np.histogram(np.random.normal(0, 1, 1000)), ax=ax, label="Data")
55+
# Add appropriate labels
56+
txt_obj = mh.add_text("PLOTHIST", loc='over left')
57+
mh.append_text("Demo", txt_obj, loc='right', fontsize='x-small')
58+
```
59+
60+
1961
=== "CMS"
2062

2163
```python
@@ -35,7 +77,6 @@ Here's a quick example showing the primary functionality
3577
# Add appropriate labels
3678
mh.cms.label("Preliminary", data=False, lumi=100, com=15) # ax can be implicit
3779
# mh.mpl_magic(soft_fail=True) # Autofit label - not needed
38-
print("This line will be hidden by the plugin") # mkdocs: hide
3980
```
4081

4182
=== "ATLAS"
@@ -75,7 +116,7 @@ Here's a quick example showing the primary functionality
75116
mh.histplot(*np.histogram(np.random.normal(0, 1, 1000)), ax=ax, label="Data")
76117
# Add appropriate labels
77118
mh.lhcb.label("Preliminary", data=False, lumi=100, com=15) # ax can be implicit
78-
# mh.mpl_magic(soft_fail=True) # Autofit label - needed but not applied
119+
mh.mpl_magic(soft_fail=True) # Autofit label
79120
```
80121

81122
=== "ALICE"
@@ -118,26 +159,6 @@ Here's a quick example showing the primary functionality
118159
# mh.mpl_magic(soft_fail=True) # Autofit label - not needed
119160
```
120161

121-
=== "PLOTHIST"
122-
123-
```python
124-
# mkdocs: render
125-
import matplotlib.pyplot as plt
126-
import mplhep as mh
127-
import numpy as np
128-
np.random.seed(42)
129-
# Set the plotting style
130-
mh.style.use("PLOTHIST")
131-
132-
# Create a plot
133-
fig, ax = plt.subplots()
134-
# Plot a pre-binned histogram
135-
mh.histplot(*np.histogram(np.random.normal(0, 1, 1000)), ax=ax, label="Data")
136-
# Add appropriate labels
137-
txt_obj = mh.add_text("PLOTHIST", loc='over left')
138-
mh.append_text("Demo", txt_obj, loc='right', fontsize='x-small')
139-
```
140-
141162
This creates a simple histogram with HEP-style formatting. Check out the [User Guide](guide.md) and the [Gallery](gallery.md) below for more advanced examples!
142163

143164

new_docs/requirements.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
docstring-inheritance
2+
griffe-inherited-docstrings
3+
markdown-exec

src/mplhep/_dev.py

Lines changed: 161 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,28 @@ def cmd_baseline(self) -> bool:
282282

283283
return success
284284

285-
def cmd_clean(self) -> bool:
285+
def cmd_precommit(self, extra_args: Optional[List[str]] = None) -> bool:
286+
"""Run pre-commit hooks on all files."""
287+
self._print_header("Running Pre-commit Hooks")
288+
289+
# Check if pre-commit is available
290+
if not self._check_tool_available("pre-commit", ["pre-commit", "--version"]):
291+
return False
292+
293+
cmd = ["pre-commit", "run", "--all-files"]
294+
295+
# Add any extra arguments
296+
if extra_args:
297+
cmd.extend(extra_args)
298+
299+
success = self._run_command_with_confirmation(cmd)
300+
301+
if success:
302+
self._print_success("Pre-commit hooks completed successfully!")
303+
else:
304+
self._print_error("Pre-commit hooks failed!")
305+
306+
return success
286307
"""Clean up test artifacts and cache files."""
287308
self._print_header("Cleaning Test Artifacts")
288309

@@ -324,35 +345,112 @@ def cmd_clean(self) -> bool:
324345

325346
return True
326347

327-
def cmd_precommit(self, extra_args: Optional[List[str]] = None) -> bool:
328-
"""Run pre-commit hooks on all files."""
329-
# Check if pre-commit is available
330-
if not self._check_tool_available("pre-commit", ["pre-commit", "--version"]):
348+
def cmd_docs(
349+
self,
350+
action: str = "build",
351+
port: int = 8000,
352+
clean: bool = True,
353+
extra_args: Optional[List[str]] = None,
354+
) -> bool:
355+
"""Build or serve documentation."""
356+
# Check if mkdocs is available
357+
if not self._check_tool_available("mkdocs", ["mkdocs", "--version"]):
331358
return False
332359

333-
# Check if .pre-commit-config.yaml exists
334-
precommit_config = self.project_root / ".pre-commit-config.yaml"
335-
if not precommit_config.exists():
336-
self._print_warning("No .pre-commit-config.yaml found")
337-
self._print_warning(
338-
"Run 'pre-commit install' to set up hooks for this repository"
339-
)
360+
# Check if new_docs directory exists
361+
docs_dir = self.project_root / "new_docs"
362+
if not docs_dir.exists():
363+
self._print_error("new_docs directory not found!")
340364
return False
341365

342-
# Run pre-commit on all files
343-
cmd = ["pre-commit", "run", "--all-files"]
366+
if action == "build":
367+
return self._build_docs(clean, extra_args)
368+
if action == "serve":
369+
return self._serve_docs(port, extra_args)
370+
self._print_error(f"Unknown docs action: {action}")
371+
return False
344372

345-
# Add any extra arguments passed through from CLI
373+
def _build_docs(self, clean: bool, extra_args: Optional[List[str]] = None) -> bool:
374+
"""Build documentation."""
375+
self._print_header("Building Documentation")
376+
377+
cmd = ["mkdocs", "build"]
378+
if clean:
379+
cmd.append("--clean")
380+
381+
# Add any extra arguments
346382
if extra_args:
347383
cmd.extend(extra_args)
348384

349-
success = self._run_command_with_confirmation(cmd)
385+
success = self._run_command(cmd, cwd=self.project_root / "new_docs")
350386

351387
if success:
352-
self._print_success("Pre-commit hooks completed successfully!")
388+
self._print_success("Documentation built successfully!")
389+
site_dir = self.project_root / "new_docs" / "site"
390+
if site_dir.exists():
391+
self._print_success(f"Built site available at: {site_dir}")
353392
else:
354-
self._print_warning("Pre-commit hooks found issues (this is normal)")
355-
self._print_warning("Review the output above and fix any issues")
393+
self._print_error("Documentation build failed!")
394+
395+
return success
396+
397+
def _serve_docs(self, port: int, extra_args: Optional[List[str]] = None) -> bool:
398+
"""Serve documentation locally."""
399+
self._print_header(f"Serving Documentation on port {port}")
400+
401+
cmd = ["mkdocs", "serve", "--dev-addr", f"127.0.0.1:{port}"]
402+
403+
# Add any extra arguments
404+
if extra_args:
405+
cmd.extend(extra_args)
406+
407+
self._print_success(
408+
f"Documentation will be available at: http://127.0.0.1:{port}"
409+
)
410+
self._print_warning("Press Ctrl+C to stop the server")
411+
412+
# For serve, we don't use confirmation since it's a long-running process
413+
return self._run_command(cmd, cwd=self.project_root / "new_docs")
414+
415+
def cmd_clean(self) -> bool:
416+
"""Clean up test artifacts and cache files."""
417+
self._print_header("Cleaning Test Artifacts")
418+
419+
items_to_clean = self._find_files_to_clean()
420+
421+
if not items_to_clean:
422+
self._print_success("Nothing to clean!")
423+
return True
424+
425+
self._show_summary(
426+
items_to_clean, f"Items to be removed ({len(items_to_clean)} total)"
427+
)
428+
429+
if not self._confirm(
430+
f"Remove these {len(items_to_clean)} items?", default=True
431+
):
432+
self._print_warning("Clean operation cancelled")
433+
return True
434+
435+
removed_count = 0
436+
for item in items_to_clean:
437+
try:
438+
if item.is_dir():
439+
shutil.rmtree(item)
440+
else:
441+
item.unlink()
442+
removed_count += 1
443+
if len(items_to_clean) <= 10: # Show individual items for small lists
444+
self._print_success(
445+
f"Removed {item.relative_to(self.project_root)}"
446+
)
447+
except OSError as e:
448+
self._print_error(f"Failed to remove {item}: {e}")
449+
450+
if len(items_to_clean) > 10:
451+
self._print_success(
452+
f"Successfully removed {removed_count}/{len(items_to_clean)} items"
453+
)
356454

357455
return True
358456

@@ -615,6 +713,7 @@ def show_help(self) -> None:
615713
test Run pytest with matplotlib comparison
616714
baseline Generate baseline images for matplotlib tests
617715
benchmark Run performance benchmarks
716+
docs Build or serve documentation
618717
clean Clean up test artifacts
619718
precommit Run pre-commit hooks on all files
620719
help Show this help
@@ -633,13 +732,21 @@ def show_help(self) -> None:
633732
--save NAME Save benchmark results with custom name
634733
--with NAME Compare with specific baseline
635734
735+
Docs command options:
736+
build Build documentation (default action)
737+
serve Serve documentation locally
738+
--port PORT Port for serve command (default: 8000)
739+
--no-clean Skip --clean flag for build command
740+
636741
Examples:
637742
./dev test -n 4 # Run tests with 4 jobs
638743
./dev test -k "test_basic" # Run only tests matching "test_basic"
639744
./dev test --verbose -s # Pass pytest arguments directly
640745
./dev benchmark run --save baseline # Run benchmarks and save as 'baseline'
641746
./dev benchmark compare --with baseline # Compare with 'baseline'
642747
./dev benchmark list # List available baselines
748+
./dev docs build # Build documentation
749+
./dev docs serve --port 8080 # Serve documentation on port 8080
643750
./dev clean # Clean up test artifacts
644751
"""
645752
print(help_text)
@@ -925,6 +1032,16 @@ def make_menu_item(title, command_text):
9251032
),
9261033
"baseline",
9271034
),
1035+
(
1036+
make_menu_item(
1037+
"📚 Build documentation", "cd new_docs && mkdocs build --clean"
1038+
),
1039+
"docs_build",
1040+
),
1041+
(
1042+
make_menu_item("🌐 Serve documentation", "cd new_docs && mkdocs serve"),
1043+
"docs_serve",
1044+
),
9281045
(
9291046
make_menu_item(
9301047
"⚡ Run benchmarks", "python -m pytest --benchmark-only"
@@ -967,6 +1084,10 @@ def make_menu_item(title, command_text):
9671084
self.cmd_clean()
9681085
elif choice == "precommit":
9691086
self.cmd_precommit()
1087+
elif choice == "docs_build":
1088+
self.cmd_docs("build", clean=True)
1089+
elif choice == "docs_serve":
1090+
self.cmd_docs("serve", port=8000)
9701091
elif choice == "benchmark":
9711092
self._interactive_benchmark_menu()
9721093
elif choice == "help":
@@ -1080,6 +1201,24 @@ def main():
10801201
"--with", dest="compare_with", type=str, help="Compare with specific baseline"
10811202
)
10821203

1204+
# Docs command
1205+
docs_parser = subparsers.add_parser("docs", help="Build or serve documentation")
1206+
docs_parser.add_argument(
1207+
"action",
1208+
choices=["build", "serve"],
1209+
default="build",
1210+
nargs="?",
1211+
help="Documentation action (default: build)",
1212+
)
1213+
docs_parser.add_argument(
1214+
"--port", type=int, default=8000, help="Port for serve command (default: 8000)"
1215+
)
1216+
docs_parser.add_argument(
1217+
"--no-clean",
1218+
action="store_true",
1219+
help="Skip --clean flag for build command",
1220+
)
1221+
10831222
# Other commands
10841223
subparsers.add_parser(
10851224
"baseline", help="Generate baseline images for matplotlib tests"
@@ -1150,6 +1289,9 @@ def main():
11501289
baseline_name = getattr(args, "save", None)
11511290
compare_with = getattr(args, "compare_with", None)
11521291
success = dev.cmd_benchmark(args.action, baseline_name, compare_with)
1292+
elif args.command == "docs":
1293+
clean = not getattr(args, "no_clean", False)
1294+
success = dev.cmd_docs(args.action, args.port, clean, unknown_args)
11531295
elif args.command == "clean":
11541296
success = dev.cmd_clean()
11551297
elif args.command == "precommit":

0 commit comments

Comments
 (0)