98 Commits
main ... ai

Author SHA1 Message Date
f88f8ae8fa governing text review 2026-04-25 10:34:20 -05:00
Codex
a91f0224cc Add AI project context and workspace skeleton 2026-04-25 09:23:21 -05:00
9d15ab56c6 Add AI documentation skills 2026-04-25 09:08:55 -05:00
100a4d5419 Track AI workspace files 2026-04-25 08:43:28 -05:00
d6f220c5fb ignore local ai files 2026-04-25 08:42:28 -05:00
e7a6ffeb29 re-add caps to team uniform
Some checks failed
CI - Docs build check / build-check (push) Successful in 12s
Build & publish docs (rc + release) / publish (push) Has been cancelled
2026-03-02 09:55:13 -06:00
c4c1be4b5f add "acting commissioner" to secretary 2026-03-02 09:54:58 -06:00
7e3693857e improve wording for DR
All checks were successful
CI - Docs build check / build-check (push) Successful in 20s
Build & publish docs (rc + release) / publish (push) Successful in 19s
2026-03-02 08:46:32 -06:00
5d3c65bd76 typo in designated hitter note 2026-03-02 08:45:31 -06:00
90e90f8373 better specify base size 2026-03-02 08:44:53 -06:00
0beaad0401 spelling error 2026-02-28 09:58:42 -06:00
b503075277 add mkdocs to spellcheck 2026-02-28 09:58:00 -06:00
5167aef0b8 update readme, index
Some checks failed
CI - Docs build check / build-check (push) Failing after 9s
Build & publish docs (rc + release) / publish (push) Successful in 16s
2026-02-28 09:53:37 -06:00
c16e25a738 fix errors 2026-02-28 09:18:02 -06:00
2e68515e2c update logo and favicon
All checks were successful
Build & publish docs (rc + release) / publish (push) Successful in 18s
CI - Docs build check / build-check (push) Successful in 9s
2026-02-27 16:34:00 -06:00
a2fbd002f0 rename branch to 'draft' 2026-02-27 16:33:25 -06:00
9664558722 cleanup, simplify to bylaws, policy, playing rules. 2026-02-27 16:33:24 -06:00
8ffb67cb2c catch typos 2026-02-27 16:11:29 -06:00
f8a9aa0f9a firm up annual meeting 2026-02-27 15:51:49 -06:00
d8dea75d89 unintentional board/commissioner mistakes 2026-02-27 15:51:29 -06:00
7ff57a159a Firm up role of member franchises 2026-02-27 15:51:07 -06:00
d7255d2aaa add buffer funds an refunds, rebate, credit 2026-02-27 15:48:40 -06:00
168ddeba15 "Good Standing"
"good standing"
2026-02-27 15:47:13 -06:00
404464f14c remove periods from headings 2026-02-27 10:54:22 -06:00
b8c4267efa change to "League Policy" 2026-02-27 10:48:59 -06:00
2abc433e4b define "playing rules" 2026-02-27 10:38:30 -06:00
16caf9aead consolidate postseason section 2026-02-27 10:36:44 -06:00
2727af3c00 Add interleague play administration 2026-02-27 10:29:31 -06:00
ad5d0ee6cd Add pre-game meeting. 2026-02-27 09:41:43 -06:00
24a796d9da remove specific rule numbers from incorporated rules 2026-02-27 09:41:43 -06:00
986cc59c78 re-organize the "regulation game" section 2026-02-27 09:41:43 -06:00
840314bed0 show "generally" note of umpire disputes from MLB rules 2026-02-27 09:41:43 -06:00
346fd9fd2f clarify number of mound visits 2026-02-27 09:41:43 -06:00
d3e60279ec Add Authority and Hierachy 2026-02-27 09:41:43 -06:00
9e82ce29f1 Reorganize Lineups into "Expanded" and "Restricted" 2026-02-27 09:41:41 -06:00
ed1c9f6b3f re-organize minimum number of players 2026-02-25 21:13:12 -06:00
0daef59061 remove duplicate voting definition, clarify 2026-02-25 21:12:40 -06:00
3987cdf512 specify record in tiebreakers 2026-02-25 21:12:14 -06:00
f7ce031701 remove reference to 501c3 2026-02-25 21:07:02 -06:00
a2cd18b5a7 fix unintentional mistakes 2026-02-25 21:06:41 -06:00
f6d8755cd7 first attempt at member franchise election of the board
All checks were successful
Build & publish docs (rc + release) / publish (push) Successful in 17s
2026-02-22 18:30:26 -06:00
33777f30a1 rely on incorporated rules for collisions 2026-02-22 18:19:46 -06:00
05ba708267 change to "Incorporated Rules" 2026-02-22 18:19:27 -06:00
2fe6d12fdd Amend umpire disputes 2026-02-22 18:18:24 -06:00
e7d226727b remove replay review from applicability 2026-02-22 18:13:23 -06:00
0fa3b36fbf further cleanup of protests, remove explicit R&C committee 2026-02-22 18:12:37 -06:00
060a8a4aa7 clean up forfeit rules 2026-02-22 18:12:37 -06:00
58ef37ebf2 change roster restrictions, removing explicit reference to R&C committee 2026-02-22 18:12:37 -06:00
779044b857 detail discipline authority 2026-02-22 18:12:37 -06:00
731b766529 detail appeals 2026-02-22 18:12:37 -06:00
8a94a0d872 provide guidance for reporting discipline to league 2026-02-22 18:12:37 -06:00
79fb5aa888 move reporting 2026-02-22 18:12:37 -06:00
25d7bc229c report process 2026-02-22 18:12:37 -06:00
7ffeb7dbc6 amend "league website" to "communication channels" 2026-02-22 18:12:37 -06:00
4fa2738d82 move conduct and discipline 2026-02-22 18:12:36 -06:00
367f3375b4 Reorganize Game Administration and Create Season Administration 2026-02-22 18:12:36 -06:00
65473dc0cf Clean-up game administration rules 2026-02-22 18:12:34 -06:00
2e4a7db9ff clean up equipment and uniforms 2026-02-22 17:52:59 -06:00
e5260acf44 Re-architect conduct and discipline 2026-02-22 17:52:59 -06:00
f31010820d add draft as a release type 2026-02-21 09:54:04 -06:00
ee68e3369b gender neutral language 2026-02-21 09:53:58 -06:00
fe0d5a2716 require board approval for paid roles 2026-02-15 18:27:27 -06:00
ad608f6ab2 add scheduler to appointed roles 2026-02-15 18:22:32 -06:00
4d0ad53b98 move meetings, move equipment, move conduct
All checks were successful
CI - Docs build check / build-check (push) Successful in 9s
Build & publish docs (rc + release) / publish (push) Successful in 15s
2026-02-07 14:37:10 -06:00
2ed384172e penalties/fees, membership duplication cleanup 2026-02-07 14:21:49 -06:00
0a1ce7e08b members rights, status, obligations and discipline 2026-02-07 12:58:21 -06:00
04ff6d3899 designation of governance vs. participants 2026-02-07 12:13:53 -06:00
58d69100c3 generalize committees from "rules and competition committee" 2026-02-07 11:50:29 -06:00
6d242c9021 budget, rules committee 2026-02-07 11:35:44 -06:00
7ee712c333 add docx to prerelease
All checks were successful
CI - Docs build check / build-check (push) Successful in 8s
Build & publish docs (rc + release) / publish (push) Successful in 15s
2026-02-07 11:17:29 -06:00
5c46a64056 members, managers, players, league roles
All checks were successful
Build & publish docs (rc + release) / publish (push) Successful in 8s
2026-02-06 18:36:38 -06:00
76964d837c flesh out miscellaneous and dissolution
All checks were successful
Build & publish docs (rc + release) / publish (push) Successful in 8s
2026-02-06 17:39:53 -06:00
0b4fadf18d flesh out treasurer and secretary 2026-02-06 17:39:53 -06:00
694c423772 remove commissioner power 2026-02-06 17:39:53 -06:00
3669173cb6 capitalization fix 2026-02-06 17:39:53 -06:00
47a3a32632 by-laws => Bylaws 2026-02-06 17:39:53 -06:00
70eace7afb typo 2026-02-06 17:39:53 -06:00
43d7b10551 amend purpose to include members 2026-02-06 17:39:53 -06:00
dcbe64b222 add powers, limitations, office and agent 2026-02-06 17:39:52 -06:00
85856af1fd remove date from index 2026-02-06 16:31:39 -06:00
04285c9817 fix pre-release
All checks were successful
Build & publish docs (rc + release) / publish (push) Successful in 8s
2026-02-06 16:00:26 -06:00
82098131aa split bylaws and policy
All checks were successful
Build & publish docs (rc + release) / publish (push) Successful in 8s
2026-02-05 20:37:48 -06:00
d5a2d95ed6 from melanie 2026-02-05 20:37:48 -06:00
89fd2860ae from tony 2026-02-05 20:37:48 -06:00
1bd64f7a99 budget section, unify on "dues" 2026-02-05 20:37:48 -06:00
5c08d16be3 restructure officers, unify on "Commissioner" 2026-02-05 20:37:48 -06:00
2cd58ee332 Add directors 2026-02-05 20:37:48 -06:00
e8ea6bccb6 simplify member standing and voting 2026-02-05 20:37:48 -06:00
3bfe28a61e section -> provision 2026-02-05 20:37:48 -06:00
4ae1d6898f clarify membership. formalize "Manager" 2026-02-05 20:37:48 -06:00
0c8c37907d amend purpose 2026-02-05 20:37:48 -06:00
f92d67775b Update name section, unify to "League" 2026-02-05 20:37:47 -06:00
5e8ef75063 promote name and purpose to sections 2026-02-05 20:37:47 -06:00
d670a6b450 move assets, styles to docs folder 2026-02-05 20:37:47 -06:00
d5669178db implement mkdocs, remove pandoc 2026-02-05 20:37:41 -06:00
44d0a66aa5 moved general play section to new document as playing rules 2026-02-05 20:34:00 -06:00
f59d056cf4 ci, build, release
All checks were successful
Build & publish docs (rc + release) / publish (push) Successful in 8s
+ update spellcheck to use cspell
2026-02-05 20:17:04 -06:00
eaf916443c implement mkdocs, remove pandoc
directory restructuring, remove makefile and build files in repo
moved general play section to new document as playing rules
move assets, styles to docs folder
2026-02-05 18:09:06 -06:00
293 changed files with 70000 additions and 2342 deletions

12
.ai/README.md Normal file
View File

@@ -0,0 +1,12 @@
# .ai
Store repository-local AI artifacts here.
Examples:
- prompts
- notes
- plans
- generated scratch files
This directory is gitignored on non-`ai` branches in this repo.

11
.ai/plans/README.md Normal file
View File

@@ -0,0 +1,11 @@
# Plans
Store task-specific plans here.
Examples:
- implementation plans
- sequencing notes
- checkpoints for multi-step work
Keep durable repository context in `../project-context.md`, not here.

85
.ai/project-context.md Normal file
View File

@@ -0,0 +1,85 @@
# Project Context
## Project Summary
This repository stores and publishes the governing documents for the Chicago Metropolitan Baseball Association (CMBA).
The canonical source text lives in Markdown files under `docs/`. The repository also contains the MkDocs configuration, build tooling, and CI/release workflows used to publish those documents as a static documentation site.
## Project Goals
- Keep the current CMBA governing documents in version-controlled plain text
- Publish a readable static site for league officials, managers, and players
- Preserve a clear separation between bylaws, policy, and playing rules
- Make edits reviewable, traceable, and easy to validate before publication
- Maintain enough project history to understand how the governing documents evolved
## Document Model
The repository is organized around three core documents:
- `docs/01-bylaws.md`: league governance, authority, membership, meetings, and amendment structure
- `docs/02-policy.md`: league operations, procedures, discipline, administration, and competition governance
- `docs/03-playing-rules.md`: on-field rules, lineup formats, game administration, and incorporated baseball rules
When interpreting or editing content, preserve that separation unless the user explicitly wants to reorganize the document set.
The site home page in `docs/index.md` describes the intended hierarchy:
1. Bylaws
2. League Policy
3. Playing Rules
For on-field administration, the playing rules also incorporate Official Baseball Rules where CMBA rules do not provide otherwise.
## Repository Structure
- `docs/`: canonical published content and site assets
- `docs/assets/`: logos and site images
- `docs/styles/`: site-specific CSS
- `mkdocs/mkdocs.yml`: MkDocs site configuration
- `mkdocs/requirements.txt`: Python build dependencies
- `tools/build.sh`: local/CI build entry point for MkDocs
- `tools/spellcheck/`: CSpell config and baseball-specific dictionary
- `.github/workflows/ci-docs.yml`: validation workflow for spelling and docs build
- `.github/workflows/release.yml`: release packaging and publishing workflow
## Working Assumptions For AI
- Treat Markdown files under `docs/` as the canonical source of truth
- Prefer editing the source documents rather than generated outputs
- Keep cross-references, headings, and document numbering stable unless there is a reason to change them
- Avoid mixing governance text, operational policy, and game rules without explicit justification
- If a change affects wording, structure, or links, local preview/build validation is useful
- League-specific terms may need updates to `tools/spellcheck/baseball-words.txt`
- Check `.ai/skills/` before substantive work and use the relevant local skill when the task matches one
## Local Development Workflow
Typical local commands:
```bash
python3 -m pip install -r mkdocs/requirements.txt
mkdocs serve -f mkdocs/mkdocs.yml
```
Builds are driven by MkDocs with `mkdocs/mkdocs.yml`, and `tools/build.sh` wraps the production build command with optional strict mode.
## Historical Context
- The constitution and bylaws were modernized in Google Docs in 2021
- This repository moves that work into Git and GitHub
- Earlier tracked history reaches back to 2016
- In 2026, the material was re-architected into the current split between bylaws, policy, and playing rules. The league was also re-organized into a non-profit organization.
## Recommended AI Usage
Use this file for stable repository context.
Put task-specific material elsewhere under `.ai/`, for example:
- `plans/` for implementation plans
- `notes/` for research notes
- `scratch/` for temporary generated files
If future AI-specific conventions are added, record them in `.ai/README.md` and keep this file focused on the project itself.

12
.ai/prompts/README.md Normal file
View File

@@ -0,0 +1,12 @@
# Prompts
Store reusable prompts here.
Examples:
- drafting prompts
- review prompts
- transformation prompts
- recurring research instructions
Prefer prompt files that are narrow, named clearly, and reusable across tasks.

View File

@@ -0,0 +1,60 @@
# CMBA Governing Text Review Prompt
Use this prompt when reviewing proposed changes to CMBA governing text, including `docs/01-bylaws.md`, `docs/02-policy.md`, and `docs/03-playing-rules.md`.
## Role
You are reviewing governing text for a nonprofit amateur baseball league. Treat the documents as operative rules, not marketing copy. Your job is to identify ambiguity, conflicts, missing authority, procedural gaps, and unintended practical effects before the text is adopted.
This is not legal advice. Do not invent legal requirements. When a legal issue may matter, flag it as a question for counsel or league leadership.
## Controlling Hierarchy
When provisions overlap or conflict, apply this hierarchy:
1. Bylaws
1. League Policy
1. Playing Rules
1. Incorporated external rules, including Official Baseball Rules, only where CMBA text incorporates them
Do not allow League Policy or Playing Rules to alter powers, voting rights, amendment procedures, membership rights, or board authority reserved to the Bylaws.
## Review Priorities
Review for the following, in order:
1. **Authority**: Does the provision identify who may act, decide, enforce, amend, or appeal?
1. **Conflict**: Does it contradict another CMBA document or create two rules for the same situation?
1. **Procedure**: Does it say when action occurs, what notice is required, what vote or approval is needed, and when the result takes effect?
1. **Defined terms**: Are key terms used consistently, especially Member Franchise, Manager, Player, Board, Commissioner, Good Standing, League Policy, and Playing Rules?
1. **Enforceability**: Can a league official apply the rule from the text alone without guessing?
1. **Fairness and due process**: Does the text provide reasonable notice, decision-maker authority, and appeal or review where discipline, eligibility, forfeits, or membership status are affected?
1. **Operational impact**: Can managers, umpires, and league officials apply the rule during a season or game without disrupting ordinary league operations?
1. **Drafting quality**: Is the language clear, direct, internally consistent, and free of avoidable redundancy?
## Drafting Standards
- Prefer mandatory language only when the duty is intended: use "shall" for obligations, "may" for discretion, and "must not" or "shall not" for prohibitions.
- Keep rules in the document where they belong: governance in Bylaws, league operations in League Policy, and on-field administration in Playing Rules.
- Preserve numbered-list Markdown style using repeated `1.` entries unless there is a specific reason to do otherwise.
- Preserve cross-reference anchors and headings when possible.
- Avoid changing substantive meaning while making copyedits unless the requested review explicitly calls for substantive revisions.
- Flag undefined or inconsistently capitalized terms instead of silently normalizing them when the capitalization may affect meaning.
## Response Format
Lead with findings, ordered by severity. Use concrete references to the affected section or heading.
For each finding, include:
1. **Issue**: the problem in the current or proposed text.
1. **Why it matters**: the practical governance or rules consequence.
1. **Suggested fix**: proposed text or a specific drafting direction.
Use these severity labels:
- **Blocking**: creates an authority problem, document conflict, unenforceable rule, or serious procedural defect.
- **Major**: likely to cause inconsistent application, disputes, or unintended operational consequences.
- **Minor**: clarity, terminology, formatting, or low-risk drafting issue.
If no material issues are found, say so directly and list any residual assumptions or open questions.

12
.ai/scratch/README.md Normal file
View File

@@ -0,0 +1,12 @@
# Scratch
Store temporary generated artifacts here.
Examples:
- intermediate exports
- generated drafts
- one-off helper outputs
- disposable working files
Do not treat files in this directory as canonical project content.

View File

@@ -0,0 +1,149 @@
---
name: baseball-rules
description: Use this skill for baseball rules interpretations, rulebook citation work, cross-code comparisons, and local policy drafting that depends on baseball rulebooks stored locally in this repository. It covers Official Baseball Rules, NFHS baseball rules, American Legion Baseball senior rules, and NCAA baseball rules.
---
# Baseball Rules
Use this skill when the answer depends on a governing baseball code, not just general baseball knowledge.
## When To Use
- Use this skill for eligibility, lineup, substitution, re-entry, batting out of order, protest, appeal, obstruction, interference, ejection, suspension, pitching, and game-administration questions.
- Use this skill when the user wants rulebook-backed answers, citations, or draft language grounded in an existing baseball code.
- Use this skill when writing local league policies that borrow from, override, or reconcile an existing ruleset.
- Use this skill when comparing how multiple baseball codes treat the same situation.
## Rule Sets In Scope
- `references/2026-official-baseball-rules.pdf`: Official Baseball Rules, used as the pro-style baseline unless local context says otherwise.
- `references/NFHS-Baseball-RB.pdf`: NFHS baseball rules for high-school play.
- `references/39ACY1225-Baseball-Rule-Book-Senior.pdf`: American Legion Baseball Rule Book, including senior baseball rules and Legion-specific administrative rules.
- `references/PRMBA_RulesBook.pdf`: NCAA baseball rules for college play.
Do not merge these codes into one composite answer unless the user explicitly asks for a comparison.
## Ruleset Selection
Choose the governing source before answering.
- If the user says MLB, professional, pro-style, or cites OBR rule numbers, start with Official Baseball Rules.
- If the user says high school, varsity, state association, or NFHS, use the NFHS book.
- If the user says college, NCAA, collegiate, or NCAA mechanics, use the NCAA book.
- If the user says American Legion, Legion, department tournament, roster certification, or Legion protest, use the American Legion rule book.
- If the user says local league, tournament, or house rules, determine whether the local rules adopt one of the base codes and then identify any local overrides.
If the governing code is uncertain:
- State the uncertainty explicitly.
- Give a conditional answer by ruleset when the likely codes differ in outcome.
- Avoid presenting one code as universal baseball law.
## Source Handling
Prefer local sources in `references/`.
Use `mutool` to inspect PDFs without converting entire books unless needed.
Examples:
```bash
mutool draw -F txt -o - references/2026-official-baseball-rules.pdf 1
mutool draw -F txt -o - references/NFHS-Baseball-RB.pdf 45
```
For broader searching, extract text into a temporary file under `.ai/` and then search with `rg`.
Example workflow:
```bash
mkdir -p .ai/tmp
mutool draw -F txt -o .ai/tmp/obr.txt references/2026-official-baseball-rules.pdf
rg -n "batting out of order|appeal play|courtesy runner" .ai/tmp/obr.txt
```
Working rules for source use:
- Read only the relevant book and section for the current question.
- Prefer rule text, definitions, and explicit penalties over memory.
- If the book has a table of contents, definitions, case plays, approved rulings, or comments, use those to narrow the search before reading widely.
- If a rulebook answer depends on a definition, cite both the operative rule and the definition when helpful.
## Analysis Workflow
1. Identify the governing ruleset.
2. Classify the question:
lineup/substitution, dead-ball/live-ball, timing play, force/tag, appeal/protest, equipment, eligibility, discipline, pitching, mercy/time limits, or administrative procedure.
3. Read the minimum rulebook text needed to answer the question.
4. Separate explicit rule text from interpretation.
5. Check for exceptions, penalties, and restart/resume mechanics.
6. If local rules are involved, state the base code first and then the local override.
7. If comparing rulesets, answer side-by-side instead of blending language.
## Common Risk Areas
Be careful in these categories because different codes often diverge:
- Courtesy runners
- Re-entry and substitution rules
- Batting out of order
- Force-play slide / collision / interference rules
- Malicious contact / flagrant conduct terminology
- Pitching restrictions, visits, and batter minimums
- Protest rights and timing
- Appeal mechanics and live-ball versus dead-ball requirements
- Ejections, suspensions, and administrative penalties
- Game-ending procedures, run limits, time limits, and tie-game handling
## Interpretation Rules
- Treat the rulebook as controlling and your reasoning as secondary.
- Say when an answer is explicit in the book versus inferred from multiple sections.
- Do not overstate certainty when the text is ambiguous or fact-sensitive.
- Distinguish between playing rules and tournament or roster-administration rules.
- Distinguish between what is permitted, what is a violation, and what the penalty or remedy is.
- When the answer depends on timing, identify the trigger:
pitch, play, appeal, substitution, discovery, or protest timing.
## Citation Style
Keep citations precise and compact.
- Prefer rule numbers, section names, or page numbers when available.
- Quote only the minimum text needed.
- If you cannot reliably identify a rule number from the extracted text, cite the rulebook and page or nearby heading instead of guessing.
- When comparing codes, give each citation next to its own conclusion.
## Policy Drafting Guidance
When using these books to draft local rules:
- State the base code being adopted.
- List each intentional departure from that base code.
- Preserve terminology from the governing code unless the local rule deliberately redefines it.
- Avoid creating local rules that conflict with penalty enforcement or protest procedures unless the local league clearly intends that result.
- Flag places where a short local rule has hidden downstream effects, especially on substitutions, forfeits, eligibility, and discipline.
## Output Patterns
For a single-code interpretation, prefer:
1. Governing ruleset.
2. Short answer.
3. Why, with concise rule support.
4. Citation.
5. Any material caveat, exception, or unresolved ambiguity.
For a multi-code comparison, prefer:
1. Brief statement of the issue.
2. One subsection per ruleset.
3. A short bottom-line comparison noting where the outcomes differ.
## What Not To Do
- Do not answer from memory when the local PDFs can be checked.
- Do not assume OBR controls amateur, school, college, or Legion play.
- Do not confuse NCAA with NFHS.
- Do not confuse playing rules with administrative tournament regulations.
- Do not claim a citation you have not actually verified in the source.

View File

@@ -0,0 +1,38 @@
---
name: cmba-historical-bylaws
description: Use when answering questions about historical CMBA constitution/bylaws text from this repository's git history. This skill restricts references to the approved historical sources only: the initial commit containing the 2016 constitution/bylaws content, plus the tagged releases 2022-01-09, 2023, and 2024. Do not use newer draft, rc, test, or other tags as authority.
---
# CMBA Historical Bylaws
Use this skill when the user asks what the CMBA rules/bylaws said in a prior year, how language changed over time, or to quote or compare historical versions.
## Approved sources
Read [references/source-map.md](references/source-map.md) first. Treat its whitelist as authoritative.
Only use these git refs as historical authority:
- `1e16926c5f76989d8821dc3f2b0df0c1c500e8e9` for the imported 2016 constitution/bylaws text
- `refs/tags/2022-01-09`
- `refs/tags/2023`
- `refs/tags/2024`
Do not cite or summarize newer tags such as `draft*`, `rc*`, `v2026*`, or similar release-prep tags.
## Workflow
1. Identify which approved version or comparison the user wants.
2. Use the path listed in `references/source-map.md` for that ref.
3. Prefer direct git reads over working tree files, for example:
- `git show refs/tags/2024:src/cmba-bylaws.md`
- `git show 1e16926c5f76989d8821dc3f2b0df0c1c500e8e9:content`
4. When comparing versions, use `git diff --word-diff=color <old-ref> <new-ref> -- <path>` and adjust paths if the file moved between refs.
5. In the answer, name the exact ref and the document path used.
## Guardrails
- Be explicit about dates and refs. The initial commit date is `2021-11-09`, but it imports the `2016` constitution/bylaws text.
- If a user asks for "latest" historical bylaws, interpret that as the latest approved historical tag: `refs/tags/2024`.
- If a request would rely on an unapproved newer tag, say that newer tags are drafts and are intentionally excluded from historical reference.
- If wording differs because of formatting or conversion, say so rather than claiming a substantive rule change.

View File

@@ -0,0 +1,48 @@
# Approved Historical Sources
Use only these refs when answering historical CMBA constitution/bylaws questions.
## Whitelist
- `1e16926c5f76989d8821dc3f2b0df0c1c500e8e9`
- Commit date: `2021-11-09`
- Commit subject: `initial commit, 2016 constitution and bylaws`
- Historical meaning: imported 2016 constitution/bylaws text
- Content path: `content`
- `refs/tags/2022-01-09`
- Content path: `src/cmba-bylaws.md`
- `refs/tags/2023`
- Content path: `src/cmba-bylaws.md`
- `refs/tags/2024`
- Content path: `src/cmba-bylaws.md`
## Non-authoritative refs
Do not use these as historical authority:
- `draft*`
- `rc*`
- `v2026*`
- `v2024`
If a user asks about one of those refs, explain that they are draft or test-era refs and not approved for historical citation.
## Useful commands
Read a full version:
```bash
git show refs/tags/2024:src/cmba-bylaws.md
git show refs/tags/2023:src/cmba-bylaws.md
git show refs/tags/2022-01-09:src/cmba-bylaws.md
git show 1e16926c5f76989d8821dc3f2b0df0c1c500e8e9:content
```
Compare approved versions:
```bash
git diff --word-diff=color refs/tags/2023 refs/tags/2024 -- src/cmba-bylaws.md
git diff --word-diff=color refs/tags/2022-01-09 refs/tags/2023 -- src/cmba-bylaws.md
```
When comparing the imported 2016 text to later tagged versions, diff the extracted file contents rather than assuming the path is the same across refs.

View File

@@ -0,0 +1,82 @@
---
name: example-sports-org-bylaws
description: Use this skill when drafting or reviewing bylaws, constitutions, or governance provisions for sports organizations and you want to compare against local example documents for leagues, youth baseball organizations, or sport-specific associations stored in this repository.
---
# Sports Organization Bylaws Examples
Use this skill when the task benefits from comparing governance language across existing sports-organization bylaws rather than drafting from scratch.
## When To Use
- Use this skill when drafting or revising bylaws, constitutions, or governance articles for a sports league, club, or association.
- Use this skill when the user wants example language for membership, board structure, meetings, officers, elections, discipline, dues, or dissolution provisions in a sports context.
- Use this skill when the draft needs operational articles that are common in sports organizations, such as eligibility, team structure, postseason rules, awards, or volunteer requirements.
- Use this skill when comparing how different sports organizations separate core governance from game- or league-administration rules.
## Scope
These are example documents, not governing authorities.
- Use them as comparative models for structure, article sequencing, and clause options.
- Do not treat any one example as the default best practice for every organization.
- Where a task also depends on nonprofit corporate law or tax-exempt language, pair this skill with the local `nonprofit` skill and check the legal framework separately.
## References
- `references/chesapeake-msbl.md`: adult baseball league bylaws with nonprofit framing, board governance, dues, meetings, discipline, finances, all-star provisions, and postseason awards.
- `references/dartball.md`: church dartball league rules and governance mix, useful as an example of where sport operations and governance provisions are combined in one document.
- `references/little-league.md`: Little League local league constitution template with member classes, board composition, officer duties, compliance expectations, and strong youth-sports governance structure.
Load only the reference file or files that match the organization's type and drafting need.
## Selection Guidance
- Start with `little-league.md` when the organization is youth-focused, volunteer-heavy, member-driven, or needs a formal board-and-officer constitution structure.
- Start with `chesapeake-msbl.md` when the organization is an adult amateur league and needs examples for dues, team participation, disciplinary authority, league operations, or baseball-specific administration.
- Read `dartball.md` when the organization blends league governance and sport rules in one document, or when you need a cautionary example of how those layers can become mixed together.
## Workflow
1. Identify the organization's type:
youth league, adult league, club, association, or faith/community-based sports organization.
2. Decide whether the task is about core governance, sport operations, or both.
3. Read the most relevant example document first instead of loading all examples.
4. Extract the useful structure and clause patterns, then rewrite them to fit the target organization.
5. Separate reusable governance concepts from sport-specific procedural rules unless the user explicitly wants them combined.
6. Normalize terminology, thresholds, officer titles, and article numbering so the final draft is internally consistent.
## Drafting Rules
- Treat examples as source material for adaptation, not copy-paste boilerplate.
- Distinguish governance provisions from playing rules, roster rules, award rules, and tournament procedures.
- If the target organization wants a clean bylaws document, move sport-specific competition rules into separate policies, league rules, or appendices.
- Keep membership, voting, board powers, officer duties, and amendment procedures coherent as a set.
- Remove organization-specific names, places, sport terms, thresholds, and compliance references that do not belong in the target draft.
- If using Little League-derived material, preserve only what fits the target organization's actual governing framework and external obligations.
## Comparison Use Cases
These references are especially useful for:
- comparing member-based versus board-centric governance;
- choosing how much operational detail belongs in bylaws;
- drafting officer duty sections with enough specificity to be useful;
- modeling discipline, suspension, and removal procedures; and
- deciding whether financial controls such as dual signatures, budgets, and audits should appear in the bylaws.
## Output Pattern
For drafting support, prefer:
1. the recommended model source or mix of sources;
2. the revised clause or article outline;
3. short notes explaining which example informed each major choice; and
4. any provisions that should be split into separate league rules instead of staying in the bylaws.
## What Not To Do
- Do not assume an example organization's governance model fits the user's organization unchanged.
- Do not copy sport-specific operating rules into a general bylaws draft unless that is intentional.
- Do not import organization-specific facts, placeholders, or external-regime requirements without confirming they apply.
- Do not confuse illustrative example language with legal requirements.

View File

@@ -0,0 +1,297 @@
**BYLAWS OF CHESAPEAKE MEN'S SENIOR BASEBALL LEAGUE, INC.**
# ARTICLE I -- ORGANIZATION
## SECTION 1. INCORPORATION
Chesapeake Men's Senior Baseball League, Inc., herein called Chesapeake MSBL, is incorporated in the State of Maryland under Maryland non-profit corporation code to qualify as a tax-exempt organization, and shall be managed at all times in such a manner as to qualify the corporation for such exemption.
## SECTION 2. PURPOSE
The purpose of Chesapeake MSBL shall include the following:
To provide an opportunity for all adults eligible for membership (as defined in Article II) to engage in the sport of baseball; To promote involvement in Men's Senior Baseball League (MSBL) and Men's Adult Baseball League (MABL) MSBL-MABL programs and provide an opportunity for members to compete in sanctioned baseball competitions; To provide training in physical fitness, good patterns of physical development, and proper conditioning habits;
To provide opportunities for social, emotional, educational and character development, and to encourage peer and family participation in team and community activities;
To promote the sport of baseball to the community;
To provide financial aid, in the form of educational scholarships, to individuals who qualify for assistance and;
To give back to our community in the form of charitable contributions to registered charities and other local organizations.
## SECTION 3. MANAGEMENT
The Chesapeake MSBL shall be managed and directed by a board of directors, acting in accordance with these by-laws.
# ARTICLE II -- MEMBERSHIP
## SECTION 1. MEMBERSHIP
The benefits and services of Chesapeake MSBL shall be made available to any person who desires to participate in any program sponsored by Chesapeake MSBL and who is physically able to do so, subject to any limitations set forth elsewhere in these bylaws. Membership shall be contingent upon payment of such periodic registration fees and membership dues as the board of directors may from time to time determine.
a. Active Member -- An active member shall be any person who is a registered member of Chesapeake MSBL whose fees and/or fee waivers are current and who is in good standing with the board of directors.
b. Division -- The Chesapeake MSBL shall establish Divisions comprising of members or teams within a specific age group and/or skill level.
c. Team -- A team participating in the Chesapeake MSBL shall have a minimum of 12 members.
## SECTION 2. LIMITATION
Membership may not be limited in number and shall be open to anyone who qualifies under Article II, Section 1 unless space is not available due to a limit on the number of teams that can participate each year due to limitation of Chesapeake MSBL resources.
## SECTION 3. VOTING
Each board member shall be entitled to one vote in the election of directors, amendment changes and any other matters brought before the board of directors by a majority vote of the board of directors as designated in these by-laws. Voting shall be limited to board members or their official designate. A designate may be submitted to Board with three days prior notice to Secretary (as defined in Article II, Section 1.a.).
## SECTION 4. RIGHTS
a. A member shall be entitled to participate in any activity sponsored by Chesapeake MSBL, with the exception of competitive and training opportunities which may be limited by the board of directors, the coaching staff, or the rules of baseball for reasons of age, achievement or ability to participate.
b. The property rights and interests of all members shall be equal on a per member basis.
## SECTION 5. TERMINATION
a. Baseball privileges and membership may be suspended if dues, fees, or other required documentation is not submitted to the Chesapeake MSBL by the deadline approved by the board of directors. The board of directors has the right to approve extensions in case of hardship.
b. A member may resign membership at any time by giving notice in writing to the board of directors or its designee provided all obligations to Chesapeake MSBL have been met in full.
c. The head coach of any Chesapeake MSBL team (a.k.a. manager) shall have the authority to expel from his team for disciplinary, unsportsmanlike, or insubordination reasons for any baseball player or assistant coach, from any practice, game or league-sponsored event.
d. The board of directors shall have the authority to expel from membership any member deemed to cause damage to the Chesapeake MSBL organization, or to the image of Chesapeake or the sport of baseball. Damage must be of a degree judged to be excessive beyond what is usual and too great to be reasonably endured, and, must in the judgment of the board, place the continued existence of Chesapeake in jeopardy. This authority is to be exercised only upon a vote of two-thirds (2/3) of the board.
# ARTICLE III -- DUES, FEES AND ASSESSMENTS
## SECTION 1. FISCAL YEAR
The fiscal year of Chesapeake MSBL shall be from January 1 to the following December 31.
## SECTION 2. FEES
Fees shall be set and approved by the board of directors and shall not exceed that necessary to provide for the anticipated expenses of the organization.
a. Registration -- Registration for active members shall be assessed on a yearly basis. Reregistration will be required prior to re-activation of membership.
b. Changes in Fee Schedule -- The fee schedule may be changed at any time if approved by the board of directors, but shall not be changed retroactively.
c. Refunds -- There shall be no refund of fees or release of obligation to pay fees.
d. Service Requirement -- The board of directors may assess a service requirement consistent with the purposes of the club.
# ARTICLE IV -- MEETINGS OF MEMBERS
## SECTION 1. ANNUAL MEETING
a. Time and Place -- The annual meeting of the members shall be held in February, unless otherwise approved by the board of directors, at such place and reasonable time within Anne Arundel County as the board of directors may designate.
b. Purpose -- The annual meeting shall be held for the purpose (of) presenting program goals, evaluations and long-range plans.
c. Notice of Meeting -- Notice of the meeting of members shall be given to each board member and team manager not less than ten (10) or more than forty-five (45) days prior to such meeting. Each team managers will be responsible for notifying members of his team.
## SECTION 2. SPECIAL MEETINGS
a. Call -- Special meetings of Chesapeake MSBL shall be held upon the call of the board of directors, and must be conducted within thirty (30) days upon notification to each active member family by the board of directors.
b. Time and Place -- Special meetings of Chesapeake MSBL shall be held at such reasonable time and place within Anne Arundel County or nearby areas as the board of directors may designate.
c. Purpose -- The purpose of any special meeting shall be stated in the notice of call, and no other business shall be transacted.
d. Notice of Meeting -- Written notice of the special meeting shall be given to each board member not less than ten (10) days or more than thirty (30) days prior to such meeting.
## SECTION 3. QUORUM
The president or vice-president and a majority of board members shall constitute a quorum for the transaction of business.
## SECTION 4. MEETING ORGANIZATION
a. Presiding Officer -- The president of the board of directors shall preside at any meeting of members, and in his or her absence the vice-president of the board of directors shall preside.  If neither is present, the members present shall elect a presiding officer from among the members of the board of directors.
b. Secretary -- The secretary shall serve as secretary for the meeting, and in his or her absence, the presiding officer shall appoint an acting secretary.
## SECTION 5. VOTING
a. Decision -- The decision of a majority of the members voting shall be the decision of Chesapeake MSBL, unless otherwise established by the Articles of Incorporation, or these by-laws.
b. Method -- Voting may be viva-voce, but twenty-five (25) percent of board members in good standing shall have the right to demand voting by roll call.
## SECTION 6. MINUTES OF MEETINGS
Minutes of each annual meeting and special meeting shall be made available to all board members as soon as possible but no later than with the notice of the next immediate annual or special meeting of board members.
# ARTICLE V -- BOARD OF DIRECTORS
## SECTION 1. BOARD COMPOSITION
The board shall be composed of the following voting members: executive committee (president, vice-president, secretary, and treasurer),  and two (2) Division Directors.  One will be the primary representative and the second will be an alternate that can step in if needed for each active Division within the Chesapeake MSBL.  Only one person from any particular family may serve as a member of the board of directors at any one time, unless otherwise approved by the board.  The voting quorum consists of the President, Vice President, Secretary and 3 division representatives (one for each age division, 21+, 35+ and 45+),   with the Treasurer serving as a tie breaker if necessary. 
## SECTION 2. TERMS
Executive committee members shall be elected by the Board of Directors and serve until such time the executive committee member resigns in writing to the board of directors, a member of the league desires to run and is nominated for the position in which the board of directors must vote in with 2/3 majority, or death of the executive committee member.  Executive committee members can serve without term limits.
## SECTION 3. ELECTION OF EXECUTIVE COMMITTEE MEMBERS
a. Nominating Committee -- The nominating committee for replacement of Executive Committee members shall consist of all board members.      1. Nomination -- The candidates for the Executive Committee selected by the nominating committee shall be placed in nomination automatically at the annual meeting.
b. Election -- Voting may be viva-voce, but twenty-five (25) percent of board members in good standing shall have the right to demand voting by secret ballot. If secret ballot is used, each active board member shall have one vote, and shall vote for the appropriate number of nominees on one ballot.
c. Vacancies -- Should a vacancy occur on the board of directors for reasons other than normal expiration of term, the board of directors shall appoint a member to fill the unexpired term.
## SECTION 4. REMOVAL OF DIRECTORS FROM OFFICE
a. Missing two (2) meetings in a Fiscal Year or two (2) consecutive unexcused board meetings by a board member will be considered a resignation and the other board members may accept the resignation and appoint another board member to fill the unexpired term of such board member.
b. A director may be removed from the board for reasonable cause by majority vote of the board of directors.
## SECTION 5. MEETINGS OF THE BOARD
a. Time of Meeting -- Meetings of the board of directors shall be held at least quarterly, or at times set by the board, or on call of either the president or the majority of directors.
b. Notice -- Three (3) days notice, in person, by phone, e-mail or regular mail, shall be given to all directors of meetings called by the president or by the majority of the board. Notice of board meetings shall be conveyed to the board members by posting to the annual calendar and in any other appropriate manner as time permits.
c. Waiver of Notice -- Required notice shall be waived if all absent directors sign the minutes of the meeting or a separate waiver of notice, which shall become a part of the minutes.  Attendance at a meeting constitutes automatic waiver of notice.
d. Open Meetings -- All meetings of the board, except those executive sessions held for the purpose of contract negotiations, shall be open to any board member. A majority of the executive committee must approve attendance by any non-board members in advance.
e. Quorum -- The president or vice-president and a majority of board members shall constitute a quorum for the transaction of business. The act of a majority of directors present at a meeting at which a quorum is present shall be the act of the board.
f. Voting -- All matters coming before t¬se by-laws.
# ARTICLE VI -- OFFICERS
## SECTION 1. POWERS OF THE BOARD OF DIRECTORS
The board shall regulate and supervise the management and operation of the Chesapeake MSBL. It shall attend to all internal affairs of the Chesapeake MSBL and shall make such arrangements for conducting the business as it deems best. In addition to the power by these by-laws expressly conferred upon the board of directors, it may exercise all the powers of the corporation and all such lawful acts and things as are not by statute or by the charter or by these by-laws required to be done or exercised by the members.
## SECTION 2. DUTIES OF THE BOARD OF DIRECTORS
The duties and powers of the board of directors shall be such as usually devolve upon the directors of any club or association and may include the selection of the place, fixing the date, and making all arrangements necessary for holding meetings of the Chesapeake MSBL and the publication of whatever data the directors deem essential to the benefit of the Chesapeake MSBL. The directors shall have the power to adopt rules and regulations, and to alter and amend the same from time to time, for the conduct of the business and activities of the Chesapeake MSBL. The board of directors shall have the authority to generally conduct the business and activities of the Chesapeake MSBL.  The board of directors shall have the authority to generally conduct all of the lawful affairs of the Chesapeake MSBL, including but not limited to, entering into any contracts, leases, or other agreements necessary to carry out the purposes of the Chesapeake MSBL. The directors shall exercise all the power of the Chesapeake MSBL as permitted by law, subject to the provision of the Articles of Incorporation and these by-laws.
## SECTION 3. COMMITTEES OF THE BOARD OF DIRECTORS
The board of directors shall also have the authority to establish committees as may be necessary to further and promote the interests and activities of the Chesapeake MSBL. Such committees may be comprised of both directors and other active members.
## SECTION 4. PRESIDENT
The president shall preside at all meetings of the membership and of the board of directors, shall perform such other duties as may be determined by the board of directors, and shall perform and discharge such other duties as generally devolve upon a chief executive officer.
## SECTION 5. VICE-PRESIDENT
The vice-president shall perform all duties incumbent upon the president during the absence or disability of the president and perform such other duties as may be prescribed by the board of directors.
## SECTION 6. SECRETARY
The Secretary shall have the custody and care of the corporate records of the Chesapeake MSBL, shall attend all meetings of the members and of the board of directors, shall keep a true and complete record of the proceedings of all such meetings, shall file and take charge of all papers and documents belonging to the Chesapeake MSBL, and shall perform such duties as may be prescribed by the board of directors.
## SECTION 7. TREASURER
The treasurer shall keep or, at the discretion of the board cause to be kept, correct and complete records showing accurately at all times the financial condition of Chesapeake MSBL; shall be legal custodian of all monies and other valuables which may from time to time come into the possession of the Chesapeake MSBL; shall maintain a bank account in the name of Chesapeake MSBL; shall prepare and file or, at the discretion of the board, cause to be prepared and filed, all required corporation tax forms and reports; shall furnish at meetings of the board of directors and membership or whenever requested by the board of directors, a statement of the financial condition of the Chesapeake MSBL; shall maintain or, at the discretion of the board, cause to be maintained a roster of active members in good standing; and shall perform such other duties as the board of directors may prescribe.
## SECTION 8. DIVISION REPRESENTATIVE
The division rep shall perform all duties assigned to them by the board of directors. They will serve as a liaison with the Board of Directors to express the wants and needs of each specific division.  They serve to conduct internal voting on topics pertaining to potential changes within their respective divisions and report results to the BOD for review and/or change approval.  Each age division will have one vote if required during league wide operations such as budget, capital expenditures, rules, etc. 
If additional age divisions are created due to league reorganization or expansion in the future requiring an increase in representatives, the President and/or BOD retain the ability to nominate, assign and/or appoint additional board members to preserve the original voting integrity and balance intended for voting purposes.
## SECTION 9. TRANSFER OF DUTIES
In case of the absence of any officer of the Chesapeake MSBL, or for any other reason that the board of directors may deem sufficient, the board of directors may delegate the powers or duties of such officer to any other director, for the time being, provided a majority of the board of directors concurs therein.
# ARTICLE VII -- ACCOUNTING, BUDGET AND CONTRACTS
## SECTION 1. CONTRACTS, CHECKS, NOTES, ETC.
All contracts and agreements authorized by the board of directors shall, unless otherwise directed by the board of directors, be signed by the president, or such other person as may be from time to time so authorized by the board of directors. All checks and drafts issued by the Chesapeake MSBL in the amount of five hundred dollars ($500.00) or more, will require two signatures and shall be signed by the president or treasurer, or such other person as may be from time to time authorized by the board of directors. Any check written for more than $7,500 shall require the vote of approval of a majority of the board of directors and must be signed by the president and treasurer.
## SECTION 2. AUDITS
a. Annual Audits -- The books of the corporation shall be closed on the last day of December of each year. Within 45 days of the end of each calendar year, the Executive Committee will audit the books. The audit shall encompass all assets of or under the control of the Chesapeake MSBL, with property valued at cost, depreciated value, or replacement cost, whichever is least. Separate "funds" shall have a separate accounting with the net gain or loss shown in the consolidated statement.
b. Special Audits -- An audit similar to the annual audit shall be prepared at any time the positions of president or treasurer are vacated before the end of their terms.
## SECTION 3. BUDGET
A budget for the next fiscal year shall be prepared by the president and treasurer for presentation and approval of the board. The board shall present the approved budget for information to the membership.
## SECTION 4. APPROVAL OF CONTRACTS
Contracts for coaching or administrative services shall require approval of two-thirds (2/3) of the board of directors. Contracts involving loans, leases, or other obligations of more than twelve (12) months shall require unanimous approval of the board of directors.
# ARTICLE VIII -- NON-PROFIT ORGANIZATION
## SECTION 1. COMPENSATION
The Chesapeake MSBL shall, at all times, be operated on a non-profit basis for the mutual benefit of its members. No dividends or other interests in the assets of the Chesapeake MSBL shall be paid by the Chesapeake MSBL to its members. No part of the earnings of the Chesapeake MSBL shall inure to the benefit of, or be distributed to, its members, officers, directors, or any other private persons, except that the Chesapeake MSBL shall be authorized and empowered to pay reasonable compensation for services rendered and expenses incurred and to make payments and distributions in full furtherance of the purposes set forth herein.
## SECTION 2. TAX-EXEMPT STATUS
No substantial part of the activities of the Chesapeake MSBL shall be the carrying on of propaganda or other attempts to influence legislation, and the Chesapeake MSBL shall not participate in any political campaign on behalf of any candidate for public office. Notwithstanding any other provision of the Articles of Incorporation or these by-laws, the Chesapeake MSBL shall refrain from engaging in any other activities not permitted of any tax-exempt organization under Section 501 of the Internal Revenue Code.
# ARTICLE IX -- BY-LAWS, RULES OF ORDER, AND INDEMNIFICATION OF DIRECTORS
## SECTION 1. BY-LAWS
These by-laws succeed any and all previous by-laws and amendments thereto, which are declared null and void.
## SECTION 2. AMENDMENTS
These by-laws may be amended by a majority of the board members present in person at any regular or special meeting provided that the proposed amendment has been submitted to the board members not less than (10) days prior to the meeting. In order to be submitted to the membership, the proposed amendment shall have been approved by the board of directors.
## SECTION 3. INTERPRETATION
Any question as to the proper interpretation of these bylaws shall be determined by the board of directors.
## SECTION 4. RULES OF ORDER
Roberts Revised Rules of Order shall be the parliamentary guide for all meetings of members and the board of directors, but shall not take precedence over these by-laws.
## SECTION 5. INDEMNIFICATION
The Chesapeake MSBL shall indemnify and hold harmless any individuals against the expense of any action, suit or proceedings in which they are made a part by reason of being or having been a director, officer or duly authorized agent of the Chesapeake MSBL, except in relation as to matters to which they shall be adjudged in such action, suit or proceedings to be liable for gross negligence or willful misconduct in the performance of their duties. This right shall extend to all such persons, their successors, heirs and legal representatives.
# ARTICLE X -- TERMINATION AND DISSOLUTION
The Chesapeake MSBL may be terminated and dissolved upon the affirmative vote of at least two-thirds (2/3) of all board members entitled to vote. In the event of such termination, the board of directors shall, after paying or making provision for the payment of all liabilities of Chesapeake MSBL, disburse any remaining assets to a non-profit organization or organizations.  A majority of the Board of Directors shall determine these organizations.
# ARTICLE XI--CHESAPEAKE MSBL ALL STAR TEAMS
## SECTION 1. ELIGIBILITY CRITERIA
a. The Player must be on the final roster of the team which he is representing and the player must be affiliated and in good standing with the Chesapeake MSBL.
b. The Player must have participated in at least 50% of the games played with the team he is representing in the Chesapeake MSBL.
## SECTION 2. SELECTION PROCESS
a. The Chesapeake MSBL All-Star Game Managers shall meet the same criteria as Article XI, Section 1.
b. The Chesapeake MSBL All-Star Game Managers shall be the Managers of teams who played in the previous season play-off Championship Game that meet Eligibility Criteria under Article XI, Section1. All Chesapeake MSBL Team Managers are encouraged and invited to participate in the event as base coaches, bench coaches, score keepers, etc.
c. A Chesapeake MSBL All-Star Game Selection Committee shall convene under Article 4, Section 2, to select Chesapeake MSBL All-Star Team roster(s) of not more than twenty-eight (28) players to represent the Chesapeake MSBL League in the All-Star game for a particular division.
d. If the Chesapeake MSBL All-Star Game Managers are not selected by the Chesapeake MSBL All-Star Game Committee, they are not eligible to participate in the game as a player in any capacity.
## SECTION 3. PARTICIPATION
a. A player representative meeting the criteria in Article XI, Section 1, from each Chesapeake MSBL League team in good standing will have representation on the Chesapeake MSBL All-Star Team.
b. If selected for the Chesapeake MSBL All-Star Team, the player may be required to pay a participation fee to offset expenses associated with the operation of the All-Star Game to the Chesapeake MSBL President or Treasurer ten (10) days before the scheduled All-Star Game.  Failure to provide payment by the deadline will result in forfeiture of participation and the next leading vote getter for the position vacated will be invited to fill the spot (provided the substitute player submits the participation fee).
c. Each player selected to represent the Chesapeake MSBL All-Star Team shall get at least one at-bat (AB) or one inning playing in the field. It is the responsibility of the Chesapeake MSBL All-Star Team Managers to ensure every player representing the Chesapeake MSBL participates in the All-Star Game.
# ARTICLE XII -- POST SEASON AWARDS
## SECTION 1. ELIGIBILITY CRITERIA
a. The Manager/Player must be on the final roster of the Team which he is representing and the Manager/Player and Team must be affiliated and in good standing with the Chesapeake MSBL League.
b. The Player must have participated in at least 50% of the games played by the team he is representing in the Chesapeake MSBL League.
c. Umpires who have umpired at least ten (10) County Adult and/or Chesapeake MSBL Baseball Games are eligible for Chesapeake MSBL League Recognition.
d. Post Season Award Ceremony will take place as a General Membership Meeting upon conclusion of the baseball season at a date, time and location to be determined by the Chesapeake MSBL Executive Committee and Board of Directors.
## SECTION 2. AWARD CATEGORIES
 - At a minimum, Post-Season Awards will be established for the following categories for each Chesapeake MSBL Division (except Outstanding Umpire Award) and may be presented if such awards are deserved or warranted as determined by the Chesapeake MSBL Awards Committee:
a. Sportsmanship Award: Recognition of player and/or manager who consistently exhibits good sportsmanship and respect towards teammates, opponents, umpires, spectators, and representatives of the Anne Arundel County Department of Parks & Recreation before, after, and during competition. Players may be nominated by anyone in the league, including umpires, or other representatives of the Anne Arundel County Department of Parks & Recreation.
b. Chesapeake MSBL Service Award: Recognition of a Manager, Player, Umpire, Sponsor or other person who has volunteered significant time or made a significant contribution to improve the quality and visibility of the Chesapeake MSBL to the Community.
c. Outstanding Umpire Award: Recognition of one Umpire meeting the eligibility requirements in Article XII, Section 1, who receives the highest scores among Chesapeake MSBL Team feedback in areas of Umpiring Consistency, Game Control, Hustle, Attitude, and Respect towards Managers, Players, and Spectators.
## SECTION 3. SELECTION PROCESS
 - A Chesapeake MSBL Awards Committee, lead by the Chesapeake MSBL Executive Committee and Board of Directors, shall convene under Article 4, Section 2, to nominate and select category winners for Post-Season Awards.
a. Nominations for Sportsmanship Award candidates should be presented to the Chesapeake MSBL Post-Season Award Committee with written a recommendation for the person nominated with specific documented instances in which good sportsmanship was exhibited by the candidate. Only one person from each Division of the Chesapeake MSBL may receive this award.
b. Nominations for the Chesapeake MSBL Service Award candidates shall be presented to the Chesapeake MSBL Post-Season Award Committee with written a recommendation for the person nominated with specific documented instances in which he or she has made volunteered significant time or made a significant contribution to improve the quality and visibility of the Chesapeake MSBL to the Community. Only one person from each Division of the Chesapeake MSBL may receive this award.
c. Outstanding Umpires Award will be determined based on post-game feedback forms from team managers or representatives based upon Umpiring Consistency, Game Control, Hustle, Attitude, and Respect towards Managers, Players, and Spectators. Only one umpire may receive this award.
# ARTICLE XIII -- CHESAPEAKE MSBL HALL OF FAME
****Selection procedures for the CMSBL HOF was changed on January 24, 2023.  A new proposal was submitted and approved by unanimous BOD vote****
## SECTION 1. ELIGIBILITY CRITERIA
a. Any Current Player, Manager, Umpire or League Sponsor who is currently affiliated and in good standing with the Chesapeake MSBL who has participated in the Chesapeake MSBL for ten (10) or more years and consistently demonstrates good sportsmanship, character and respect towards teammates, opponents, and umpires; competitive skill; and, provides unselfish devotion to the continuing improvement to the quality and experience of Amateur Adult Baseball within the Chesapeake MSBL and the community at large.
## SECTION 2. NOMINATION PROCESS
a. Former and Current Players, Managers, Umpires, or League Sponsors may be nominated by any member or organization affiliated with the Chesapeake MSBL. (See section 1.a)
b. Nominations should be submitted to the Chesapeake MSBL Hall-Of-Fame Chairman and the Executive Committee in writing describing the qualifications that warrant consideration for induction into the Chesapeake MSBL Hall of Fame. The nomination must include the name, team, primary position played, years affiliated with Chesapeake MSBL, stats (if available), accomplishments and other additional information related to community activities which may assist the Chesapeake MSBL Hall of Fame Selection Committee in reaching a decision for induction.
c. Nominations for annual induction must be submitted to the Chesapeake MSBL Executive Committee prior to July 1st for Chesapeake MSBL Hall of Fame induction consideration. This will allow the presentation of a HOF plaque to inductees on the field prior to the conclusion of the season. Each inductee will also receive a credit for a Chesapeake Hall of Fame Ring of their choosing. See Section 4.f.
## SECTION 3. SELECTION PROCESS
a. The Chesapeake MSBL Executive Committee and Board of Directors will select a Hall of Fame Chairman to convene Chesapeake MSBL Hall of Fame Selection Committee under Article 4, Section 2.
b. The CMSBL HOF Selection Committee will be selected by the HOF Chairman in conjunction with the Board of directors. It will be made up of 5 members, preferably at least 1 member from each age group, if possible.
## SECTION 4. Hall of Fame Selection Process**
a. In order for a member to be inducted into the Chesapeake MSBL Hall of Fame, the Chesapeake MSBL Hall of Fame Committee will conduct an in-person meeting to discuss the nomination and weigh each candidate's merits and to ensure there is a complete understanding of the metrics of the league scoring parameters. (Addendum A) After discussions have concluded the committee will proceed with a transparent vote on each nominee rating them on the enclosed scale for their accomplishments. Note: If a member of the Hall of Fame Committee cannot attend the vote meeting, a member of the Board of Directors will substitute and vote in their place.
b. Voting Score: Votes will be tabulated by the Chesapeake MSBL secretary and results will be revealed to the committee upon completion. Nominees, who achieve a minimum of 70% of the points (350 points) required for induction, as counted by the Secretary, will be inducted as members into the Chesapeake MSBL Hall of Fame.
c. Candidate Re-Review process: Any Candidate who receives a score between 60- 69% will be discussed and then a second vote will be conducted to ensure there is a proper understanding and review of the grading.
d. To ensure the credibility and integrity of the Chesapeake MSBL Hall of Fame is not compromised, marginalized, or undermined, no more than three (3) persons shall be inducted into the Chesapeake MSBL Hall of Fame in any given year unless it is determined by the HOF chairman that there are additional worthy candidates warranting consideration.
e. Special Circumstances exception appointment. The current League President, Board of Directors, and/or Hall of Fame Committee may induct a new Hall of Fame member without the normal nomination/voting process.  This could be an umpire, league sponsor, historical player, critically ill person, or post mortem of a former player/official that embodies the qualities and qualifications to warrant induction.
f. There is no annual minimum selection requirement for the Chesapeake MSBL Hall of Fame induction.
g. Expenses- League will provide a $300.00 stipend for the Hall of Fame Ring. Inductees are to contact Brian Sands at Recognition Concepts. sands@recognitionconcepts.com for sizing and  additional costs depending on the type of ring chosen.
Addendum A: Metrics for HOF Induction
1. Criteria
   1.    Playing ability 15%
   2.    Character 20%
   3.    Service to league 30%
   4.    Service to community 35%
Each Attribute for admission is assigned a Maximum point value 15, 20, 30, & 35 = 100 points
Define and examples of each.
   1.    (15 points) Playing Ability: Rate player in comparison to the best players in the league during their tenure. Self explanatory.
   2.    (20 points) Character: How do other players/ people in the league refer to said player? Is he well respected and do others think highly of them? Is he a respected team leader? What is the one word that best describes his character as a person?
3.    (30 points) Service to the League: What has he done to benefit the league other than playing. Does he volunteer, or donate time? Does he participate in before and after team field activities on a regular basis? Does he go above and beyond just playing to make the league better? Do they work only for their team or the rest of the league? Do they hold a league position or volunteer to run specific league events? (Such as the league draft or HOF voting etc) Example: Managing a team is 5 points maximum.
   4.    (35 points) Service to the Community: We are looking for things where the nominee does acts to benefit others rather than for himself/herself, team or family. What does the player do to benefit the community? Do they volunteer their time to baseball and or other athletic/community organizations or projects? Example: Coaching your own child is 5 points. Being compensated in a paid coaching position also would count no more than 5 points.
# ARTICLE XIV-- MISCELLANEOUS
## SECTION 1. NOTIFICATION OF MEETINGS
a. Notification Method -- Notification of meetings shall be made in writing via e-mail, phone, mail correspondence, or via notification on Chesapeake MSBL Website League News or Message Board.
b. Contact Information -- Board members are required to provide contact information to Chesapeake MSBL. Failure to do so would constitute a waiver of right to receive notice of any meetings.
## SECTION 2. GOVERNANCE
a. These bylaws are governed by the applicable laws of the State of Maryland.  The foregoing was adopted this 30th day of January, 2018, to be the Bylaws for Chesapeake Men's Senior Baseball League, Inc.
By (Signatures on File in Corporate Records):
**Alex Brunet, Chairman  **
**Michael Largent, Vice-President**
**Joe DiMonda, Secretary**
**Wayne Vance, Treasurer **
**Danny Tyler, Director-Field Maintenance**
**Ron Ebelein, Division Representative (45+)**
**Tom Finch, Division Representative (45+)**
**Jeff Wolf, Division Representative (35+)**
**Tim Biggs, Division Representative (21+)**
**Alan Kietz, Division Representative (21+)**

View File

@@ -0,0 +1,95 @@
Lockport Church Dartball League
*Amended April 2011, August 2013, August 2014
Bi-laws
# Article I: Dartboard and Dart Information
## Section 1: Dartboard Regulations
The fundamental dartboard is a square piece of 1/4” thick dense fiberboard measuring 48” by 48”. To provide rigidity, this board requires backer plywood to be either glued or stapled to its back. The bottom of the board should be positioned 24” from the floor, placing the boards center at 48” from the floor. The board is printed with seven distinct bright colors and displays various elements of a baseball game, including first base, second base, third base, home run, strike, ball, out, foul, double play, and sacrifice hit. The board is wired, allowing players to determine how to score their darts. Wires are run between each distinct spot on the board. For instance, if a dart lands precisely between the first base box and the out, the player can determine whether it should be scored as a hit or an out by observing which side of the wire the dart has landed on. These wires effectively act as the umpire. Host teams have the option of using the “tilt board setup method,” which is popular among other dartball leagues.
## Section 2: Pitching Line
The pitching of the darts shall be 20' from the base of the board to front edge of pitching line. The preferred pitching line shall be 6 long and 2" wide directly in front of board and adhered to the floor. The batters foot may be on the pitching line up to the very front edge without penalty. If he oversteps the line, a warning should be issued by any player. Continued overstepping the line will result in the batter being called out.
## Section 3: Dartboard Information
These boards are available through the league or from the supplier, Davis manufacturing at www.dartballusa.com
## Section 4: Dart Information
All darts must be thrown underhand. Apex #2 three feathered darts are the only darts approved for play. Loading or modifications of darts is prohibited.
# Article II: Playing Regulations
## Section 1: John Doe
A. Regular Season
A team is required to have seven players as the minimum during the regular season, with no maximum amount of players. If a team does not have seven players, John Doe [s] must be added to bring the team to the required minimum of seven players. No more than four John Does are recommended, but the teanm captain can decide either to play or forfeit the evening's games if they have less than four players. Each John Doe counts as an out as it comes up in the batting order. Women will be allowed to play in place of a John Doe if a team is short but only during regular season games. John Doe[s] can be present anywhere in the batting order. When a late player arrives, his name can be inserted in place of a John Doe or at the end of the line up. Lineups may be changed at the beginning of each game. Any team may postpone or reschedule a game night as long as it is agreeable between both captains and every effort is made to make up the games in the same half as the occurrence.
B. Postseason (Bezold and Championship Games)
Same rules apply from the Regular Season except a team must have a minimum of eight players.
C. Tournament
Same rules apply from the Regular Season except a team must have a minimum of nine players.
## Section 2: Batting out of Turn
Any player batting out of turn (A dart must be thrown] will be called out. Any hit or subsequent runs do not count. Any skipped batter can then continue with his turn. The out of turn batter then loses his next turn with no penalty whether it is in the same inning or the next.
## Section 3: Throwing Darts
Any darts sticking for 3 seconds or more is considered a live dart. Umpires must call out each dart's disposition and keep the thrower aware of his count [balls and strikes]. Darts will be used to indicate base runners and placed on the board near the represented base. The batter is automatically out if the dart fails to hit the board or hits any other object in flight before hitting the board. Dropping of darts at the throwing line is not considered a penalty. If a dart falls to the floor immediately [or within 3 seconds] after striking the board It shall be ruled a dead dart with no penalty to the thrower. If a dart is thrown into a board in such a way that the wire dividers cannot be used to determine the call, then the dart shall be considered a dead dart with no penalty to the thrower. If a thrown dart sticks into the body of another dart already in the board, the last thrown dart shall be ruled a dead dart with no penalty to the thrower. Darts shall be removed from the board only when the thrower completes his time at bat. The dart shaft must be completely encircled by green board to be considered a foul ball, otherwise it is a "woody". If a dart hits any board mounting hardware, and fails to stick, it's considered a dead dart unless there is no question as to its determination.
A. Center Strike Rule
If a player is batting .199 or less they are allowed to have the center strike area around the 2BS considered as a single. Batters must have played two weeks in the season and captains must have current stats.
## Section 4: Running the Bases
All runners shall advance one base on a single, two bases on a double, three bases on a triple and four bases on a home run. On a two-base single (2BS), all runners advance two bases and the batter goes to first base. On a double play (DP), the batter is out as well as the lead runner. Remaining runner/runners advance one base. On a sacrifice hit (SH), all runners advance one base including any runner on third. If no one is on base, both the DP and SH are just a strike. The batter is out for computing batting averages. A walk is considered a hit for computing batting averages. If the walk forces a run to be scored the RBI counts for season statistics. 2BS, SH and Walks should be recorded as described to insure that RBI's are appropriately computed.
# Article III: Governance
## Section 1: Umpiring
In league play, each captain will designate a player from their team to serve as an umpire. These umpires shall make all decisions. It is recommended that the non batting team umpire call or announce the play but this is not enforced as long as the two umpires are in agreement. In the case of a dispute, the umpires may call upon the captains to make a determination on the call. If no agreement is made the said dart will be ruled a dead dart with no penalty to the thrower. In league play, each team shall provide an umpire, score marker and a pitching line judge. The pitching line judge and the umpire can be the same person. Teams must announce if a separate line judge is being used and only he can call a player out for overstepping the line. This is only to be used after warnings have not corrected the batters overstepping of the line. Under no circumstances shall one umpire remove darts from the board before the other umpire has had a chance to verify the location of the darts.
Calling of [ it doesn't matter darts ] All darts regardless of immediate impact will be called. In an effort to speed up play, the side umpire nearest will call the close dart and leave it available for inspection after the play.
## Section 2: End of the Year Awards
The minimum number of at bats to qualify for any trophy is 150.
A. MVP
The most valuable player will be selected by ballot. Each team will select its most valuable player with the names turned into the statistician the last night of regular season play. At the single elimination tournament each team will be given a ballot with all teams' selection for MVP except that of their own player. It is the captain's responsibility to have his men to vote for MVP of each members choosing. The ballots will be returned to the league statistician and another officer. The ballots should be counted by individuals who are not on the ballot. The MVP will be announced at the banquet.
B. Rookie of the year:
A rookie is defined as his first year in any dartball league. If rookie has less than 75 at bats he is considered a fill in player and not considered for Rookie of the year. To be considered, the batter must have at least 150 at bats with no more than 75 at bats for the previous season. Rookie of the year will be selected by ballot along side and in the same manner as the MVP. A team may vote for their own teammate.
## Section 3: Dues
The annual team dues are payable at the captains meeting at the beginning of the season or make arrangements with the Treasurer to pay the dues. The officers and league board will determine the amount due. Currently at time of revision this amount per team is $50. All team players with the exception of 1s timers must contribute $1 to the host church every night that a game is played including postseason.
## Section 4: Manners
Profanity and alcoholic beverages on church property is not acceptable. If after warnings this rule is not followed, the host church captain has every right to ask them to leave and they will have the full support of the officers and league board. If a team and or any of their team members are consuming alcohol on church property, the team will forfeit all 3 games.
## Section 5: Officer Duties
The Treasurer is responsible for all dues, collection for supplies and sponsor donations to be deposited in league account for audit and review at any time by the officers and league board. All bills for needed equipment and supplies including the banquet must be paid for from the league account and subject for review at anytime. Treasurer must retain checks and statements for 84 Months and subject for review at any time. All funds collected for league use [banquet, sponsors, dues, ect ] will be given to treasurer directly.
## Section 6: Postseason Play
The team captains will flip a coin to determine who will have home field advantage for all postseason play (1s and 2nd half Bezold, Championship and Tournament games).
A. Bezold playoff guidelines:
The 1s Half Bezold is to be played between the 1$ and 2n place team at the mid-season break. The 2nd Half Bezold is to be played between the 1st and 2nd place teams at season end. If the winner of the first half Bezold is the 1t or 2nd place team then the 3e place team will play. No one team can win both Bezold trophies. The team that wins the best of three games wins the Bezold. For the Bezold games, each team must have a minimum of eight players.
B. Championship Playoff Guidelines:
The championship game will be played between the team with the best 1st half record and the team with the best 2nd half record. If a team has the best record for both halves, then they will be named the League Champion. For the Championship game, each team must have a minimum of eight players.
C. Tournament Guidelines:
The tournament will be played by all teams. Teams ill be randomly drawn in order to determine matchups. There is also a consolation bracket for teams that lose their 1 game. Each team must have a minimum of nine players.
## Section 7: Tie Breakers
In the event we have ties between teams based on their league won/lost records, the tie breaker will be based on heads up play between the two or more said teams. If still no clear winner then total runs for that half. If that continues a tie then Highest total team batting average based on all players that have participated. In the highly unlikely event that this ends in a tie we will base the tiebreaker on total triples for the half.
## Section 8: Captains Meeting Protocol
Topics can be introduced and reviewed as normal business. Motions must be announced prior to any voting. A second to the motion must be announced or the motion will not be considered. After the second to the motion, each captain and officers allowed to present opinions and ask questions to the person originating the motion. The secretary will take roll call and include in the minutes of all attending the meeting. A majority is required to pass a motion.
## Section 9: Minimum Age
There is no minimum age.
## Section 10: Other
No one is to pass behind the board while play is happening.

View File

@@ -0,0 +1,375 @@
# CONSTITUTION:
# Little League
> **Date submitted:** [PLACEHOLDER]
> **Date accepted:** [PLACEHOLDER] **Not accepted:**
> [PLACEHOLDER]
## ARTICLE I -- NAME
> This organization shall be known as the [PLACEHOLDER] Little League, hereinafter referred to as "Local League."
## ARTICLE II -- OBJECTIVE
### SECTION 1
The objective of the Local League shall be to positively impact youth and communities using the power of youth baseball and/or softball to teach life lessons to build stronger individuals and communities.
### SECTION 2
To achieve this objective, the Local League will provide a supervised program of baseball and/or softball consistent with the Rules and Regulations of Little League Baseball, Incorporated. All Directors, Officers and Members shall consider and incorporate the values of Little League: Teamwork, Community, Inclusion, Fun, and Integrity. The molding of future citizens is of prime importance and the attainment of exceptional athletic skill or the winning of games is secondary. In accordance with Section 501(c)(3) of the Federal Internal Revenue Code, the Local League shall operate exclusively as a nonprofit educational organization providing a supervised program of competitive baseball and/or softball games. No part of the net earnings shall benefit any individual or be used in any substantial part to influence legislation or intervene in any political campaign on behalf of any candidate for public office.
## ARTICLE III -- MEMBERSHIP
### SECTION 1
Any person sincerely interested in active participation to further the objective of the Local League may apply to become a Member.
### SECTION 2
There shall be the following classes of Members:
### Regular Members ("Members") shall include: --
a. Current year Managers, Coaches, Board Members, Local League Officers, and any registered volunteer, who have completed a background check.
b. One Parent or one Legal Guardian of each registered player. Parents or Guardians of multiple registered players are limited to a maximum of two memberships.
c. Any adult person actively interested in furthering the objectives of the Local League may become a Regular Member upon approval by the Board and payment if applicable. Upon receipt of a written request to become a member, the Board of Directors shall vote upon the request at the next scheduled Board of Directors meeting.
d. All Members must annually complete the Little League Official Application, submit to a background check pursuant to Regulation I(8) and (9), and complete abuse awareness training pursuant to Regulation I(10) before the commencement of the season.
e. The Secretary shall maintain the roll of membership to qualify voting Members. Only Members in good standing are eligible to vote at General Membership Meetings. Each Member is entitled to one vote.
<!-- -->
2. **Player Members** - Any player candidate meeting the requirements of Little League Regulation IV shall be eligible to compete for participation. Player Members shall have no rights, duties, or obligations in the management or in the property of the Local League.
3. **Honorary Members (Optional)** -- Any person may be elected as Honorary Member by the unanimous vote of all Directors present at any duly held meeting of the Board of Directors but shall have no rights, duties, or obligations in the management or in the property of the Local League.
4. **Sustaining Members (Optional)** -- Any person not a Regular Member who makes financial or other contribution to the Local League may by a majority vote of the Board of Directors become a Sustaining Member, but such person shall have no rights, duties, or obligations in the management of or in the property of the Local League.
### SECTION 3
Members, whether Regular or Player, shall not be required to be affiliated with another organization or group to qualify as members of the Local League. Members shall not be actively engaged in the organization, operation and/or leadership of any other baseball and/or softball program.
### SECTION 4
> Dues, if any, for Members may be fixed at such amounts as the Board of Directors shall determine for a particular fiscal year. Dues for Members are separate from registration fees for Player Members, which are determined annually by the Board of Directors in accordance with Little League Regulation XIII (c).
### SECTION 5
> **Suspension or Termination** -- Membership may be terminated by resignation or action of the Board of Directors as follows.
(a) The Board of Directors, by a two-thirds vote of those present at any duly constituted Board meeting, shall have the authority to discipline, suspend or terminate the membership of any Member of any class, including managers, coaches, and other volunteers when the conduct of such person is inconsistent with the values of Little League Baseball, Incorporated and is considered detrimental to the best interests of the players, Local League and/or Little League Baseball, Incorporated. The Member involved shall be notified of such meeting, informed of the general nature of the charges, and be given an opportunity to appear at the meeting to answer such charges.
(b) The Board of Directors shall, in case of a Player Member, give notice to the Manager of the team for which the player is a Player Member. Said Manager shall appear, in the capacity of an adviser, with the player before the Board of Directors or a duly appointed committee of the Board of Directors. The player's parent(s) or legal guardian(s) may also be present. The Board of Directors shall have full power to suspend or revoke such player's right to future participation in the Local League by two-thirds vote of those present at any duly constituted Board meeting.
(c) If membership dues are collected, Members who fail to pay their fixed dues may, by a two-thirds vote of the Board present at any duly constituted Board meeting, be dropped from the rolls and shall forfeit all rights and privileges of membership. The Board of Directors will establish the number of days within which applicants have to pay membership dues as part of the annual Policies and Procedures which shall be voted on at the first Board meeting of each fiscal year.
## ARTICLE IV -- BOARD OF DIRECTORS
### SECTION 1
The management of the property and affairs of the Local League shall be vested in the Board of Directors.
### SECTION 2
The Board of Directors shall be comprised of no fewer than seven (7) and no more than fifteen (15) Members in good standing. The Officers of the Board of Directors shall include, at a minimum: President, Vice President, Treasurer, Secretary, Player Agent, Safety Officer, and Coaching Coordinator, per Little League Regulation I(b).
### SECTION 3
If any vacancy occurs on the Board of Directors, by death, resignation or otherwise, it may be filled, for the balance of the absent Board Member's term of office, by a majority vote of the remaining Directors at any duly constituted Board meeting or Special Board Meeting called for that purpose.
### SECTION 4
Regular meetings of the Board of Directors shall be held immediately following the Annual Meeting and, on such days, thereafter as shall be determined by the Board.
(a) The President or Secretary shall at the request in writing of
- [ ] 3 Directors
- [ ] 4 Directors
- [ ] 5 Directors
> Issue the call for a Special Board Meeting. In the case of Special Board Meetings, such notice shall include the purpose of the meeting and only matters so stated in such notice may be acted upon at the Special meeting. Meetings of the Board of Directors may be held in-person and/or by telephonic or electronic means and such means shall be clearly stated in any meeting notice.
(b) Notice of every Board meeting shall be given by the Secretary personally, electronically or by mail to each Director at a minimum {{Five (5), Ten (10), Fourteen (14), Twenty-one (21), Thirty (30)}} Calendar day(s) before the time appointed for the meeting to the last recorded address of each Director.
(c) At any meeting of the Board of Directors, the presence of {{One-third (33.3 percent), One-fourth (25 percent), One-fifth (20 percent) }} of the Board of Directors shall constitute a quorum for the transaction of regular business. If a quorum is not present, no business shall be conducted.
(d) Only members of the Board of Directors may make motions and vote at meetings of the Board of Directors. However, the Board of Directors may invite, admit, and recognize guests for presentations or comments during Board meetings.
(e) A simple majority vote of the Directors present during a duly constituted Board of Directors meeting is necessary to approve any action relating to the general business of the Local league.
(f) No Director shall be allowed to vote by proxy at any meeting of the Board of Directors.
### SECTION 5
The Board of Directors shall have the power to appoint such standing committees as it shall determine appropriate and to delegate such powers to them as the Board shall deem advisable and which it may properly delegate.
The Board may adopt such rules and regulations for the conduct of its meetings and the management of the Local League as it may deem proper, provided such rules and regulations do not conflict with this Constitution or the Rules and Regulations of Little League Baseball, Incorporated.
The Board shall have the power by a two-thirds vote of those present at any regular Board or Special Board Meeting to discipline, suspend or remove any Director, Officer, Committee Member, or Member of the Local League in accordance with the procedure set forth in Article III, Section 5.
### SECTION 6
Robert's Rules of Order shall govern the proceedings of all Local League meetings, including Board of Directors meetings. Any action taken by the Board of Directors at a meeting at which a quorum is present will be deemed the action of the Board of Directors, except where same conflicts with this Constitution. Minutes of all meetings will be recorded and will accurately reflect the action(s) taken.
## ARTICLE V -- DUTIES AND POWERS OF THE BOARD
### SECTION 1
The Board of Directors may appoint such other officers or agents as it may deem necessary or desirable and may prescribe the powers and duties of each. Appointed officers or agents shall have no vote on actions taken by the Board of Directors unless such individuals have been elected to the Board by the membership or have been elected to fill a vacancy on the Board.
### SECTION 2
> **President** -- The President shall:
(a) Conduct the affairs of the Local League and execute the policies established by the Board of Directors.
(b) Present a report of the condition of the Local League at the Annual Meeting.
(c) Communicate to the Board of Directors such matters as deemed appropriate and make such suggestions as may tend to promote the welfare of the Local League.
(d) Be responsible for the conduct of the Local League in strict conformity to the policies, principles, and Rules and Regulations of Little League Baseball, Incorporated, as agreed to under the conditions of charter issued to the Local League by that organization.
(e) Investigate complaints, irregularities, and conditions detrimental to the Local League and report thereon to the Board or Executive Committee as circumstances warrant.
(f) Prepare and submit an annual budget to the Board of Directors and be responsible for the proper execution thereof.
(g) With the assistance of the Player Agent, examine the application and support proof-of age documents of every player candidate and
(h) certify to residence or school enrollment, and age eligibility before the player may be accepted for tryouts and selection.
(i) Complete the required background checks per Little League Regulation I (b) and I (c) 8 & 9; or delegate this responsibility to the league Safety Officer, or other designated Board member.
(j) Ensure that all individuals who submit the Volunteer Application complete the Abuse Awareness Training as outlined in the Little League Child Protection Program or delegate this responsibility to the league Safety Officer, or other designated Board member.
(k) Ensure the Local League compliance with the requirements of the Little League Child Protection Program or delegate this responsibility to the league Safety Officer, or other designated Board Member.
### SECTION 3
> **Vice President** -- The Vice President shall:
(a) Perform the duties of the President in the absence or disability of the President, provided he or she is authorized by the President or Board to so act. When so acting, the Vice President shall have all the powers of that office.
(b) Perform such duties as from time to time may be assigned by the Board of Directors or by the President.
### SECTION 4
> **Secretary** -- The Secretary shall:
(a) Be responsible for recording the activities of the Local League and maintain appropriate files, mailing lists, email lists and necessary records.
(b) Perform such duties as are herein specifically set forth, in addition to such other duties as are customarily incident to the office of Secretary or as may be assigned by the Board of Directors.
(c) Maintain a list of all Regular, Sustaining and Honorary Members, Directors and Committee Members and give notice of all meetings of the Local League, the Board of Directors, and Committees.
(d) Maintain a current list of all Regular Members in good standing and determine the number of Regular
> Members needed to constitute a quorum.
(e) Issue membership cards to Regular Members, if approved by the Board of Directors.
(f) Keep the minutes of the meetings of the Members, the Board of Directors, and the Executive Committee, and cause them to be recorded in a book kept for that purpose.
(g) Conduct all correspondence not otherwise specifically delegated in connection with said meeting and shall be responsible for carrying out all orders, votes and resolutions not otherwise committed.
(h) Notify Members, Directors, Officers and Committee Members of their election or appointment. Provide each of these individuals with a copy of the Local League Constitution.
### SECTION 5
> **Treasurer** -- The Treasurer shall:
(a) Perform such duties as are herein set forth and such other duties as are customarily incident to the Office of Treasurer or may be assigned by the Board of Directors.
(b) Receive all moneys and securities, and deposit same in a depository approved by the Board of Directors.
(c) Keep records for the receipt and disbursement of all moneys and securities of the Local League, including the Auxiliary, approve all payments from allotted funds and draw checks therefore in agreement with policies established in advance of such actions by the Board of Directors. All disbursements by check must have dual signatures.
(d) Prepare an annual budget, under the direction of the President, for submission to the Board of Directors at the Annual Meeting.
(e) Prepare an annual financial report, under the direction of the President, for submission to the Membership and Board of Directors at the Annual Meeting, and to Little League International.
### SECTION 6
> **Player Agent** -- The Player Agent shall:
(a) Record all player transactions and maintain an accurate and up-to-date record thereof.
(b) Receive and review applications for player candidates and assist the President in verifying residence or school enrollment and age eligibility.
(c) Conduct tryouts, player draft, and all other player transactions or selection meetings.
(d) Prepare the Player Agent's list.
(e) Prepare for the President's signature and submission to Little League Baseball, Incorporated team rosters, including players claimed, and the tournament team eligibility affidavit.
(f) Notify Little League Baseball, Incorporated of any subsequent player replacements or trades.
### SECTION 7
> **Safety Officer** -- The Safety Officer shall:
(a) Be responsible to create awareness, through education and information, of the opportunities to provide a safer environment for Players and all participants of Little League.
(b) Develop and implement a plan for increasing safety of activities, equipment and facilities through education, compliance and reporting which may include:
1. Education -- Facilitate meetings and distribute information among participants including players, managers, coaches, umpires, league officials, parents, guardians, and other volunteers.
2. Compliance -- Promote safety compliance leadership by increasing awareness of the safety opportunities that arise from these responsibilities.
3. Reporting -- Define a process to assure that incidents are recorded, information is sent to league/district and national offices, and follow-up information on medical and other data is forwarded as available.
4. Background Checks - If the League President so designates, the Safety Officer will complete the required background checks per Little League Regulation I(b) and I(c)(8) & (9).
5. Training -- If the League President so designates, the Safety Officer shall ensure that all individuals who submit the Volunteer Application complete the Abuse Awareness Training per Little League Regulation I(c)10 and as outlined in the Little League Child Protection Program.
6. Child Protection Program -- If the League President so designates, the Safety Officer will ensure the league is compliant with all aspects of the Little League Child Protection Program.
### SECTION 8
Additional Managers and Committees may be established by the Board of Directors and may be filled by persons who do not serve on the Board of Directors but report to such. The need for and responsibilities of those positions will be reviewed annually and included in the Local League's Policies and Procedures.
## ARTICLE VI -- COMMITTEES
### SECTION 1
> **Executive Committee**
(a) The Board of Directors may appoint an Executive Committee which shall consist of not less than three (3) nor more than five (5) Directors, one of whom shall be the President of the Local League.
(b) The Executive Committee shall advise with and assist the Officers of the Local League in all matters concerning its interests and the management of its affairs, and shall have such other powers as may be delegated to it by the Board, but in no event will the Executive Committee have authority over the Board of Directors.
(c) At any meeting of the Executive Committee, a majority of the total number of members then in office shall constitute a quorum for the transaction of business, and the act of a majority present at any meeting at which there is a quorum shall be the act of the Committee.
### SECTION 2
The Board of Directors may appoint such Committees as it may deem necessary or desirable and may prescribe the powers and duties of each Committee in Policies and Procedures. Committee Chairs and members of the Committees shall have no vote on actions taken by the Board of Directors unless such individuals have been elected to the Board by the membership or have been elected to fill a vacancy on the Board.
## ARTICLE VII -- GENERAL MEMBERSHIP MEETINGS
### SECTION 1
**Definition** -- A General Membership Meeting is any meeting of the membership of the league which is called in accordance with this Constitution. A minimum of one meeting per year (Annual Meeting, see Section 6) is required. General Membership Meetings may be held in-person and/or by other electronic means which allow for full participation by all Members.
### SECTION 2
**Notice of Meeting** -- Notice of each General Membership Meeting shall be delivered personally, electronically, or by mail to each Member at the last recorded address at least 10 calendar days in advance of the meeting, setting forth the place, time, and purpose of the meeting.
### SECTION 3
**Quorum** -- At any General Membership Meeting, the presence in person or representation by absentee ballot of twenty (20) percent of the Regular Members or forty (40) Regular Members, whichever is less, shall be necessary to constitute a quorum. If a quorum is not present, no business shall be conducted. The Secretary shall be responsible for providing a list of all Regular Members in good standing.
### SECTION 4
**Voting** -- Only Regular Members in good standing shall be entitled to attend, make motions and vote at General Membership Meetings. However, the Board of Directors may invite, admit, and recognize guests for presentations or comments during General Membership Meetings.
### SECTION 5
**Absentee Ballot** -- For the expressed purpose of accommodating a Regular Member in good standing who cannot attend a General Membership Meeting at which new Board members will be elected, an absentee ballot may be requested and obtained from the Secretary of the Local League. The absentee ballot shall be properly completed, signed, and returned in a sealed envelope to the Secretary prior to the date of the election. The Secretary shall present all absentee ballots to the Election Chairman (appointed at the meeting) on the date of the meeting, prior to the voting portion of the election process.
### SECTION 6
> **Annual Meeting of the Members** -- The Annual Meeting of the Members of the Local League shall be held [PLACEHOLDER] (Insert date/time. For example: "The third Wednesday of (month) at 8 p.m.") each year for the purpose of electing the Board of Directors, receiving reports, reviewing the Constitution, appointing committees, and for the transaction of such business as may properly come before the meeting.
(a) The Membership shall receive at the Annual Meeting of the Members of the Local League a report, verified by the President and Treasurer, or a majority of the Directors, showing:
1. The condition of the Local League, to be presented by the President or his/her designee.
2. A general summary of funds received and expended by the Local League for the previous year, the amount of funds currently in possession of the Local League, and the name of the financial institution in which such funds are maintained.
3. The whole amount of real and personal property owned by the Local League, where located, and where and how invested.
4. For the year immediately preceding, the amount and nature of the property acquired, with the date of the report and the manner of the acquisition, the amount applied, appropriated, or expended, and the purposes, objects, or persons to or for which such applications, appropriations or expenditures have been made.
5. The names of the persons who have been admitted to Membership in the Local League during the preceding year.
(b) This report shall be filed with the records of the Local League and entered in the minutes of the proceedings of the Annual Meeting. A copy of such report shall be forwarded to Little League International.
(c) At the Annual Meeting, the Regular Members shall elect the Board of Directors. If the total number of Board candidates exceeds the number of available Board positions, then those Board candidates receiving the most votes will be considered elected to the Board. Regular Members may only cast a number of votes equal to or less than the board positions available. In the event of a tie in the number of votes received by two or more Board candidates for unfilled Board seats, a run-off election, in which all Members may vote, will be held for the tied Board candidates.
(d) After the Board of Directors is elected, the Board shall meet to elect the Officers of the Board.
(e) After the election, the Board of Directors shall assume the performance of its duties on [PLACEHOLDER] \[Insert Month / Day and delete content in brackets.\] The Board's term of office shall continue until its successors are elected and qualified under this section at the next annual meeting.
### SECTION 7
**Special General Membership Meetings** -- Special General Membership Meetings may be called by the Board of Directors, by the Secretary or President at their discretion. Additionally, upon the written request of a minimum of five (5) Members, the President or Secretary shall call a Special General Membership Meeting to consider the subject specified in the request. No business other than that specified in the notice of the Special General Membership Meeting shall be transacted at any Special General Membership Meeting. Such Special General Membership Meeting shall be scheduled to take place not less than (choos, {{Five (5), Ten (10), Fourteen (14), Twenty-one (21), Thirty (30)}} calendar days after the request is received by the President or Secretary.
### SECTION 8
Any vote by the Regular Members at a meeting at which a quorum is present will be deemed the action of the Regular Members, except where same conflicts with this Constitution. Minutes of all meetings will be kept and will accurately reflect the action(s) taken.
## ARTICLE VIII -- AFFILIATION
### SECTION 1
The Local League shall annually apply for a charter from Little League Baseball, Incorporated, and shall do all things necessary to obtain and maintain such charter. The Local League shall devote its entire energies to the activities authorized by such charter, and it shall not be affiliated with any other program or organization or operate any other program.
### SECTION 2
The Official Playing Rules and Regulations as published by Little League Baseball, Incorporated shall be binding on the Local League.
### SECTION 3
The local rules, ground rules and/or bylaws of the Local League shall be adopted by the Board of Directors at a meeting to be held not less than one month before the first scheduled game of the season, but shall in no way conflict with the Rules, Regulations and Policies of Little League Baseball, Incorporated, nor shall they conflict with this Constitution. The local rules, ground rules and/or bylaws of this Local League shall expire at the end of each playing season and are not considered part of this Constitution.
## ARTICLE IX -- FINANCIAL AND ACCOUNTING
### SECTION 1
The Board of Directors shall decide all matters pertaining to the finances of the Local League and it shall place all income including auxiliary funds, in a common league treasury, directing the expenditure of funds in such manner as will give no individual or team an advantage over those in competition with such individual or team.
### SECTION 2
The Board shall not permit the contribution of funds or property to individual teams but shall solicit funds for the common treasury of the Local League, thereby to discourage favoritism among teams and to endeavor to equalize the benefits of the Local League.
### SECTION 3
The Board shall not permit the solicitation of funds in the name of Little League Baseball, Incorporated unless all funds so raised be placed in the Local League treasury.
### SECTION 4
The Board shall not permit the disbursement of Local League funds for other than the conduct of Little League activities in accordance with the Rules, Regulations, and Policies of Little League Baseball, Incorporated. All disbursements shall be made by check, or league credit or debit card. All checks shall be signed by both the Local League Treasurer and such other officer or officers, or person or persons, as the Board of Directors shall determine.
### SECTION 5
No Board member authorized to disburse funds may be the spouse or family relative of the Local League President or Treasurer or have direct access to league funds without the approval of the majority of the Board of Directors with such vote recorded in the minutes. The use of a league credit or debit card is permitted, and the card is returned to the Local League President, Treasurer, or Chairman of the Audit Committee with receipt for all purchases made within three (3) days of the purchase date.
### SECTION 6
No Director, Officer, or Member of the Local League shall receive, directly or indirectly any salary, compensation, or payment from the Local League for services rendered as Director, Officer, or Member.
### SECTION 7
All moneys received, including sponsorship and fundraising, shall be deposited into the financial account of the Local League which must be a federally insured bank or other certified financial intuition as determined by the Board. The establishment of the Local League account or change of account must be noted in the board minutes.
### SECTION 8
###
The fiscal year of the Local League shall begin on (Check one): {{October 1 and shall end on September 30., January 1 and shall end on December 31, Other -- Specify dates: [PLACEHOLDER]}}
### SECTION 9
Upon dissolution of the Local League program for any reason and after all outstanding debts and claims have been satisfied, the Regular Members may either direct the remaining property of the Local League to another chartered Little League program in good standing with Little League Baseball, Incorporated or may direct the funds to Little League Baseball, Incorporated.
## ARTICLE X -- AMENDMENTS
This Constitution may only be amended, repealed, or altered in whole or in part by a majority vote of sixty-six (66) percent of the Members at a duly organized meeting, provided notice of the proposed change is included in the notice of such meeting. A draft of all proposed amendments shall be submitted to Little League Baseball, Incorporated for approval before a vote of the Membership is held.
This Constitution was approved by the Local League Membership on (date)
> [PLACEHOLDER]
President's Name (Printed)
President's Signature
> Little League ID No. [PLACEHOLDER].
> Federal ID No. (if available) [PLACEHOLDER].
> State ID No. (if available) [PLACEHOLDER].
> *Little League Baseball, Incorporated does not limit participation in its activities on the basis of disability, race, creed, color, national origin, gender, sexual preference or religious preference.*

View File

@@ -0,0 +1,39 @@
---
name: local-domain-template
description: Use this skill for project-local domain knowledge that should not be installed system-wide. Replace this description with what the domain is, when the skill should trigger, and what kinds of tasks it should guide.
---
# Local Domain Skill
Replace this template with the domain knowledge you want available only in this repository.
## When To Use
- Use this skill when working on:
- Use this skill when the user asks about:
- Use this skill when decisions depend on:
## Core Rules
- Put the most important domain constraints here.
- Keep these as concrete rules, not general commentary.
- Prefer short bullets over long explanations.
## Workflow
1. Identify the domain-specific question or task.
2. Load only the references needed for that task.
3. Apply the domain rules before making edits or recommendations.
4. Validate the result against the domain constraints.
## References
- Add optional files under `references/` when detailed material is needed.
- Add scripts under `scripts/` when parts of the workflow should be deterministic.
- Add assets under `assets/` only when the skill needs files used in output.
## Notes
- Keep this skill local under `.ai/skills/` so it stays repo-specific.
- Rename the folder and the `name` field to match the real domain.
- Tighten the `description` so the skill triggers only for the intended work.

166
.ai/skills/mkdocs/SKILL.md Normal file
View File

@@ -0,0 +1,166 @@
---
name: mkdocs
description: "Use when creating, configuring, debugging, or customizing MkDocs sites pinned to MkDocs 1.6.1 with Material for MkDocs 9.7.1, including mkdocs.yml, nav, Markdown authoring, theme overrides, plugins, search, deployment, and version-safe upgrades."
---
# MkDocs
## When to use
Use this skill for work on documentation sites that use:
- `mkdocs==1.6.1`
- `mkdocs-material==9.7.1`
Typical tasks:
- create or restructure a docs site
- update `mkdocs.yml`
- fix navigation, links, assets, or Markdown rendering
- enable or tune Material features, plugins, and extensions
- add CSS/JS overrides or theme template overrides
- prepare deployment for GitHub Pages or another static host
## Version guardrails
- Treat `MkDocs 1.6.1` and `Material for MkDocs 9.7.1` as fixed unless the user explicitly asks to upgrade.
- Keep recommendations compatible with those versions.
- If a repo is missing pinned versions, prefer adding explicit pins rather than floating latest versions.
## Procedure
### 1) Inspect the current site shape first
Check:
- `mkdocs.yml`
- `docs/`
- dependency files such as `requirements.txt`, `pyproject.toml`, `uv.lock`, or `poetry.lock`
- any `overrides/`, `docs/stylesheets/`, `docs/javascripts/`, or CI deploy workflow
### 2) Start from the canonical baseline
Prefer this baseline unless the existing site already has an intentional alternative:
```yaml
site_name: Example Docs
site_url: https://example.com/docs/
theme:
name: material
```
Recommendations drawn from the versioned docs:
- Always set `site_url`. Material relies on it for several features, and MkDocs uses it for canonical URLs and path-aware local serving.
- Prefer an explicit `nav` for stable ordering once a site has more than a few pages.
- Keep internal links relative between Markdown files. Avoid absolute doc links.
- Put static assets under `docs/` so MkDocs copies them through unchanged.
- Keep `site/` out of version control.
### 3) Author content the MkDocs way
- Use `index.md` for section landing pages. `README.md` is also supported for index pages, but do not keep both `index.md` and `README.md` in the same directory.
- Prefer shallow, readable navigation over deep nesting.
- If pages are intentionally hidden from global navigation, remember they still build and must still have valid links.
- When fixing broken anchors, verify the generated heading slug rather than guessing.
Primary references:
- `references/upstream/mkdocs-1.6.1-docs/user-guide/writing-your-docs.md`
- `references/upstream/mkdocs-1.6.1-docs/user-guide/configuration.md`
### 4) Customize Material with the lowest-friction tool first
Choose the least invasive option that solves the task:
1. small visual tweaks: `extra_css` and `extra_javascript` under `docs/`
2. theme HTML changes: `theme.custom_dir: overrides`
3. template changes: prefer block overrides with `main.html` and `{{ super() }}` over copying full templates
Recommendations:
- Prefer `docs/stylesheets/extra.css` and `docs/javascripts/extra.js` for minor changes.
- For HTML customization, install Material via package name and set `theme.name: material`; do not fork the theme when `custom_dir` will do.
- When overriding templates, prefer extending `base.html` or overriding blocks instead of replacing whole partials.
- If custom JavaScript must run after client-side navigation, attach it via Material's `document$` observable.
Primary references:
- `references/upstream/mkdocs-material-9.7.1-docs/customization.md`
- `references/upstream/mkdocs-1.6.1-docs/user-guide/customizing-your-theme.md`
- `references/upstream/mkdocs-material-9.7.1-docs/setup/`
### 5) Use Material features intentionally
- Keep `theme.name: material` unless the repo deliberately uses another theme.
- Add only the features actually needed; avoid turning on large feature sets blindly.
- For search, analytics, navigation, blog, tags, privacy, social cards, and versioning, consult the matching Material setup/plugin page before editing config.
- If editing `mkdocs.yml` directly is error-prone, use Material's schema support in the editor.
Primary references:
- `references/upstream/mkdocs-material-9.7.1-docs/creating-your-site.md`
- `references/upstream/mkdocs-material-9.7.1-schema.json`
- `references/upstream/mkdocs-material-9.7.1-docs/setup/`
- `references/upstream/mkdocs-material-9.7.1-docs/plugins/`
- `references/upstream/mkdocs-material-9.7.1-docs/reference/`
### 6) Validate before deployment
Default verification flow:
```bash
mkdocs build --strict
mkdocs serve
```
For large sites, consider:
```bash
mkdocs serve --dirtyreload
```
Deployment guardrails:
- Review the local build before `mkdocs gh-deploy`.
- Do not run `mkdocs gh-deploy` from a dirty working tree unless the deployed output is meant to include those changes.
- For GitHub Pages custom domains, keep `CNAME` in `docs/`.
- For offline or `file://` output, set `site_url: ""`, set `use_directory_urls: false`, and do not rely on the default search plugin.
Primary references:
- `references/upstream/mkdocs-1.6.1-docs/user-guide/deploying-your-docs.md`
- `references/upstream/mkdocs-1.6.1-docs/user-guide/cli.md`
- `references/upstream/mkdocs-material-9.7.1-docs/publishing-your-site.md`
- `references/upstream/mkdocs-material-9.7.1-docs/setup/building-for-offline-usage.md`
## Reference map
Open only the specific files needed:
- core MkDocs usage:
`references/upstream/mkdocs-1.6.1-docs/getting-started.md`
- config:
`references/upstream/mkdocs-1.6.1-docs/user-guide/configuration.md`
- authoring and links:
`references/upstream/mkdocs-1.6.1-docs/user-guide/writing-your-docs.md`
- deployment:
`references/upstream/mkdocs-1.6.1-docs/user-guide/deploying-your-docs.md`
- Material bootstrap:
`references/upstream/mkdocs-material-9.7.1-docs/getting-started.md`
- Material site setup:
`references/upstream/mkdocs-material-9.7.1-docs/creating-your-site.md`
- Material customization:
`references/upstream/mkdocs-material-9.7.1-docs/customization.md`
- Material setup pages:
`references/upstream/mkdocs-material-9.7.1-docs/setup/`
- Material plugin pages:
`references/upstream/mkdocs-material-9.7.1-docs/plugins/`
- Material writing features:
`references/upstream/mkdocs-material-9.7.1-docs/reference/`
For quick discovery inside the bundled docs:
```bash
rg -n "^#|^##" references/upstream/mkdocs-1.6.1-docs references/upstream/mkdocs-material-9.7.1-docs
```

View File

@@ -0,0 +1,7 @@
interface:
display_name: "MkDocs"
short_description: "Work on MkDocs and Material sites"
default_prompt: "Use $mkdocs to create or update this documentation site for MkDocs 1.6.1 and Material for MkDocs 9.7.1."
policy:
allow_implicit_invocation: true

View File

@@ -0,0 +1,21 @@
# MkDocs Skill References
This skill vendors official documentation from the tagged upstream source trees for:
- `mkdocs==1.6.1`
- `mkdocs-material==9.7.1`
Included files:
- `upstream/mkdocs-1.6.1-docs/`
- `upstream/mkdocs-1.6.1-mkdocs.yml`
- `upstream/mkdocs-material-9.7.1-docs/`
- `upstream/mkdocs-material-9.7.1-mkdocs.yml`
- `upstream/mkdocs-material-9.7.1-schema.json`
Source bundles used:
- `https://codeload.github.com/mkdocs/mkdocs/tar.gz/refs/tags/1.6.1`
- `https://codeload.github.com/squidfunk/mkdocs-material/tar.gz/refs/tags/9.7.1`
Use the reference files directly for version-specific details. Keep `SKILL.md` procedural and concise.

View File

@@ -0,0 +1 @@
www.mkdocs.org

View File

@@ -0,0 +1 @@
--8<-- "CONTRIBUTING.md"

View File

@@ -0,0 +1,37 @@
# License
The legal stuff.
---
## Included projects
Themes used under license from the ReadTheDocs projects.
* ReadTheDocs theme - [View license](https://github.com/snide/sphinx_rtd_theme/blob/master/LICENSE).
Many thanks to the authors and contributors of those wonderful projects.
## MkDocs License (BSD)
Copyright © 2014, Tom Christie. All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer. Redistributions in binary form must
reproduce the above copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,89 @@
div.col-md-9 h1:first-of-type {
text-align: center;
font-size: 60px;
font-weight: 300;
}
div.col-md-9>p:first-of-type {
text-align: center;
}
div.col-md-9 p.admonition-title:first-of-type {
text-align: left;
}
div.col-md-9 h1:first-of-type .headerlink {
display: none;
}
div.admonition.block>.admonition-title {
display: none;
}
.admonition.new, details.new {
color: var(--bs-success-text-emphasis);
background-color: var(--bs-success-bg-subtle);
border-color: var(--bs-success-border-subtle);
}
.admonition.example, details.example {
color: var(--bs-info-text-emphasis);
background-color: var(--bs-info-bg-subtle);
border-color: var(--bs-info-border-subtle);
}
/* Definition List styles */
dd {
padding-left: 20px;
}
.card-body svg {
width: 100%;
padding: 0 50px;
height: auto;
}
/* Homepage */
body.homepage>div.container>div.row>div.col-md-3 {
display: none;
}
body.homepage>div.container>div.row>div.col-md-9 {
margin-left: 0;
flex: 0 0 100%;
max-width: 100%;
}
/* mkdocstrings */
.doc-object {
padding-left: 10px;
border-left: 4px solid var(--bs-light-border-subtle);
}
.doc-contents .field-body p:first-of-type {
display: inline;
}
.doc-label-class-attribute,
.doc-label-instance-attribute {
display: none;
}
h2.doc-heading {
font-size: 1.5rem;
}
h3.doc-heading {
font-size: 1.4rem;
}
h4.doc-heading {
font-size: 1.3rem;
}
h5.doc-heading {
font-size: 1.2rem;
}
.doc-contents {
padding-left: 0;
}

View File

@@ -0,0 +1,18 @@
# Developer Guide
Extending MkDocs
---
The MkDocs Developer Guide provides documentation for developers of third
party themes and plugins. Please see the [Contributing Guide] for information
on contributing to MkDocs itself. You can jump directly to a page listed
below, or use the *next* and *previous* buttons in the navigation bar at the
top of the page to move through the documentation in order.
- [Themes](themes.md)
- [Translations](translations.md)
- [Plugins](plugins.md)
- [API Reference](api.md)
[Contributing Guide]: ../about/contributing.md

View File

@@ -0,0 +1,24 @@
# API reference
NOTE: The main entry point to the API is through [Events](plugins.md#events) that are received by plugins. These events' descriptions link back to this page.
::: mkdocs.structure.files.Files
options:
show_root_heading: true
::: mkdocs.structure.files.File
options:
show_root_heading: true
::: mkdocs.config.base.Config
options:
show_root_heading: true
::: mkdocs.utils.templates.TemplateContext
options:
show_root_heading: true
show_if_no_docstring: true
::: mkdocs.livereload.LiveReloadServer
options:
show_root_heading: true

View File

@@ -0,0 +1,566 @@
# MkDocs Plugins
A Guide to installing, using and creating MkDocs Plugins
---
## Installing Plugins
Before a plugin can be used, it must be installed on the system. If you are
using a plugin which comes with MkDocs, then it was installed when you installed
MkDocs. However, to install third party plugins, you need to determine the
appropriate package name and install it using `pip`:
```bash
pip install mkdocs-foo-plugin
```
WARNING: Installing an MkDocs plugin means installing a Python package and executing any code that the author has put in there. So, exercise the usual caution; there's no attempt at sandboxing.
Once a plugin has been successfully installed, it is ready to use. It just needs
to be [enabled](#using-plugins) in the configuration file. The [Catalog]
repository has a large ranked list of plugins that you can install and use.
## Using Plugins
The [`plugins`][config] configuration option should contain a list of plugins to
use when building the site. Each "plugin" must be a string name assigned to the
plugin (see the documentation for a given plugin to determine its "name"). A
plugin listed here must already be [installed](#installing-plugins).
```yaml
plugins:
- search
```
Some plugins may provide configuration options of their own. If you would like
to set any configuration options, then you can nest a key/value mapping
(`option_name: option value`) of any options that a given plugin supports. Note
that a colon (`:`) must follow the plugin name and then on a new line the option
name and value must be indented and separated by a colon. If you would like to
define multiple options for a single plugin, each option must be defined on a
separate line.
```yaml
plugins:
- search:
lang: en
foo: bar
```
For information regarding the configuration options available for a given plugin,
see that plugin's documentation.
For a list of default plugins and how to override them, see the
[configuration][config] documentation.
## Developing Plugins
Like MkDocs, plugins must be written in Python. It is generally expected that
each plugin would be distributed as a separate Python module, although it is
possible to define multiple plugins in the same module. At a minimum, a MkDocs
Plugin must consist of a [BasePlugin] subclass and an [entry point] which
points to it.
### BasePlugin
A subclass of `mkdocs.plugins.BasePlugin` should define the behavior of the plugin.
The class generally consists of actions to perform on specific events in the build
process as well as a configuration scheme for the plugin.
All `BasePlugin` subclasses contain the following attributes:
#### config_scheme
A tuple of configuration validation instances. Each item must consist of a
two item tuple in which the first item is the string name of the
configuration option and the second item is an instance of
`mkdocs.config.config_options.BaseConfigOption` or any of its subclasses.
For example, the following `config_scheme` defines three configuration options: `foo`, which accepts a string; `bar`, which accepts an integer; and `baz`, which accepts a boolean value.
```python
class MyPlugin(mkdocs.plugins.BasePlugin):
config_scheme = (
('foo', mkdocs.config.config_options.Type(str, default='a default value')),
('bar', mkdocs.config.config_options.Type(int, default=0)),
('baz', mkdocs.config.config_options.Type(bool, default=True))
)
```
> NEW: **New in version 1.4.**
>
> ##### Subclassing `Config` to specify the config schema
>
> To get type safety benefits, if you're targeting only MkDocs 1.4+, define the config schema as a class instead:
>
> ```python
> class MyPluginConfig(mkdocs.config.base.Config):
> foo = mkdocs.config.config_options.Type(str, default='a default value')
> bar = mkdocs.config.config_options.Type(int, default=0)
> baz = mkdocs.config.config_options.Type(bool, default=True)
>
> class MyPlugin(mkdocs.plugins.BasePlugin[MyPluginConfig]):
> ...
> ```
##### Examples of config definitions
>! EXAMPLE:
>
> ```python
> from mkdocs.config import base, config_options as c
>
> class _ValidationOptions(base.Config):
> enabled = c.Type(bool, default=True)
> verbose = c.Type(bool, default=False)
> skip_checks = c.ListOfItems(c.Choice(('foo', 'bar', 'baz')), default=[])
>
> class MyPluginConfig(base.Config):
> definition_file = c.File(exists=True) # required
> checksum_file = c.Optional(c.File(exists=True)) # can be None but must exist if specified
> validation = c.SubConfig(_ValidationOptions)
> ```
>
> From the user's point of view `SubConfig` is similar to `Type(dict)`, it's just that it also retains full ability for validation: you define all valid keys and what each value should adhere to.
>
> And `ListOfItems` is similar to `Type(list)`, but again, we define the constraint that each value must adhere to.
>
> This accepts a config as follows:
>
> ```yaml
> my_plugin:
> definition_file: configs/test.ini # relative to mkdocs.yml
> validation:
> enabled: !ENV [CI, false]
> verbose: true
> skip_checks:
> - foo
> - baz
> ```
<!-- -->
>? EXAMPLE:
>
> ```python
> import numbers
> from mkdocs.config import base, config_options as c
>
> class _Rectangle(base.Config):
> width = c.Type(numbers.Real) # required
> height = c.Type(numbers.Real) # required
>
> class MyPluginConfig(base.Config):
> add_rectangles = c.ListOfItems(c.SubConfig(_Rectangle)) # required
> ```
>
> In this example we define a list of complex items, and that's achieved by passing a concrete `SubConfig` to `ListOfItems`.
>
> This accepts a config as follows:
>
> ```yaml
> my_plugin:
> add_rectangles:
> - width: 5
> height: 7
> - width: 12
> height: 2
> ```
When the user's configuration is loaded, the above scheme will be used to
validate the configuration and fill in any defaults for settings not
provided by the user. The validation classes may be any of the classes
provided in `mkdocs.config.config_options` or a third party subclass defined
in the plugin.
Any settings provided by the user which fail validation or are not defined
in the `config_scheme` will raise a `mkdocs.config.base.ValidationError`.
#### config
A dictionary of configuration options for the plugin, which is populated by
the `load_config` method after configuration validation has completed. Use
this attribute to access options provided by the user.
```python
def on_pre_build(self, config, **kwargs):
if self.config['baz']:
# implement "baz" functionality here...
```
> NEW: **New in version 1.4.**
>
> ##### Safe attribute-based access
>
> To get type safety benefits, if you're targeting only MkDocs 1.4+, access options as attributes instead:
>
> ```python
> def on_pre_build(self, config, **kwargs):
> if self.config.baz:
> print(self.config.bar ** 2) # OK, `int ** 2` is valid.
> ```
All `BasePlugin` subclasses contain the following method(s):
#### load_config(options)
Loads configuration from a dictionary of options. Returns a tuple of
`(errors, warnings)`. This method is called by MkDocs during configuration
validation and should not need to be called by the plugin.
#### on_&lt;event_name&gt;()
Optional methods which define the behavior for specific [events]. The plugin
should define its behavior within these methods. Replace `<event_name>` with
the actual name of the event. For example, the `pre_build` event would be
defined in the `on_pre_build` method.
Most events accept one positional argument and various keyword arguments. It
is generally expected that the positional argument would be modified (or
replaced) by the plugin and returned. If nothing is returned (the method
returns `None`), then the original, unmodified object is used. The keyword
arguments are simply provided to give context and/or supply data which may
be used to determine how the positional argument should be modified. It is
good practice to accept keyword arguments as `**kwargs`. In the event that
additional keywords are provided to an event in a future version of MkDocs,
there will be no need to alter your plugin.
For example, the following event would add an additional static_template to
the theme config:
```python
class MyPlugin(BasePlugin):
def on_config(self, config, **kwargs):
config['theme'].static_templates.add('my_template.html')
return config
```
> NEW: **New in version 1.4.**
>
> To get type safety benefits, if you're targeting only MkDocs 1.4+, access config options as attributes instead:
>
> ```python
> def on_config(self, config: MkDocsConfig):
> config.theme.static_templates.add('my_template.html')
> return config
> ```
### Events
There are three kinds of events: [Global Events], [Page Events] and
[Template Events].
<details class="card">
<summary>
See a diagram with relations between all the plugin events
</summary>
<div class="card-body">
<ul>
<li>The events themselves are shown in yellow, with their parameters.
<li>Arrows show the flow of arguments and outputs of each event.
Sometimes they're omitted.
<li>The events are chronologically ordered from top to bottom.
<li>Dotted lines appear at splits from global events to per-page events.
<li>Click the events' titles to jump to their description.
</ul>
--8<-- "docs/img/plugin-events.svg"
</div>
</details>
<br>
#### One-time Events
One-time events run once per `mkdocs` invocation. The only case where these tangibly differ from [global events](#global-events) is for `mkdocs serve`: global events, unlike these, will run multiple times -- once per *build*.
##### on_startup
::: mkdocs.plugins.BasePlugin.on_startup
options:
show_root_heading: false
show_root_toc_entry: false
##### on_shutdown
::: mkdocs.plugins.BasePlugin.on_shutdown
options:
show_root_heading: false
show_root_toc_entry: false
##### on_serve
::: mkdocs.plugins.BasePlugin.on_serve
options:
show_root_heading: false
show_root_toc_entry: false
#### Global Events
Global events are called once per build at either the beginning or end of the
build process. Any changes made in these events will have a global effect on the
entire site.
##### on_config
::: mkdocs.plugins.BasePlugin.on_config
options:
show_root_heading: false
show_root_toc_entry: false
##### on_pre_build
::: mkdocs.plugins.BasePlugin.on_pre_build
options:
show_root_heading: false
show_root_toc_entry: false
##### on_files
::: mkdocs.plugins.BasePlugin.on_files
options:
show_root_heading: false
show_root_toc_entry: false
##### on_nav
::: mkdocs.plugins.BasePlugin.on_nav
options:
show_root_heading: false
show_root_toc_entry: false
##### on_env
::: mkdocs.plugins.BasePlugin.on_env
options:
show_root_heading: false
show_root_toc_entry: false
##### on_post_build
::: mkdocs.plugins.BasePlugin.on_post_build
options:
show_root_heading: false
show_root_toc_entry: false
##### on_build_error
::: mkdocs.plugins.BasePlugin.on_build_error
options:
show_root_heading: false
show_root_toc_entry: false
#### Template Events
Template events are called once for each non-page template. Each template event
will be called for each template defined in the [extra_templates] config setting
as well as any [static_templates] defined in the theme. All template events are
called after the [env] event and before any [page events].
##### on_pre_template
::: mkdocs.plugins.BasePlugin.on_pre_template
options:
show_root_heading: false
show_root_toc_entry: false
##### on_template_context
::: mkdocs.plugins.BasePlugin.on_template_context
options:
show_root_heading: false
show_root_toc_entry: false
##### on_post_template
::: mkdocs.plugins.BasePlugin.on_post_template
options:
show_root_heading: false
show_root_toc_entry: false
#### Page Events
Page events are called once for each Markdown page included in the site. All
page events are called after the [post_template] event and before the
[post_build] event.
##### on_pre_page
::: mkdocs.plugins.BasePlugin.on_pre_page
options:
show_root_heading: false
show_root_toc_entry: false
##### on_page_read_source
::: mkdocs.plugins.BasePlugin.on_page_read_source
options:
show_root_heading: false
show_root_toc_entry: false
##### on_page_markdown
::: mkdocs.plugins.BasePlugin.on_page_markdown
options:
show_root_heading: false
show_root_toc_entry: false
##### on_page_content
::: mkdocs.plugins.BasePlugin.on_page_content
options:
show_root_heading: false
show_root_toc_entry: false
##### on_page_context
::: mkdocs.plugins.BasePlugin.on_page_context
options:
show_root_heading: false
show_root_toc_entry: false
##### on_post_page
::: mkdocs.plugins.BasePlugin.on_post_page
options:
show_root_heading: false
show_root_toc_entry: false
### Event Priorities
For each event type, corresponding methods of plugins are called in the order that the plugins appear in the `plugins` [config][].
Since MkDocs 1.4, plugins can choose to set a priority value for their events. Events with higher priority are called first. Events without a chosen priority get a default of 0. Events that have the same priority are ordered as they appear in the config.
#### ::: mkdocs.plugins.event_priority
> NEW: **New in version 1.6**
>
> There may also arise a need to register a handler for the same event at multiple different priorities.
>
> `CombinedEvent` makes this possible.
>
> #### ::: mkdocs.plugins.CombinedEvent
### Handling Errors
MkDocs defines four error types:
#### ::: mkdocs.exceptions.MkDocsException
#### ::: mkdocs.exceptions.ConfigurationError
#### ::: mkdocs.exceptions.BuildError
#### ::: mkdocs.exceptions.PluginError
Unexpected and uncaught exceptions will interrupt the build process and produce
typical Python tracebacks, which are useful for debugging your code. However,
users generally find tracebacks overwhelming and often miss the helpful error
message. Therefore, MkDocs will catch any of the errors listed above, retrieve
the error message, and exit immediately with only the helpful message displayed
to the user.
Therefore, you might want to catch any exceptions within your plugin and raise a
`PluginError`, passing in your own custom-crafted message, so that the build
process is aborted with a helpful message.
The [on_build_error] event will be triggered for any exception.
For example:
```python
from mkdocs.exceptions import PluginError
from mkdocs.plugins import BasePlugin
class MyPlugin(BasePlugin):
def on_post_page(self, output, page, config, **kwargs):
try:
# some code that could throw a KeyError
...
except KeyError as error:
raise PluginError(f"Failed to find the item by key: '{error}'")
def on_build_error(self, error, **kwargs):
# some code to clean things up
...
```
### Logging in plugins
To ensure that your plugins' log messages adhere with MkDocs' formatting and `--verbose`/`--debug` flags, please write the logs to a logger under the `mkdocs.plugins.` namespace.
> EXAMPLE:
>
> ```python
> import logging
>
> log = logging.getLogger(f"mkdocs.plugins.{__name__}")
>
> log.warning("File '%s' not found. Breaks the build if --strict is passed", my_file_name)
> log.info("Shown normally")
> log.debug("Shown only with `--verbose`")
>
> if log.getEffectiveLevel() <= logging.DEBUG:
> log.debug("Very expensive calculation only for debugging: %s", get_my_diagnostics())
> ```
`log.error()` is another logging level that is differentiated by its look, but in all other ways it functions the same as `warning`, so it's strange to use it. If your plugin encounters an actual error, it is best to just interrupt the build by raising [`mkdocs.exceptions.PluginError`][] (which will also log an ERROR message).
<!-- -->
> NEW: **New in version 1.5**
>
> MkDocs now provides a `get_plugin_logger()` convenience function that returns a logger like the above that is also prefixed with the plugin's name.
>
> #### ::: mkdocs.plugins.get_plugin_logger
### Entry Point
Plugins need to be packaged as Python libraries (distributed on PyPI separate
from MkDocs) and each must register as a Plugin via a setuptools `entry_points`.
Add the following to your `setup.py` script:
```python
entry_points={
'mkdocs.plugins': [
'pluginname = path.to.some_plugin:SomePluginClass',
]
}
```
The `pluginname` would be the name used by users (in the config file) and
`path.to.some_plugin:SomePluginClass` would be the importable plugin itself
(`from path.to.some_plugin import SomePluginClass`) where `SomePluginClass` is a
subclass of [BasePlugin] which defines the plugin behavior. Naturally, multiple
Plugin classes could exist in the same module. Simply define each as a separate
entry point.
```python
entry_points={
'mkdocs.plugins': [
'featureA = path.to.my_plugins:PluginA',
'featureB = path.to.my_plugins:PluginB'
]
}
```
Note that registering a plugin does not activate it. The user still needs to
tell MkDocs to use it via the config.
### Publishing a Plugin
You should publish a package on [PyPI], then add it to the [Catalog] for discoverability. Plugins are strongly recommended to have a unique plugin name (entry point name) according to the catalog.
[BasePlugin]:#baseplugin
[config]: ../user-guide/configuration.md#plugins
[entry point]: #entry-point
[env]: #on_env
[events]: #events
[extra_templates]: ../user-guide/configuration.md#extra_templates
[Global Events]: #global-events
[Page Events]: #page-events
[post_build]: #on_post_build
[post_template]: #on_post_template
[static_templates]: ../user-guide/configuration.md#static_templates
[Template Events]: #template-events
[catalog]: https://github.com/mkdocs/catalog
[on_build_error]: #on_build_error
[PyPI]: https://pypi.org/

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,221 @@
# Translations
Theme localization guide.
---
The [built-in themes] that are included with MkDocs provide support for
translations. This is a guide for translators, which documents the process for
contributing new translations and/or updating existing translations. For
guidance on modifying the existing themes, see the [Contributing Guide][update
themes]. To enable a specific translation see the documentation about the
specific theme you are using in the [User Guide][built-in themes]. For
translations of third-party themes, please see the documentation for those
themes. For a third-party theme to make use of MkDocs' translation tools and
methods, that theme must be properly [configured] to make use of those tools.
NOTE:
Translations only apply to text contained within a theme's template, such
as "next" and "previous" links. The Markdown content of a page is not
translated. If you wish to create multilingual documentation, you need to
combine theme localization with a third-party
internationalization/localization plugin.
[built-in themes]: ../user-guide/choosing-your-theme.md
[update themes]: ../about/contributing.md#submitting-changes-to-the-builtin-themes
[configured]: themes.md#supporting-theme-localizationtranslation
## Localization tooling prerequisites
Theme localization makes use of the [babel][babel] project for generation and
compilation of localization files. You will need to be working from the
git working tree on your local machine to make use of the translation commands.
See the [Contributing Guide] for direction on how to [Install for Development]
and [Submit a Pull Request]. The instructions in this document assume that you
are working from a properly configured development environment.
Make sure translation requirements are installed in your environment:
```bash
pip install 'mkdocs[i18n]'
```
[babel]: https://babel.pocoo.org/en/latest/cmdline.html
[Contributing Guide]: ../about/contributing.md
[Install for Development]: ../about/contributing.md#installing-for-development
[Submit a Pull Request]: ../about/contributing.md#submitting-pull-requests
## Adding language translations to themes
If your favorite language locale is not yet supported on one (or both) of the
built-in themes (`mkdocs` and `readthedocs`), you can easily contribute a
translation by following the steps below.
Here is a quick summary of what you'll need to do:
1. [Fork and clone the MkDocs repository](#fork-and-clone-the-mkdocs-repository) and then [install MkDocs for development](../about/contributing.md#installing-for-development) for adding and testing translations.
2. [Initialize new localization catalogs](#initializing-the-localization-catalogs) for your language (if a translation for your locale already exists, follow the instructions for [updating theme localization files](#updating-the-translation-catalogs) instead).
3. [Add a translation](#translating-the-mkdocs-themes) for every text placeholder in the localized catalogs.
4. [Locally serve and test](#testing-theme-translations) the translated themes for your language.
5. [Update the documentation](#updating-theme-documentation) about supported translations for each translated theme.
6. [Contribute your translation](#contributing-translations) through a Pull Request.
NOTE:
Translation locales are usually identified using the [ISO-639-1] (2-letter)
language codes. While territory/region/county codes are also supported,
location specific translations should only be added after the general
language translation has been completed and the regional dialect requires
use of a term which differs from the general language translation.
[ISO-639-1]: https://en.wikipedia.org/wiki/ISO_639-1
### Fork and clone the MkDocs repository
In the following steps you'll work with a fork of the MkDocs repository. Follow
the instructions for [forking and cloning the MkDocs
repository](../about/contributing.md#installing-for-development).
To test the translations you also need to [install MkDocs for
development](../about/contributing.md#installing-for-development) from your fork.
### Initializing the localization catalogs
The templates for each theme contain text placeholders that have been extracted
into a Portable Object Template (`messages.pot`) file, which is present in each
theme's folder.
Initializing a catalog consists of running a command which will create a
directory structure for your desired language and prepare a Portable Object
(`messages.po`) file derived from the `pot` file of the theme.
Use the `init_catalog` command on each theme's directory and provide the appropriate language code (`-l <language>`).
The language code is almost always just two lowercase letters, such as `sv`, but in some cases it needs to be further disambiguated.
See:
* [Already translated languages for built-in themes](../user-guide/choosing-your-theme.md#mkdocs-locale)
* [ISO 639 Language List](https://www.localeplanet.com/icu/iso639.html)
* [Language subtag registry](https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry)
In particular, the way to know that the `pt` language should be disambiguated as `pt_PT` and `pt_BR` is that the *Language subtag registry* page contains `pt-` if you search for it. Whereas `sv` should remain just `sv`, because that page does *not* contain `sv-`.
So, if we pick `es` (Spanish) as our example language code, to add a translation for it to both built-in themes, run these commands:
```bash
pybabel init --input-file mkdocs/themes/mkdocs/messages.pot --output-dir mkdocs/themes/mkdocs/locales -l es
pybabel init --input-file mkdocs/themes/readthedocs/messages.pot --output-dir mkdocs/themes/readthedocs/locales -l es
```
The above command will create a file structure as follows:
```text
mkdocs/themes/mkdocs/locales
├── es
│   └── LC_MESSAGES
│   └── messages.po
```
You can now move on to the next step and [add a
translation](#translating-the-mkdocs-themes) for every text placeholder in the
localized catalog.
## Updating a theme translation
If a theme's `messages.pot` template file has been [updated][update themes]
since the `messages.po` was last updated for your locale, follow the steps
below to update the theme's `messages.po` file:
1. [Update the theme's translation catalog](#updating-the-translation-catalogs) to refresh the translatable text placeholders of each theme.
2. [Translate](#translating-the-mkdocs-themes) the newly added translatable text placeholders on every `messages.po` catalog file language you can.
3. [Locally serve and test](#testing-theme-translations) the translated themes for your language.
4. [Contribute your translation](#contributing-translations) through a Pull Request.
### Updating the translation catalogs
This step should be completed after a theme template have been [updated][update
themes] for each language that you are comfortable contributing a translation
for.
To update the `fr` translation catalog of both built-in themes, use the following commands:
```bash
pybabel update --ignore-obsolete --input-file mkdocs/themes/mkdocs/messages.pot --output-dir mkdocs/themes/mkdocs/locales -l fr
pybabel update --ignore-obsolete --input-file mkdocs/themes/readthedocs/messages.pot --output-dir mkdocs/themes/readthedocs/locales -l fr
```
You can now move on to the next step and [add a translation] for every updated
text placeholder in the localized catalog.
[add a translation]: #translating-the-mkdocs-themes
### Translating the MkDocs themes
Now that your localized `messages.po` files are ready, all you need to do is
add a translation in each `msgstr` item for each `msgid` item in the file.
```text
msgid "Next"
msgstr "Siguiente"
```
WARNING:
Do not modify the `msgid` as it is common to all translations. Just add
its translation in the `msgstr` item.
Once you have finished translating all of the terms listed in the `po` file,
you'll want to [test your localized theme](#testing-theme-translations).
### Testing theme translations
To test a theme with translations, you need to first compile the `messages.po`
files of your theme into `messages.mo` files. The following commands will compile
the `es` translation for both built-in themes:
```bash
pybabel compile --statistics --directory mkdocs/themes/mkdocs/locales -l es
pybabel compile --statistics --directory mkdocs/themes/readthedocs/locales -l es
```
The above command results in the following file structure:
```text
mkdocs/themes/mkdocs/locales
├── es
│   └── LC_MESSAGES
│   ├── messages.mo
│   └── messages.po
```
Note that the compiled `messages.mo` file was generated based on the
`messages.po` file that you just edited.
Then modify the `mkdocs.yml` file at the root of the project to test the new
and/or updated locale:
```yaml
theme:
name: mkdocs
locale: es
```
Finally, run `mkdocs serve` to check out your new localized version of the theme.
> NOTE:
> The build and release process takes care of compiling and distributing
> all locales to end users so you only have to worry about contributing the
> actual text translation `messages.po` files (the rest is ignored by git).
>
> After you have finished testing your work, be sure to undo the change to
> the `locale` setting in the `mkdocs.yml` file before submitting your
> changes.
## Updating theme documentation
The page [Choosing your theme](../user-guide/choosing-your-theme.md) updates by itself with all available locale options.
## Contributing translations
It is now time for you to [contribute](../about/contributing.md) your nice work
to the project. Thank you!

View File

@@ -0,0 +1,213 @@
# Getting Started with MkDocs
An introductory tutorial!
---
## Installation
To install MkDocs, run the following command from the command line:
```bash
pip install mkdocs
```
For more details, see the [Installation Guide].
## Creating a new project
Getting started is super easy. To create a new project, run the following
command from the command line:
```bash
mkdocs new my-project
cd my-project
```
Take a moment to review the initial project that has been created for you.
![The initial MkDocs layout](img/initial-layout.png)
There's a single configuration file named `mkdocs.yml`, and a folder named
`docs` that will contain your documentation source files (`docs` is
the default value for the [docs_dir] configuration setting). Right now the `docs`
folder just contains a single documentation page, named `index.md`.
MkDocs comes with a built-in dev-server that lets you preview your documentation
as you work on it. Make sure you're in the same directory as the `mkdocs.yml`
configuration file, and then start the server by running the `mkdocs serve`
command:
```console
$ mkdocs serve
INFO - Building documentation...
INFO - Cleaning site directory
INFO - Documentation built in 0.22 seconds
INFO - [15:50:43] Watching paths for changes: 'docs', 'mkdocs.yml'
INFO - [15:50:43] Serving on http://127.0.0.1:8000/
```
Open up <http://127.0.0.1:8000/> in your browser, and you'll see the default
home page being displayed:
![The MkDocs live server](img/screenshot.png)
The dev-server also supports auto-reloading, and will rebuild your documentation
whenever anything in the configuration file, documentation directory, or theme
directory changes.
Open the `docs/index.md` document in your text editor of choice, change the
initial heading to `MkLorum`, and save your changes. Your browser will
auto-reload and you should see your updated documentation immediately.
Now try editing the configuration file: `mkdocs.yml`. Change the
[`site_name`][site_name] setting to `MkLorum` and save the file.
```yaml
site_name: MkLorum
```
Your browser should immediately reload, and you'll see your new site name take
effect.
![The site_name setting](img/site-name.png)
NOTE:
The [`site_name`][site_name] configuration
option is the only required option in your configuration file.
## Adding pages
Now add a second page to your documentation:
```bash
curl 'https://jaspervdj.be/lorem-markdownum/markdown.txt' > docs/about.md
```
As our documentation site will include some navigation headers, you may want to
edit the configuration file and add some information about the order, title, and
nesting of each page in the navigation header by adding a [`nav`][nav]
setting:
```yaml
site_name: MkLorum
nav:
- Home: index.md
- About: about.md
```
Save your changes and you'll now see a navigation bar with `Home` and `About`
items on the left as well as `Search`, `Previous`, and `Next` items on the
right.
![Screenshot](img/multipage.png)
Try the menu items and navigate back and forth between pages. Then click on
`Search`. A search dialog will appear, allowing you to search for any text on
any page. Notice that the search results include every occurrence of the search
term on the site and links directly to the section of the page in which the
search term appears. You get all of that with no effort or configuration on your
part!
![Screenshot](img/search.png)
## Theming our documentation
Now change the configuration file to alter how the documentation is displayed by
changing the theme. Edit the `mkdocs.yml` file and add a [`theme`][theme] setting:
```yaml
site_name: MkLorum
nav:
- Home: index.md
- About: about.md
theme: readthedocs
```
Save your changes, and you'll see the ReadTheDocs theme being used.
![Screenshot](img/readthedocs.png)
## Changing the Favicon Icon
By default, MkDocs uses the [MkDocs favicon] icon. To use a different icon, create
an `img` subdirectory in the `docs` directory and copy your custom `favicon.ico`
file to that directory. MkDocs will automatically detect and use that file as your
favicon icon.
[MkDocs favicon]: img/favicon.ico
## Building the site
That's looking good. You're ready to deploy the first pass of your `MkLorum`
documentation. First build the documentation:
```bash
mkdocs build
```
This will create a new directory, named `site`. Take a look inside the
directory:
```console
$ ls site
about fonts index.html license search.html
css img js mkdocs sitemap.xml
```
Notice that your source documentation has been output as two HTML files named
`index.html` and `about/index.html`. You also have various other media that's
been copied into the `site` directory as part of the documentation theme. You
even have a `sitemap.xml` file and `mkdocs/search_index.json`.
If you're using source code control such as `git` you probably don't want to
check your documentation builds into the repository. Add a line containing
`site/` to your `.gitignore` file.
```bash
echo "site/" >> .gitignore
```
If you're using another source code control tool you'll want to check its
documentation on how to ignore specific directories.
## Other Commands and Options
There are various other commands and options available. For a complete list of
commands, use the `--help` flag:
```bash
mkdocs --help
```
To view a list of options available on a given command, use the `--help` flag
with that command. For example, to get a list of all options available for the
`build` command run the following:
```bash
mkdocs build --help
```
## Deploying
The documentation site that you just built only uses static files so you'll be
able to host it from pretty much anywhere. Simply upload the contents of the
entire `site` directory to wherever you're hosting your website from and
you're done. For specific instructions on a number of common hosts, see the
[Deploying your Docs][deploy] page.
## Getting help
See the [User Guide] for more complete documentation of all of MkDocs' features.
To get help with MkDocs, please use the [GitHub discussions] or [GitHub issues].
[Installation Guide]: user-guide/installation.md
[docs_dir]: user-guide/configuration.md#docs_dir
[deploy]: user-guide/deploying-your-docs.md
[nav]: user-guide/configuration.md#nav
[GitHub discussions]: https://github.com/mkdocs/mkdocs/discussions
[GitHub issues]: https://github.com/mkdocs/mkdocs/issues
[site_name]: user-guide/configuration.md#site_name
[theme]: user-guide/configuration.md#theme
[User Guide]: user-guide/README.md

View File

@@ -0,0 +1,36 @@
from __future__ import annotations
import re
from pathlib import Path
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from mkdocs.config.defaults import MkDocsConfig
from mkdocs.structure.nav import Page
def _get_language_of_translation_file(path: Path) -> str:
with path.open(encoding='utf-8') as f:
translation_line = f.readline()
m = re.search('^# (.+) translations ', translation_line)
assert m
return m[1]
def on_page_markdown(markdown: str, page: Page, config: MkDocsConfig, **kwargs) -> str | None:
if page.file.src_uri == 'user-guide/choosing-your-theme.md':
here = Path(config.config_file_path).parent
def replacement(m: re.Match) -> str:
lines = []
for d in sorted(here.glob(m[2])):
lang = _get_language_of_translation_file(Path(d, 'LC_MESSAGES', 'messages.po'))
lines.append(f'{m[1]}`{d.name}`: {lang}')
return '\n'.join(lines)
return re.sub(
r'^( *\* )\(see the list of existing directories `(.+)`\)$',
replacement,
markdown,
flags=re.MULTILINE,
)

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

View File

@@ -0,0 +1,171 @@
# Run this to re-generate 'plugin-events.svg'.
# Requires `pip install graphviz`.
import contextlib
import pathlib
import re
from graphviz import Digraph
graph = Digraph("MkDocs", format="svg")
graph.attr(compound="true", bgcolor="transparent")
graph.graph_attr.update(fontname="inherit", tooltip=" ")
graph.node_attr.update(fontname="inherit", tooltip=" ", style="filled")
graph.edge_attr.update(fontname="inherit", tooltip=" ")
def strip_suffix(name):
return re.sub(r"_.$", "", name)
subgraph_to_first_node = {}
subgraph_to_last_node = {}
def node(g, name, **kwargs):
if "_point" in name:
kwargs.setdefault("shape", "point")
else:
kwargs.setdefault("fillcolor", "#77ff7788")
kwargs.setdefault("color", "#00000099")
kwargs.setdefault("label", strip_suffix(name))
g.node(name, **kwargs)
subgraph_to_first_node.setdefault(g.name, name)
subgraph_to_last_node[g.name] = name
def edge(g, a, b, dashed=False, **kwargs):
if kwargs.get("style") == "dashed":
kwargs.setdefault("penwidth", "1.5")
if a in subgraph_to_last_node:
kwargs.setdefault("ltail", a)
a = subgraph_to_last_node[a]
if b in subgraph_to_first_node:
kwargs.setdefault("lhead", b)
b = subgraph_to_first_node[b]
if a.startswith(("on_", "placeholder_")):
a += ":s"
else:
node(g, a.split(":")[0])
if b.startswith(("on_", "placeholder_")):
b += ":n"
else:
node(g, b.split(":")[0])
g.edge(a, b, **kwargs)
def ensure_order(a, b):
edge(graph, a, b, style="invis")
@contextlib.contextmanager
def cluster(g, name, **kwargs):
assert name.startswith("cluster_")
kwargs.setdefault("label", strip_suffix(name)[len("cluster_") :])
kwargs.setdefault("bgcolor", "#dddddd55")
kwargs.setdefault("pencolor", "#00000066")
with g.subgraph(name=name) as c:
c.attr(**kwargs)
yield c
def event(g, name, parameters):
with cluster(
g, f"cluster_{name}", href=f"#{name}", bgcolor="#ffff3388", pencolor="#00000088"
) as c:
label = "|".join(f"<{p}>{p}" for p in parameters.split())
node(c, name, shape="record" if parameters else "point", label=label, fillcolor="#ffffff55")
def placeholder_cluster(g, name):
with cluster(g, name) as c:
node(c, f"placeholder_{name}", label="...", fillcolor="transparent", color="transparent")
event(graph, "on_startup", "command dirty")
with cluster(graph, "cluster_build", bgcolor="#dddddd11") as g:
event(g, "on_config", "config")
event(g, "on_pre_build", "config")
event(g, "on_files", "files config")
event(g, "on_nav", "nav config files")
edge(g, "load_config", "on_config:config")
edge(g, "on_config:config", "on_pre_build:config")
edge(g, "on_config:config", "get_files")
edge(g, "get_files", "on_files:files")
edge(g, "on_files:files", "get_nav")
edge(g, "get_nav", "on_nav:nav")
edge(g, "on_files:files", "on_nav:files")
with cluster(g, "cluster_populate_page") as c:
event(c, "on_pre_page", "page config files")
event(c, "on_page_read_source", "page config")
event(c, "on_page_markdown", "markdown page config files")
event(c, "on_page_content", "html page config files")
edge(c, "on_pre_page:page", "on_page_read_source:page", style="dashed")
edge(c, "cluster_on_page_read_source", "on_page_markdown:markdown", style="dashed")
edge(c, "on_page_markdown:markdown", "render_p", style="dashed")
edge(c, "render_p", "on_page_content:html", style="dashed")
edge(g, "on_nav:files", "pages_point_a", arrowhead="none")
edge(g, "pages_point_a", "on_pre_page:page", style="dashed")
edge(g, "pages_point_a", "cluster_populate_page")
for i in 2, 3:
placeholder_cluster(g, f"cluster_populate_page_{i}")
edge(g, "pages_point_a", f"cluster_populate_page_{i}", style="dashed")
edge(g, f"cluster_populate_page_{i}", "pages_point_b", style="dashed")
event(g, "on_env", "env config files")
edge(g, "on_page_content:html", "pages_point_b", style="dashed")
edge(g, "pages_point_b", "on_env:files")
edge(g, "pages_point_b", "pages_point_c", arrowhead="none")
edge(g, "pages_point_c", "on_page_context:page", style="dashed")
with cluster(g, "cluster_build_page") as c:
event(c, "on_page_context", "context page config nav")
event(c, "on_post_page", "output page config")
edge(c, "get_context", "on_page_context:context")
edge(c, "on_page_context:context", "render")
edge(c, "get_template", "render")
edge(c, "render", "on_post_page:output")
edge(c, "on_post_page:output", "write_file")
edge(g, "on_nav:nav", "cluster_build_page")
edge(g, "on_env:env", "cluster_build_page")
for i in 2, 3:
placeholder_cluster(g, f"cluster_build_page_{i}")
edge(g, "pages_point_c", f"cluster_build_page_{i}", style="dashed")
event(g, "on_post_build", "config")
event(graph, "on_serve", "server config")
event(graph, "on_shutdown", "")
ensure_order("on_startup", "cluster_build")
ensure_order("on_pre_build", "on_files")
ensure_order("on_nav", "cluster_populate_page")
ensure_order("cluster_populate_page_2", "cluster_populate_page_3")
ensure_order("on_page_content", "on_env")
ensure_order("pages_point_c", "cluster_build_page")
ensure_order("cluster_build_page_2", "cluster_build_page_3")
ensure_order("cluster_build_page", "on_post_build")
ensure_order("on_post_build", "on_serve")
ensure_order("on_serve", "on_shutdown")
data = graph.pipe()
data = data[data.index(b"<svg ") :]
pathlib.Path(__file__).with_suffix(".svg").write_bytes(data)

View File

@@ -0,0 +1,780 @@
<svg width="527pt" height="1786pt"
viewBox="0.00 0.00 527.00 1785.80" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 1781.8)">
<title>MkDocs</title>
<g id="a_graph0"><a xlink:title=" ">
</a>
</g>
<g id="clust1" class="cluster">
<title>cluster_on_startup</title>
<g id="a_clust1"><a xlink:href="#on_startup" xlink:title=" ">
<polygon fill="#ffff33" fill-opacity="0.533333" stroke="#000000" stroke-opacity="0.533333" points="199,-1693.8 199,-1769.8 341,-1769.8 341,-1693.8 199,-1693.8"/>
<text text-anchor="middle" x="270" y="-1754.6" font-family="inherit" font-size="14.00">on_startup</text>
</a>
</g>
</g>
<g id="clust2" class="cluster">
<title>cluster_build</title>
<g id="a_clust2"><a xlink:title=" ">
<polygon fill="#dddddd" fill-opacity="0.066667" stroke="#000000" stroke-opacity="0.400000" points="8,-142.6 8,-1685.8 511,-1685.8 511,-142.6 8,-142.6"/>
<text text-anchor="middle" x="259.5" y="-1670.6" font-family="inherit" font-size="14.00">build</text>
</a>
</g>
</g>
<g id="clust3" class="cluster">
<title>cluster_on_config</title>
<g id="a_clust3"><a xlink:href="#on_config" xlink:title=" ">
<polygon fill="#ffff33" fill-opacity="0.533333" stroke="#000000" stroke-opacity="0.533333" points="230,-1534.8 230,-1610.8 310,-1610.8 310,-1534.8 230,-1534.8"/>
<text text-anchor="middle" x="270" y="-1595.6" font-family="inherit" font-size="14.00">on_config</text>
</a>
</g>
</g>
<g id="clust4" class="cluster">
<title>cluster_on_pre_build</title>
<g id="a_clust4"><a xlink:href="#on_pre_build" xlink:title=" ">
<polygon fill="#ffff33" fill-opacity="0.533333" stroke="#000000" stroke-opacity="0.533333" points="161,-1450.8 161,-1526.8 261,-1526.8 261,-1450.8 161,-1450.8"/>
<text text-anchor="middle" x="211" y="-1511.6" font-family="inherit" font-size="14.00">on_pre_build</text>
</a>
</g>
</g>
<g id="clust5" class="cluster">
<title>cluster_on_files</title>
<g id="a_clust5"><a xlink:href="#on_files" xlink:title=" ">
<polygon fill="#ffff33" fill-opacity="0.533333" stroke="#000000" stroke-opacity="0.533333" points="226,-1366.8 226,-1442.8 342,-1442.8 342,-1366.8 226,-1366.8"/>
<text text-anchor="middle" x="284" y="-1427.6" font-family="inherit" font-size="14.00">on_files</text>
</a>
</g>
</g>
<g id="clust6" class="cluster">
<title>cluster_on_nav</title>
<g id="a_clust6"><a xlink:href="#on_nav" xlink:title=" ">
<polygon fill="#ffff33" fill-opacity="0.533333" stroke="#000000" stroke-opacity="0.533333" points="181,-1218.8 181,-1294.8 335,-1294.8 335,-1218.8 181,-1218.8"/>
<text text-anchor="middle" x="258" y="-1279.6" font-family="inherit" font-size="14.00">on_nav</text>
</a>
</g>
</g>
<g id="clust7" class="cluster">
<title>cluster_populate_page</title>
<g id="a_clust7"><a xlink:title=" ">
<polygon fill="#dddddd" fill-opacity="0.333333" stroke="#000000" stroke-opacity="0.400000" points="22,-729.2 22,-1179.2 284,-1179.2 284,-729.2 22,-729.2"/>
<text text-anchor="middle" x="153" y="-1164" font-family="inherit" font-size="14.00">populate_page</text>
</a>
</g>
</g>
<g id="clust8" class="cluster">
<title>cluster_on_pre_page</title>
<g id="a_clust8"><a xlink:href="#on_pre_page" xlink:title=" ">
<polygon fill="#ffff33" fill-opacity="0.533333" stroke="#000000" stroke-opacity="0.533333" points="80,-1072.2 80,-1148.2 244,-1148.2 244,-1072.2 80,-1072.2"/>
<text text-anchor="middle" x="162" y="-1133" font-family="inherit" font-size="14.00">on_pre_page</text>
</a>
</g>
</g>
<g id="clust9" class="cluster">
<title>cluster_on_page_read_source</title>
<g id="a_clust9"><a xlink:href="#on_page_read_source" xlink:title=" ">
<polygon fill="#ffff33" fill-opacity="0.533333" stroke="#000000" stroke-opacity="0.533333" points="46,-988.2 46,-1064.2 201,-1064.2 201,-988.2 46,-988.2"/>
<text text-anchor="middle" x="123.5" y="-1049" font-family="inherit" font-size="14.00">on_page_read_source</text>
</a>
</g>
</g>
<g id="clust10" class="cluster">
<title>cluster_on_page_markdown</title>
<g id="a_clust10"><a xlink:href="#on_page_markdown" xlink:title=" ">
<polygon fill="#ffff33" fill-opacity="0.533333" stroke="#000000" stroke-opacity="0.533333" points="30,-904.2 30,-980.2 276,-980.2 276,-904.2 30,-904.2"/>
<text text-anchor="middle" x="153" y="-965" font-family="inherit" font-size="14.00">on_page_markdown</text>
</a>
</g>
</g>
<g id="clust11" class="cluster">
<title>cluster_on_page_content</title>
<g id="a_clust11"><a xlink:href="#on_page_content" xlink:title=" ">
<polygon fill="#ffff33" fill-opacity="0.533333" stroke="#000000" stroke-opacity="0.533333" points="66,-737.2 66,-813.2 276,-813.2 276,-737.2 66,-737.2"/>
<text text-anchor="middle" x="171" y="-798" font-family="inherit" font-size="14.00">on_page_content</text>
</a>
</g>
</g>
<g id="clust14" class="cluster">
<title>cluster_on_env</title>
<g id="a_clust14"><a xlink:href="#on_env" xlink:title=" ">
<polygon fill="#ffff33" fill-opacity="0.533333" stroke="#000000" stroke-opacity="0.533333" points="202,-621.6 202,-697.6 356,-697.6 356,-621.6 202,-621.6"/>
<text text-anchor="middle" x="279" y="-682.4" font-family="inherit" font-size="14.00">on_env</text>
</a>
</g>
</g>
<g id="clust12" class="cluster">
<title>cluster_populate_page_2</title>
<g id="a_clust12"><a xlink:title=" ">
<polygon fill="#dddddd" fill-opacity="0.333333" stroke="#000000" stroke-opacity="0.400000" points="292,-821.2 292,-896.2 404,-896.2 404,-821.2 292,-821.2"/>
<text text-anchor="middle" x="348" y="-881" font-family="inherit" font-size="14.00">populate_page</text>
</a>
</g>
</g>
<g id="clust13" class="cluster">
<title>cluster_populate_page_3</title>
<g id="a_clust13"><a xlink:title=" ">
<polygon fill="#dddddd" fill-opacity="0.333333" stroke="#000000" stroke-opacity="0.400000" points="312,-737.7 312,-812.7 424,-812.7 424,-737.7 312,-737.7"/>
<text text-anchor="middle" x="368" y="-797.5" font-family="inherit" font-size="14.00">populate_page</text>
</a>
</g>
</g>
<g id="clust15" class="cluster">
<title>cluster_build_page</title>
<g id="a_clust15"><a xlink:title=" ">
<polygon fill="#dddddd" fill-opacity="0.333333" stroke="#000000" stroke-opacity="0.400000" points="16,-234.6 16,-613.6 398,-613.6 398,-234.6 16,-234.6"/>
<text text-anchor="middle" x="207" y="-598.4" font-family="inherit" font-size="14.00">build_page</text>
</a>
</g>
</g>
<g id="clust16" class="cluster">
<title>cluster_on_page_context</title>
<g id="a_clust16"><a xlink:href="#on_page_context" xlink:title=" ">
<polygon fill="#ffff33" fill-opacity="0.533333" stroke="#000000" stroke-opacity="0.533333" points="166,-454.6 166,-530.6 390,-530.6 390,-454.6 166,-454.6"/>
<text text-anchor="middle" x="278" y="-515.4" font-family="inherit" font-size="14.00">on_page_context</text>
</a>
</g>
</g>
<g id="clust17" class="cluster">
<title>cluster_on_post_page</title>
<g id="a_clust17"><a xlink:href="#on_post_page" xlink:title=" ">
<polygon fill="#ffff33" fill-opacity="0.533333" stroke="#000000" stroke-opacity="0.533333" points="109,-306.6 109,-382.6 291,-382.6 291,-306.6 109,-306.6"/>
<text text-anchor="middle" x="200" y="-367.4" font-family="inherit" font-size="14.00">on_post_page</text>
</a>
</g>
</g>
<g id="clust18" class="cluster">
<title>cluster_build_page_2</title>
<g id="a_clust18"><a xlink:title=" ">
<polygon fill="#dddddd" fill-opacity="0.333333" stroke="#000000" stroke-opacity="0.400000" points="406,-538.6 406,-613.6 493,-613.6 493,-538.6 406,-538.6"/>
<text text-anchor="middle" x="449.5" y="-598.4" font-family="inherit" font-size="14.00">build_page</text>
</a>
</g>
</g>
<g id="clust19" class="cluster">
<title>cluster_build_page_3</title>
<g id="a_clust19"><a xlink:title=" ">
<polygon fill="#dddddd" fill-opacity="0.333333" stroke="#000000" stroke-opacity="0.400000" points="411,-455.1 411,-530.1 498,-530.1 498,-455.1 411,-455.1"/>
<text text-anchor="middle" x="454.5" y="-514.9" font-family="inherit" font-size="14.00">build_page</text>
</a>
</g>
</g>
<g id="clust20" class="cluster">
<title>cluster_on_post_build</title>
<g id="a_clust20"><a xlink:href="#on_post_build" xlink:title=" ">
<polygon fill="#ffff33" fill-opacity="0.533333" stroke="#000000" stroke-opacity="0.533333" points="95,-150.6 95,-226.6 202,-226.6 202,-150.6 95,-150.6"/>
<text text-anchor="middle" x="148.5" y="-211.4" font-family="inherit" font-size="14.00">on_post_build</text>
</a>
</g>
</g>
<g id="clust21" class="cluster">
<title>cluster_on_serve</title>
<g id="a_clust21"><a xlink:href="#on_serve" xlink:title=" ">
<polygon fill="#ffff33" fill-opacity="0.533333" stroke="#000000" stroke-opacity="0.533333" points="84,-58.6 84,-134.6 212,-134.6 212,-58.6 84,-58.6"/>
<text text-anchor="middle" x="148" y="-119.4" font-family="inherit" font-size="14.00">on_serve</text>
</a>
</g>
</g>
<g id="clust22" class="cluster">
<title>cluster_on_shutdown</title>
<g id="a_clust22"><a xlink:href="#on_shutdown" xlink:title=" ">
<polygon fill="#ffff33" fill-opacity="0.533333" stroke="#000000" stroke-opacity="0.533333" points="102,-8 102,-50.6 206,-50.6 206,-8 102,-8"/>
<text text-anchor="middle" x="154" y="-35.4" font-family="inherit" font-size="14.00">on_shutdown</text>
</a>
</g>
</g>
<!-- on_startup -->
<g id="node1" class="node">
<title>on_startup</title>
<g id="a_node1"><a xlink:title=" ">
<polygon fill="#ffffff" fill-opacity="0.333333" stroke="#000000" stroke-opacity="0.600000" points="207,-1702.3 207,-1738.3 333,-1738.3 333,-1702.3 207,-1702.3"/>
<text text-anchor="middle" x="246.5" y="-1716.6" font-family="inherit" font-size="14.00">command</text>
<polyline fill="none" stroke="#000000" stroke-opacity="0.600000" points="286,-1702.3 286,-1738.3"/>
<text text-anchor="middle" x="309.5" y="-1716.6" font-family="inherit" font-size="14.00">dirty</text>
</a>
</g>
</g>
<!-- load_config -->
<g id="node6" class="node">
<title>load_config</title>
<g id="a_node6"><a xlink:title=" ">
<ellipse fill="#77ff77" fill-opacity="0.533333" stroke="#000000" stroke-opacity="0.600000" cx="270" cy="-1636.8" rx="59.29" ry="18"/>
<text text-anchor="middle" x="270" y="-1633.1" font-family="inherit" font-size="14.00">load_config</text>
</a>
</g>
</g>
<!-- on_startup&#45;&gt;load_config -->
<!-- on_config -->
<g id="node2" class="node">
<title>on_config</title>
<g id="a_node2"><a xlink:title=" ">
<polygon fill="#ffffff" fill-opacity="0.333333" stroke="#000000" stroke-opacity="0.600000" points="242,-1543.3 242,-1579.3 298,-1579.3 298,-1543.3 242,-1543.3"/>
<text text-anchor="middle" x="270" y="-1557.6" font-family="inherit" font-size="14.00">config</text>
</a>
</g>
</g>
<!-- on_pre_build -->
<g id="node3" class="node">
<title>on_pre_build</title>
<g id="a_node3"><a xlink:title=" ">
<polygon fill="#ffffff" fill-opacity="0.333333" stroke="#000000" stroke-opacity="0.600000" points="196,-1459.3 196,-1495.3 252,-1495.3 252,-1459.3 196,-1459.3"/>
<text text-anchor="middle" x="224" y="-1473.6" font-family="inherit" font-size="14.00">config</text>
</a>
</g>
</g>
<!-- on_config&#45;&gt;on_pre_build -->
<g id="edge2" class="edge">
<title>on_config:s&#45;&gt;on_pre_build:n</title>
<g id="a_edge2"><a xlink:title=" ">
<path fill="none" stroke="black" d="M270,-1542.3C270,-1536.71 242.48,-1516.57 230.01,-1504.39"/>
<polygon fill="black" stroke="black" points="232.77,-1502.24 224,-1496.3 227.16,-1506.41 232.77,-1502.24"/>
</a>
</g>
</g>
<!-- get_files -->
<g id="node7" class="node">
<title>get_files</title>
<g id="a_node7"><a xlink:title=" ">
<ellipse fill="#77ff77" fill-opacity="0.533333" stroke="#000000" stroke-opacity="0.600000" cx="316" cy="-1477.3" rx="46.29" ry="18"/>
<text text-anchor="middle" x="316" y="-1473.6" font-family="inherit" font-size="14.00">get_files</text>
</a>
</g>
</g>
<!-- on_config&#45;&gt;get_files -->
<g id="edge3" class="edge">
<title>on_config:s&#45;&gt;get_files</title>
<g id="a_edge3"><a xlink:title=" ">
<path fill="none" stroke="black" d="M270,-1542.3C270,-1526.62 279.21,-1512.16 289.39,-1500.97"/>
<polygon fill="black" stroke="black" points="291.96,-1503.34 296.49,-1493.76 286.98,-1498.43 291.96,-1503.34"/>
</a>
</g>
</g>
<!-- on_files -->
<g id="node4" class="node">
<title>on_files</title>
<g id="a_node4"><a xlink:title=" ">
<polygon fill="#ffffff" fill-opacity="0.333333" stroke="#000000" stroke-opacity="0.600000" points="234.5,-1375.3 234.5,-1411.3 333.5,-1411.3 333.5,-1375.3 234.5,-1375.3"/>
<text text-anchor="middle" x="256" y="-1389.6" font-family="inherit" font-size="14.00">files</text>
<polyline fill="none" stroke="#000000" stroke-opacity="0.600000" points="277.5,-1375.3 277.5,-1411.3"/>
<text text-anchor="middle" x="305.5" y="-1389.6" font-family="inherit" font-size="14.00">config</text>
</a>
</g>
</g>
<!-- on_pre_build&#45;&gt;on_files -->
<!-- on_nav -->
<g id="node5" class="node">
<title>on_nav</title>
<g id="a_node5"><a xlink:title=" ">
<polygon fill="#ffffff" fill-opacity="0.333333" stroke="#000000" stroke-opacity="0.600000" points="189.5,-1227.3 189.5,-1263.3 326.5,-1263.3 326.5,-1227.3 189.5,-1227.3"/>
<text text-anchor="middle" x="208.5" y="-1241.6" font-family="inherit" font-size="14.00">nav</text>
<polyline fill="none" stroke="#000000" stroke-opacity="0.600000" points="227.5,-1227.3 227.5,-1263.3"/>
<text text-anchor="middle" x="255.5" y="-1241.6" font-family="inherit" font-size="14.00">config</text>
<polyline fill="none" stroke="#000000" stroke-opacity="0.600000" points="283.5,-1227.3 283.5,-1263.3"/>
<text text-anchor="middle" x="305" y="-1241.6" font-family="inherit" font-size="14.00">files</text>
</a>
</g>
</g>
<!-- on_files&#45;&gt;on_nav -->
<g id="edge7" class="edge">
<title>on_files:s&#45;&gt;on_nav:n</title>
<g id="a_edge7"><a xlink:title=" ">
<path fill="none" stroke="black" d="M256,-1374.3C256,-1352.14 280.73,-1358.43 291,-1338.8 304.91,-1312.21 305.15,-1300.61 305.03,-1274.59"/>
<polygon fill="black" stroke="black" points="308.53,-1274.29 305,-1264.3 301.53,-1274.31 308.53,-1274.29"/>
</a>
</g>
</g>
<!-- get_nav -->
<g id="node8" class="node">
<title>get_nav</title>
<g id="a_node8"><a xlink:title=" ">
<ellipse fill="#77ff77" fill-opacity="0.533333" stroke="#000000" stroke-opacity="0.600000" cx="216" cy="-1320.8" rx="43.59" ry="18"/>
<text text-anchor="middle" x="216" y="-1317.1" font-family="inherit" font-size="14.00">get_nav</text>
</a>
</g>
</g>
<!-- on_files&#45;&gt;get_nav -->
<g id="edge5" class="edge">
<title>on_files:s&#45;&gt;get_nav</title>
<g id="a_edge5"><a xlink:title=" ">
<path fill="none" stroke="black" d="M256,-1374.3C256,-1363.19 250.26,-1352.96 243.12,-1344.54"/>
<polygon fill="black" stroke="black" points="245.43,-1341.88 236,-1337.05 240.36,-1346.71 245.43,-1341.88"/>
</a>
</g>
</g>
<!-- render_p -->
<g id="node13" class="node">
<title>render_p</title>
<g id="a_node13"><a xlink:title=" ">
<ellipse fill="#77ff77" fill-opacity="0.533333" stroke="#000000" stroke-opacity="0.600000" cx="88" cy="-847.2" rx="38.19" ry="18"/>
<text text-anchor="middle" x="88" y="-843.5" font-family="inherit" font-size="14.00">render</text>
</a>
</g>
</g>
<!-- on_nav&#45;&gt;render_p -->
<!-- pages_point_a -->
<g id="node14" class="node">
<title>pages_point_a</title>
<g id="a_node14"><a xlink:title=" ">
<ellipse fill="black" stroke="black" cx="305" cy="-1189" rx="1.8" ry="1.8"/>
</a>
</g>
</g>
<!-- on_nav&#45;&gt;pages_point_a -->
<g id="edge12" class="edge">
<title>on_nav:s&#45;&gt;pages_point_a</title>
<g id="a_edge12"><a xlink:title=" ">
<path fill="none" stroke="black" d="M305,-1226.3C305,-1212.18 305,-1194.98 305,-1190.9"/>
</a>
</g>
</g>
<!-- get_context -->
<g id="node22" class="node">
<title>get_context</title>
<g id="a_node22"><a xlink:title=" ">
<ellipse fill="#77ff77" fill-opacity="0.533333" stroke="#000000" stroke-opacity="0.600000" cx="229" cy="-564.6" rx="61.19" ry="18"/>
<text text-anchor="middle" x="229" y="-560.9" font-family="inherit" font-size="14.00">get_context</text>
</a>
</g>
</g>
<!-- on_nav&#45;&gt;get_context -->
<g id="edge28" class="edge">
<title>on_nav:s&#45;&gt;get_context</title>
<g id="a_edge28"><a xlink:title=" ">
<path fill="none" stroke="black" d="M208,-1226.3C208,-1176.78 394.87,-1227.61 428,-1190.8 455.13,-1160.66 433,-1140.25 433,-1099.7 433,-1099.7 433,-1099.7 433,-706.4 433,-656.67 403.87,-645.02 360,-621.6 337.19,-609.42 324.79,-620.79 303.65,-616.51"/>
<polygon fill="black" stroke="black" points="304.58,-613.13 294,-613.6 302.57,-619.84 304.58,-613.13"/>
</a>
</g>
</g>
<!-- load_config&#45;&gt;on_config -->
<g id="edge1" class="edge">
<title>load_config&#45;&gt;on_config:n</title>
<g id="a_edge1"><a xlink:title=" ">
<path fill="none" stroke="black" d="M270,-1618.8C270,-1610.64 270,-1600.5 270,-1590.53"/>
<polygon fill="black" stroke="black" points="273.5,-1590.3 270,-1580.3 266.5,-1590.3 273.5,-1590.3"/>
</a>
</g>
</g>
<!-- get_files&#45;&gt;on_files -->
<g id="edge4" class="edge">
<title>get_files&#45;&gt;on_files:n</title>
<g id="a_edge4"><a xlink:title=" ">
<path fill="none" stroke="black" d="M290.55,-1462.16C276.88,-1452.84 261.92,-1439.27 257.38,-1422.52"/>
<polygon fill="black" stroke="black" points="260.81,-1421.74 256,-1412.3 253.87,-1422.68 260.81,-1421.74"/>
</a>
</g>
</g>
<!-- get_nav&#45;&gt;on_nav -->
<g id="edge6" class="edge">
<title>get_nav&#45;&gt;on_nav:n</title>
<g id="a_edge6"><a xlink:title=" ">
<path fill="none" stroke="black" d="M212.19,-1302.4C210.66,-1294.31 209.09,-1284.32 208.39,-1274.45"/>
<polygon fill="black" stroke="black" points="211.88,-1274.16 208,-1264.3 204.88,-1274.43 211.88,-1274.16"/>
</a>
</g>
</g>
<!-- on_pre_page -->
<g id="node9" class="node">
<title>on_pre_page</title>
<g id="a_node9"><a xlink:title=" ">
<polygon fill="#ffffff" fill-opacity="0.333333" stroke="#000000" stroke-opacity="0.600000" points="88.5,-1080.7 88.5,-1116.7 235.5,-1116.7 235.5,-1080.7 88.5,-1080.7"/>
<text text-anchor="middle" x="112.5" y="-1095" font-family="inherit" font-size="14.00">page</text>
<polyline fill="none" stroke="#000000" stroke-opacity="0.600000" points="136.5,-1080.7 136.5,-1116.7"/>
<text text-anchor="middle" x="164.5" y="-1095" font-family="inherit" font-size="14.00">config</text>
<polyline fill="none" stroke="#000000" stroke-opacity="0.600000" points="192.5,-1080.7 192.5,-1116.7"/>
<text text-anchor="middle" x="214" y="-1095" font-family="inherit" font-size="14.00">files</text>
</a>
</g>
</g>
<!-- on_page_read_source -->
<g id="node10" class="node">
<title>on_page_read_source</title>
<g id="a_node10"><a xlink:title=" ">
<polygon fill="#ffffff" fill-opacity="0.333333" stroke="#000000" stroke-opacity="0.600000" points="72,-996.7 72,-1032.7 176,-1032.7 176,-996.7 72,-996.7"/>
<text text-anchor="middle" x="96" y="-1011" font-family="inherit" font-size="14.00">page</text>
<polyline fill="none" stroke="#000000" stroke-opacity="0.600000" points="120,-996.7 120,-1032.7"/>
<text text-anchor="middle" x="148" y="-1011" font-family="inherit" font-size="14.00">config</text>
</a>
</g>
</g>
<!-- on_pre_page&#45;&gt;on_page_read_source -->
<g id="edge8" class="edge">
<title>on_pre_page:s&#45;&gt;on_page_read_source:n</title>
<g id="a_edge8"><a xlink:title=" ">
<path fill="none" stroke="black" stroke-width="1.5" stroke-dasharray="5,2" d="M112,-1079.7C112,-1061.94 101.23,-1056.93 97.36,-1043.75"/>
<polygon fill="black" stroke="black" stroke-width="1.5" points="100.81,-1043.14 96,-1033.7 93.88,-1044.08 100.81,-1043.14"/>
</a>
</g>
</g>
<!-- on_page_markdown -->
<g id="node11" class="node">
<title>on_page_markdown</title>
<g id="a_node11"><a xlink:title=" ">
<polygon fill="#ffffff" fill-opacity="0.333333" stroke="#000000" stroke-opacity="0.600000" points="37.5,-912.7 37.5,-948.7 268.5,-948.7 268.5,-912.7 37.5,-912.7"/>
<text text-anchor="middle" x="79.5" y="-927" font-family="inherit" font-size="14.00">markdown</text>
<polyline fill="none" stroke="#000000" stroke-opacity="0.600000" points="121.5,-912.7 121.5,-948.7"/>
<text text-anchor="middle" x="145.5" y="-927" font-family="inherit" font-size="14.00">page</text>
<polyline fill="none" stroke="#000000" stroke-opacity="0.600000" points="169.5,-912.7 169.5,-948.7"/>
<text text-anchor="middle" x="197.5" y="-927" font-family="inherit" font-size="14.00">config</text>
<polyline fill="none" stroke="#000000" stroke-opacity="0.600000" points="225.5,-912.7 225.5,-948.7"/>
<text text-anchor="middle" x="247" y="-927" font-family="inherit" font-size="14.00">files</text>
</a>
</g>
</g>
<!-- on_page_read_source&#45;&gt;on_page_markdown -->
<g id="edge9" class="edge">
<title>on_page_read_source:s&#45;&gt;on_page_markdown:n</title>
<g id="a_edge9"><a xlink:title=" ">
<path fill="none" stroke="black" stroke-width="1.5" stroke-dasharray="5,2" d="M122.73,-988.2C116.55,-971.96 89.67,-974.03 81.42,-959.63"/>
<polygon fill="black" stroke="black" stroke-width="1.5" points="84.77,-958.59 79,-949.7 77.97,-960.24 84.77,-958.59"/>
</a>
</g>
</g>
<!-- on_page_markdown&#45;&gt;render_p -->
<g id="edge10" class="edge">
<title>on_page_markdown:s&#45;&gt;render_p</title>
<g id="a_edge10"><a xlink:title=" ">
<path fill="none" stroke="black" stroke-width="1.5" stroke-dasharray="5,2" d="M79,-911.7C79,-899.72 80.59,-886.59 82.43,-875.4"/>
<polygon fill="black" stroke="black" stroke-width="1.5" points="85.91,-875.82 84.24,-865.36 79.02,-874.58 85.91,-875.82"/>
</a>
</g>
</g>
<!-- on_page_content -->
<g id="node12" class="node">
<title>on_page_content</title>
<g id="a_node12"><a xlink:title=" ">
<polygon fill="#ffffff" fill-opacity="0.333333" stroke="#000000" stroke-opacity="0.600000" points="74,-745.7 74,-781.7 268,-781.7 268,-745.7 74,-745.7"/>
<text text-anchor="middle" x="97.5" y="-760" font-family="inherit" font-size="14.00">html</text>
<polyline fill="none" stroke="#000000" stroke-opacity="0.600000" points="121,-745.7 121,-781.7"/>
<text text-anchor="middle" x="145" y="-760" font-family="inherit" font-size="14.00">page</text>
<polyline fill="none" stroke="#000000" stroke-opacity="0.600000" points="169,-745.7 169,-781.7"/>
<text text-anchor="middle" x="197" y="-760" font-family="inherit" font-size="14.00">config</text>
<polyline fill="none" stroke="#000000" stroke-opacity="0.600000" points="225,-745.7 225,-781.7"/>
<text text-anchor="middle" x="246.5" y="-760" font-family="inherit" font-size="14.00">files</text>
</a>
</g>
</g>
<!-- pages_point_b -->
<g id="node16" class="node">
<title>pages_point_b</title>
<g id="a_node16"><a xlink:title=" ">
<ellipse fill="black" stroke="black" cx="326" cy="-707.4" rx="1.8" ry="1.8"/>
</a>
</g>
</g>
<!-- on_page_content&#45;&gt;pages_point_b -->
<g id="edge19" class="edge">
<title>on_page_content:s&#45;&gt;pages_point_b</title>
<g id="a_edge19"><a xlink:title=" ">
<path fill="none" stroke="black" stroke-width="1.5" stroke-dasharray="5,2" d="M97,-744.7C97,-722.45 267.86,-711.55 314.41,-709"/>
<polygon fill="black" stroke="black" stroke-width="1.5" points="314.73,-712.49 324.54,-708.47 314.37,-705.5 314.73,-712.49"/>
</a>
</g>
</g>
<!-- on_env -->
<g id="node18" class="node">
<title>on_env</title>
<g id="a_node18"><a xlink:title=" ">
<polygon fill="#ffffff" fill-opacity="0.333333" stroke="#000000" stroke-opacity="0.600000" points="210.5,-630.1 210.5,-666.1 347.5,-666.1 347.5,-630.1 210.5,-630.1"/>
<text text-anchor="middle" x="229.5" y="-644.4" font-family="inherit" font-size="14.00">env</text>
<polyline fill="none" stroke="#000000" stroke-opacity="0.600000" points="248.5,-630.1 248.5,-666.1"/>
<text text-anchor="middle" x="276.5" y="-644.4" font-family="inherit" font-size="14.00">config</text>
<polyline fill="none" stroke="#000000" stroke-opacity="0.600000" points="304.5,-630.1 304.5,-666.1"/>
<text text-anchor="middle" x="326" y="-644.4" font-family="inherit" font-size="14.00">files</text>
</a>
</g>
</g>
<!-- on_page_content&#45;&gt;on_env -->
<!-- render_p&#45;&gt;on_page_content -->
<g id="edge11" class="edge">
<title>render_p&#45;&gt;on_page_content:n</title>
<g id="a_edge11"><a xlink:title=" ">
<path fill="none" stroke="black" stroke-width="1.5" stroke-dasharray="5,2" d="M91.76,-829.04C93.71,-819 95.85,-805.8 96.66,-792.91"/>
<polygon fill="black" stroke="black" stroke-width="1.5" points="100.16,-792.81 97,-782.7 93.17,-792.58 100.16,-792.81"/>
</a>
</g>
</g>
<!-- pages_point_a&#45;&gt;on_pre_page -->
<g id="edge13" class="edge">
<title>pages_point_a&#45;&gt;on_pre_page:n</title>
<g id="a_edge13"><a xlink:title=" ">
<path fill="none" stroke="black" stroke-width="1.5" stroke-dasharray="5,2" d="M303.35,-1187.97C295.87,-1187.77 264.43,-1186.52 240,-1179.2 183.09,-1162.14 119.89,-1178.63 112.68,-1127.97"/>
<polygon fill="black" stroke="black" stroke-width="1.5" points="116.15,-1127.45 112,-1117.7 109.17,-1127.91 116.15,-1127.45"/>
</a>
</g>
</g>
<!-- pages_point_a&#45;&gt;render_p -->
<g id="edge14" class="edge">
<title>pages_point_a&#45;&gt;render_p</title>
<g id="a_edge14"><a xlink:title=" ">
<path fill="none" stroke="black" d="M304.65,-1187.19C304,-1185.67 302.63,-1182.23 302,-1179.2 290.63,-1124.31 314.02,-979.63 288.52,-918.91"/>
<polygon fill="black" stroke="black" points="291.62,-917.28 284,-909.91 285.36,-920.42 291.62,-917.28"/>
</a>
</g>
</g>
<!-- placeholder_cluster_populate_page_2 -->
<g id="node15" class="node">
<title>placeholder_cluster_populate_page_2</title>
<g id="a_node15"><a xlink:title=" ">
<ellipse fill="none" stroke="none" cx="327" cy="-847.2" rx="27" ry="18"/>
<text text-anchor="middle" x="327" y="-843.5" font-family="inherit" font-size="14.00">...</text>
</a>
</g>
</g>
<!-- pages_point_a&#45;&gt;placeholder_cluster_populate_page_2 -->
<g id="edge15" class="edge">
<title>pages_point_a&#45;&gt;placeholder_cluster_populate_page_2:n</title>
<g id="a_edge15"><a xlink:title=" ">
<path fill="none" stroke="black" stroke-width="1.5" stroke-dasharray="5,2" d="M305.1,-1187.2C306.53,-1175.36 323.3,-1034.9 326.48,-906.23"/>
<polygon fill="black" stroke="black" stroke-width="1.5" points="329.98,-906.27 326.7,-896.2 322.98,-906.12 329.98,-906.27"/>
</a>
</g>
</g>
<!-- placeholder_cluster_populate_page_3 -->
<g id="node17" class="node">
<title>placeholder_cluster_populate_page_3</title>
<g id="a_node17"><a xlink:title=" ">
<ellipse fill="none" stroke="none" cx="349" cy="-763.7" rx="27" ry="18"/>
<text text-anchor="middle" x="349" y="-760" font-family="inherit" font-size="14.00">...</text>
</a>
</g>
</g>
<!-- pages_point_a&#45;&gt;placeholder_cluster_populate_page_3 -->
<g id="edge17" class="edge">
<title>pages_point_a&#45;&gt;placeholder_cluster_populate_page_3:n</title>
<g id="a_edge17"><a xlink:title=" ">
<path fill="none" stroke="black" stroke-width="1.5" stroke-dasharray="5,2" d="M306.14,-1187.29C308.27,-1185.92 312.92,-1182.74 316,-1179.2 371.44,-1115.44 413,-1100.19 413,-1015.7 413,-1015.7 413,-1015.7 413,-929.7 413,-881.43 431.96,-863.11 408,-821.2 407.81,-820.86 407.61,-820.54 407.41,-820.22"/>
<polygon fill="black" stroke="black" stroke-width="1.5" points="409.89,-817.74 400.58,-812.7 404.71,-822.45 409.89,-817.74"/>
</a>
</g>
</g>
<!-- placeholder_cluster_populate_page_2&#45;&gt;pages_point_b -->
<g id="edge16" class="edge">
<title>placeholder_cluster_populate_page_2:s&#45;&gt;pages_point_b</title>
<g id="a_edge16"><a xlink:title=" ">
<path fill="none" stroke="black" stroke-width="1.5" stroke-dasharray="5,2" d="M322.03,-821.2C317.43,-819.39 310.89,-819.17 308,-813.2 291.72,-779.6 294.96,-764.18 308,-729.2 309.91,-724.06 313.73,-719.35 317.36,-715.72"/>
<polygon fill="black" stroke="black" stroke-width="1.5" points="319.79,-718.24 325.08,-709.06 315.22,-712.94 319.79,-718.24"/>
</a>
</g>
</g>
<!-- placeholder_cluster_populate_page_2&#45;&gt;placeholder_cluster_populate_page_3 -->
<!-- pages_point_b&#45;&gt;on_env -->
<g id="edge20" class="edge">
<title>pages_point_b&#45;&gt;on_env:n</title>
<g id="a_edge20"><a xlink:title=" ">
<path fill="none" stroke="black" d="M326,-705.43C326,-701.98 326,-689.85 326,-677.43"/>
<polygon fill="black" stroke="black" points="329.5,-677.1 326,-667.1 322.5,-677.1 329.5,-677.1"/>
</a>
</g>
</g>
<!-- pages_point_c -->
<g id="node19" class="node">
<title>pages_point_c</title>
<g id="a_node19"><a xlink:title=" ">
<ellipse fill="black" stroke="black" cx="454" cy="-648.1" rx="1.8" ry="1.8"/>
</a>
</g>
</g>
<!-- pages_point_b&#45;&gt;pages_point_c -->
<g id="edge21" class="edge">
<title>pages_point_b&#45;&gt;pages_point_c</title>
<g id="a_edge21"><a xlink:title=" ">
<path fill="none" stroke="black" d="M327.33,-706.17C331.95,-705.33 347.7,-702.3 360,-697.6 399.8,-682.4 444.66,-654.92 452.73,-649.9"/>
</a>
</g>
</g>
<!-- placeholder_cluster_populate_page_3&#45;&gt;pages_point_b -->
<g id="edge18" class="edge">
<title>placeholder_cluster_populate_page_3:s&#45;&gt;pages_point_b</title>
<g id="a_edge18"><a xlink:title=" ">
<path fill="none" stroke="black" stroke-width="1.5" stroke-dasharray="5,2" d="M348.02,-737.7C345.7,-729.17 339.67,-721.46 334.5,-716.09"/>
<polygon fill="black" stroke="black" stroke-width="1.5" points="336.72,-713.38 326.99,-709.18 331.97,-718.53 336.72,-713.38"/>
</a>
</g>
</g>
<!-- on_env&#45;&gt;get_context -->
<g id="edge29" class="edge">
<title>on_env:s&#45;&gt;get_context</title>
<g id="a_edge29"><a xlink:title=" ">
<path fill="none" stroke="black" d="M229,-629.1C229,-627.37 229,-625.62 229,-623.85"/>
<polygon fill="black" stroke="black" points="232.5,-623.6 229,-613.6 225.5,-623.6 232.5,-623.6"/>
</a>
</g>
</g>
<!-- on_page_context -->
<g id="node20" class="node">
<title>on_page_context</title>
<g id="a_node20"><a xlink:title=" ">
<polygon fill="#ffffff" fill-opacity="0.333333" stroke="#000000" stroke-opacity="0.600000" points="174.5,-463.1 174.5,-499.1 381.5,-499.1 381.5,-463.1 174.5,-463.1"/>
<text text-anchor="middle" x="207" y="-477.4" font-family="inherit" font-size="14.00">context</text>
<polyline fill="none" stroke="#000000" stroke-opacity="0.600000" points="239.5,-463.1 239.5,-499.1"/>
<text text-anchor="middle" x="263.5" y="-477.4" font-family="inherit" font-size="14.00">page</text>
<polyline fill="none" stroke="#000000" stroke-opacity="0.600000" points="287.5,-463.1 287.5,-499.1"/>
<text text-anchor="middle" x="315.5" y="-477.4" font-family="inherit" font-size="14.00">config</text>
<polyline fill="none" stroke="#000000" stroke-opacity="0.600000" points="343.5,-463.1 343.5,-499.1"/>
<text text-anchor="middle" x="362.5" y="-477.4" font-family="inherit" font-size="14.00">nav</text>
</a>
</g>
</g>
<!-- pages_point_c&#45;&gt;on_page_context -->
<g id="edge22" class="edge">
<title>pages_point_c&#45;&gt;on_page_context:n</title>
<g id="a_edge22"><a xlink:title=" ">
<path fill="none" stroke="black" stroke-width="1.5" stroke-dasharray="5,2" d="M453.63,-645.9C452.27,-641.79 447.22,-628.11 438,-621.6 424.61,-612.15 415.2,-623.31 402,-613.6 371.05,-590.83 387.99,-563.81 359,-538.6 327.29,-511.03 273.34,-540.1 264.3,-510.2"/>
<polygon fill="black" stroke="black" stroke-width="1.5" points="267.75,-509.57 263,-500.1 260.81,-510.47 267.75,-509.57"/>
</a>
</g>
</g>
<!-- pages_point_c&#45;&gt;get_context -->
<!-- placeholder_cluster_build_page_2 -->
<g id="node26" class="node">
<title>placeholder_cluster_build_page_2</title>
<g id="a_node26"><a xlink:title=" ">
<ellipse fill="none" stroke="none" cx="455" cy="-564.6" rx="27" ry="18"/>
<text text-anchor="middle" x="455" y="-560.9" font-family="inherit" font-size="14.00">...</text>
</a>
</g>
</g>
<!-- pages_point_c&#45;&gt;placeholder_cluster_build_page_2 -->
<g id="edge30" class="edge">
<title>pages_point_c&#45;&gt;placeholder_cluster_build_page_2:n</title>
<g id="a_edge30"><a xlink:title=" ">
<path fill="none" stroke="black" stroke-width="1.5" stroke-dasharray="5,2" d="M454.02,-646.2C454.1,-643.5 454.33,-634.89 454.54,-623.84"/>
<polygon fill="black" stroke="black" stroke-width="1.5" points="458.05,-623.66 454.72,-613.6 451.05,-623.53 458.05,-623.66"/>
</a>
</g>
</g>
<!-- placeholder_cluster_build_page_3 -->
<g id="node27" class="node">
<title>placeholder_cluster_build_page_3</title>
<g id="a_node27"><a xlink:title=" ">
<ellipse fill="none" stroke="none" cx="459" cy="-481.1" rx="27" ry="18"/>
<text text-anchor="middle" x="459" y="-477.4" font-family="inherit" font-size="14.00">...</text>
</a>
</g>
</g>
<!-- pages_point_c&#45;&gt;placeholder_cluster_build_page_3 -->
<g id="edge31" class="edge">
<title>pages_point_c&#45;&gt;placeholder_cluster_build_page_3:n</title>
<g id="a_edge31"><a xlink:title=" ">
<path fill="none" stroke="black" stroke-width="1.5" stroke-dasharray="5,2" d="M455.41,-646.55C461.75,-644.01 487.69,-632.65 497,-613.6 511.63,-583.65 509.66,-569.44 497,-538.6 496.96,-538.49 496.91,-538.38 496.86,-538.27"/>
<polygon fill="black" stroke="black" stroke-width="1.5" points="499.88,-536.48 491.42,-530.1 494.05,-540.36 499.88,-536.48"/>
</a>
</g>
</g>
<!-- render -->
<g id="node23" class="node">
<title>render</title>
<g id="a_node23"><a xlink:title=" ">
<ellipse fill="#77ff77" fill-opacity="0.533333" stroke="#000000" stroke-opacity="0.600000" cx="148" cy="-408.6" rx="38.19" ry="18"/>
<text text-anchor="middle" x="148" y="-404.9" font-family="inherit" font-size="14.00">render</text>
</a>
</g>
</g>
<!-- on_page_context&#45;&gt;render -->
<g id="edge24" class="edge">
<title>on_page_context:s&#45;&gt;render</title>
<g id="a_edge24"><a xlink:title=" ">
<path fill="none" stroke="black" d="M207,-462.1C207,-447.17 196.33,-435.45 184.06,-426.9"/>
<polygon fill="black" stroke="black" points="185.76,-423.83 175.43,-421.49 182.04,-429.76 185.76,-423.83"/>
</a>
</g>
</g>
<!-- on_post_page -->
<g id="node21" class="node">
<title>on_post_page</title>
<g id="a_node21"><a xlink:title=" ">
<polygon fill="#ffffff" fill-opacity="0.333333" stroke="#000000" stroke-opacity="0.600000" points="117,-315.1 117,-351.1 283,-351.1 283,-315.1 117,-315.1"/>
<text text-anchor="middle" x="148" y="-329.4" font-family="inherit" font-size="14.00">output</text>
<polyline fill="none" stroke="#000000" stroke-opacity="0.600000" points="179,-315.1 179,-351.1"/>
<text text-anchor="middle" x="203" y="-329.4" font-family="inherit" font-size="14.00">page</text>
<polyline fill="none" stroke="#000000" stroke-opacity="0.600000" points="227,-315.1 227,-351.1"/>
<text text-anchor="middle" x="255" y="-329.4" font-family="inherit" font-size="14.00">config</text>
</a>
</g>
</g>
<!-- write_file -->
<g id="node25" class="node">
<title>write_file</title>
<g id="a_node25"><a xlink:title=" ">
<ellipse fill="#77ff77" fill-opacity="0.533333" stroke="#000000" stroke-opacity="0.600000" cx="148" cy="-260.6" rx="50.09" ry="18"/>
<text text-anchor="middle" x="148" y="-256.9" font-family="inherit" font-size="14.00">write_file</text>
</a>
</g>
</g>
<!-- on_post_page&#45;&gt;write_file -->
<g id="edge27" class="edge">
<title>on_post_page:s&#45;&gt;write_file</title>
<g id="a_edge27"><a xlink:title=" ">
<path fill="none" stroke="black" d="M148,-314.1C148,-305.86 148,-296.9 148,-288.74"/>
<polygon fill="black" stroke="black" points="151.5,-288.62 148,-278.62 144.5,-288.62 151.5,-288.62"/>
</a>
</g>
</g>
<!-- get_context&#45;&gt;on_page_context -->
<g id="edge23" class="edge">
<title>get_context&#45;&gt;on_page_context:n</title>
<g id="a_edge23"><a xlink:title=" ">
<path fill="none" stroke="black" d="M219.67,-546.63C214.89,-536.68 209.68,-523.49 207.76,-510.21"/>
<polygon fill="black" stroke="black" points="211.24,-509.81 207,-500.1 204.26,-510.34 211.24,-509.81"/>
</a>
</g>
</g>
<!-- render&#45;&gt;on_post_page -->
<g id="edge26" class="edge">
<title>render&#45;&gt;on_post_page:n</title>
<g id="a_edge26"><a xlink:title=" ">
<path fill="none" stroke="black" d="M148,-390.6C148,-382.44 148,-372.3 148,-362.33"/>
<polygon fill="black" stroke="black" points="151.5,-362.1 148,-352.1 144.5,-362.1 151.5,-362.1"/>
</a>
</g>
</g>
<!-- get_template -->
<g id="node24" class="node">
<title>get_template</title>
<g id="a_node24"><a xlink:title=" ">
<ellipse fill="#77ff77" fill-opacity="0.533333" stroke="#000000" stroke-opacity="0.600000" cx="90" cy="-481.1" rx="66.09" ry="18"/>
<text text-anchor="middle" x="90" y="-477.4" font-family="inherit" font-size="14.00">get_template</text>
</a>
</g>
</g>
<!-- get_template&#45;&gt;render -->
<g id="edge25" class="edge">
<title>get_template&#45;&gt;render</title>
<g id="a_edge25"><a xlink:title=" ">
<path fill="none" stroke="black" d="M103.75,-463.39C111.07,-454.49 120.22,-443.37 128.29,-433.56"/>
<polygon fill="black" stroke="black" points="131.1,-435.65 134.75,-425.7 125.7,-431.2 131.1,-435.65"/>
</a>
</g>
</g>
<!-- on_post_build -->
<g id="node28" class="node">
<title>on_post_build</title>
<g id="a_node28"><a xlink:title=" ">
<polygon fill="#ffffff" fill-opacity="0.333333" stroke="#000000" stroke-opacity="0.600000" points="120,-159.1 120,-195.1 176,-195.1 176,-159.1 120,-159.1"/>
<text text-anchor="middle" x="148" y="-173.4" font-family="inherit" font-size="14.00">config</text>
</a>
</g>
</g>
<!-- write_file&#45;&gt;on_post_build -->
<!-- placeholder_cluster_build_page_2&#45;&gt;placeholder_cluster_build_page_3 -->
<!-- on_serve -->
<g id="node29" class="node">
<title>on_serve</title>
<g id="a_node29"><a xlink:title=" ">
<polygon fill="#ffffff" fill-opacity="0.333333" stroke="#000000" stroke-opacity="0.600000" points="92,-67.1 92,-103.1 204,-103.1 204,-67.1 92,-67.1"/>
<text text-anchor="middle" x="120" y="-81.4" font-family="inherit" font-size="14.00">server</text>
<polyline fill="none" stroke="#000000" stroke-opacity="0.600000" points="148,-67.1 148,-103.1"/>
<text text-anchor="middle" x="176" y="-81.4" font-family="inherit" font-size="14.00">config</text>
</a>
</g>
</g>
<!-- on_post_build&#45;&gt;on_serve -->
<!-- on_shutdown -->
<g id="node30" class="node">
<title>on_shutdown</title>
<g id="a_node30"><a xlink:title=" ">
<ellipse fill="#ffffff" fill-opacity="0.333333" stroke="#000000" stroke-opacity="0.600000" cx="148" cy="-17.8" rx="1.8" ry="1.8"/>
</a>
</g>
</g>
<!-- on_serve&#45;&gt;on_shutdown -->
</g>
</svg>

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

View File

@@ -0,0 +1,89 @@
# MkDocs
Project documentation with&nbsp;Markdown.
---
MkDocs is a **fast**, **simple** and **downright gorgeous** static site
generator that's geared towards building project documentation. Documentation
source files are written in Markdown, and configured with a single YAML
configuration file. Start by reading the [introductory tutorial], then check the
[User Guide] for more information.
[introductory tutorial]: getting-started.md
[User Guide]: user-guide/README.md
<div class="text-center">
<a href="getting-started/" class="btn btn-primary" role="button">Getting Started</a>
<a href="user-guide/" class="btn btn-primary" role="button">User Guide</a>
</div>
<div class="pt-2 pb-4 px-4 my-4 bg-body-tertiary rounded-3">
<h2 class="display-4 text-center">Features</h2>
<div class="row">
<div class="col-sm-6">
<div class="card mb-4">
<div class="card-body">
<h3 class="card-title">Great themes available</h3>
<p class="card-text">
There's a stack of good looking <a href="user-guide/choosing-your-theme">themes</a> available for MkDocs.
Choose between the built in themes:
<a href="user-guide/choosing-your-theme/#mkdocs">mkdocs</a> and
<a href="user-guide/choosing-your-theme/#readthedocs">readthedocs</a>,
select one of the third-party themes
(on the <a href="https://github.com/mkdocs/mkdocs/wiki/MkDocs-Themes">MkDocs Themes</a> wiki page
as well as the <a href="https://github.com/mkdocs/catalog#-theming">MkDocs Catalog</a>),
or <a href="dev-guide/themes/">build your own</a>.
</p>
</div>
</div>
</div>
<div class="col-sm-6">
<div class="card mb-4">
<div class="card-body">
<h3 class="card-title">Easy to customize</h3>
<p class="card-text">
Get your project documentation looking just the way you want it by
<a href="user-guide/customizing-your-theme/">customizing your
theme</a> and/or installing some <a
href="user-guide/configuration/#plugins">plugins</a>. Modify
Markdown's behavior with <a
href="user-guide/configuration/#markdown_extensions">Markdown
extensions</a>. Many <a
href="user-guide/configuration/">configuration options</a> are
available.
</p>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-6">
<div class="card">
<div class="card-body">
<h3 class="card-title">Preview your site as you work</h3>
<p class="card-text">
The built-in dev-server allows you to preview your documentation
as you're writing it. It will even auto-reload and refresh your
browser whenever you save your changes.
</p>
</div>
</div>
</div>
<div class="col-sm-6">
<div class="card">
<div class="card-body">
<h3 class="card-title">Host anywhere</h3>
<p class="card-text">
MkDocs builds completely static HTML sites that you can host on
GitHub Pages, Amazon S3, or <a
href="user-guide/deploying-your-docs/">anywhere</a> else you
choose.
</p>
</div>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,21 @@
# User Guide
Building Documentation with MkDocs
---
The MkDocs User Guide provides documentation for users of MkDocs. See
[Getting Started] for an introductory tutorial. You can jump directly to a
page listed below, or use the *next* and *previous* buttons in the navigation
bar at the top of the page to move through the documentation in order.
- [Installation](installation.md)
- [Writing Your Docs](writing-your-docs.md)
- [Choosing Your Theme](choosing-your-theme.md)
- [Customizing Your Theme](customizing-your-theme.md)
- [Localizing Your Theme](localizing-your-theme.md)
- [Configuration](configuration.md)
- [Command Line Interface](cli.md)
- [Deploying Your Docs](deploying-your-docs.md)
[Getting Started]: ../getting-started.md

View File

@@ -0,0 +1,229 @@
# Choosing your Theme
Selecting and configuring a theme.
---
MkDocs includes two built-in themes ([mkdocs](#mkdocs) and
[readthedocs](#readthedocs)), as documented below. However, many [third party
themes] are available to choose from as well.
To choose a theme, set the [theme] configuration option in your `mkdocs.yml`
config file.
```yaml
theme:
name: readthedocs
```
## mkdocs
The default theme, which was built as a custom [Bootstrap] theme, supports almost
every feature of MkDocs.
<div id="mkdocs-theme-images" class="carousel slide carousel-fade" data-bs-ride="carousel">
<div class="carousel-inner">
<div class="carousel-item active">
<img src="../../img/mkdocs_theme_light_mode.png" class="d-block w-100" alt="MkDocs theme in light mode">
</div>
<div class="carousel-item">
<img src="../../img/mkdocs_theme_dark_mode.png" class="d-block w-100" alt="MkDocs theme in dark mode">
</div>
</div>
</div>
In addition to the default [theme configuration options][theme], the `mkdocs` theme
supports the following options:
* **`color_mode`**: Set the default color mode for the theme to one of `light`,
`dark`, or `auto`. The `auto` mode will switch to `light` or `dark` based on
the system configuration of the user's device. Default: `light`.
* **`user_color_mode_toggle`**: Enable a toggle menu in the navigation bar
which allows users to select their preferred `color_mode` (light, dark, auto)
from within the browser and save their preference for future page loads. The
default selection of the toggle menu on first page load is the value set to
`color_mode`. Default: `false`.
![color mode toggle menu](../img/color_mode_toggle_menu.png)
* **`nav_style`**: Adjust the visual style of the top navigation bar. Set to
one of `primary`, `dark` or `light`. Default: `primary`. This option is
independent of the `color_mode` option and must be defined separately.
* **`highlightjs`**: Enables highlighting of source code in code blocks using
the [highlight.js] JavaScript library. Default: `True`.
* **`hljs_style`**: The highlight.js library provides many different [styles]
(color variations) for highlighting source code in code blocks. Set this to
the name of the desired style when in `light` mode. Default: `github`.
* **`hljs_style_dark`**: Set this to the name of the desired highlight.js
style when in `dark` mode. Default: `github_dark`.
* **`hljs_languages`**: By default, highlight.js only supports 23 common
languages. List additional languages here to include support for them.
```yaml
theme:
name: mkdocs
highlightjs: true
hljs_languages:
- yaml
- rust
```
* **`analytics`**: Defines configuration options for an analytics service.
Currently, only Google Analytics v4 is supported via the `gtag` option.
* **`gtag`**: To enable Google Analytics, set to a Google Analytics v4
tracking ID, which uses the `G-` format. See Google's documentation to
[Set up Analytics for a website and/or app (GA4)][setup-GA4] or to
[Upgrade to a Google Analytics 4 property][upgrade-GA4].
```yaml
theme:
name: mkdocs
analytics:
gtag: G-ABC123
```
When set to the default (`null`) Google Analytics is disabled for the
site.
* **`shortcuts`**: Defines keyboard shortcut keys.
```yaml
theme:
name: mkdocs
shortcuts:
help: 191 # ?
next: 78 # n
previous: 80 # p
search: 83 # s
```
All values must be numeric key codes. It is best to use keys that are
available on all keyboards. You may use <https://keycode.info/> to determine
the key code for a given key.
* **`help`**: Display a help modal that lists the keyboard shortcuts.
Default: `191` (&quest;)
* **`next`**: Navigate to the "next" page. Default: `78` (n)
* **`previous`**: Navigate to the "previous" page. Default: `80` (p)
* **`search`**: Display the search modal. Default: `83` (s)
* **`navigation_depth`**: The maximum depth of the navigation tree in the
sidebar. Default: `2`.
* **`locale`**{ #mkdocs-locale }: The locale (language/location) used to
build the theme. If your locale is not yet supported, it will fall back
to the default.
The following locales are supported by this theme:
* `en`: English (default)
* (see the list of existing directories `mkdocs/themes/mkdocs/locales/*/`)
See the guide on [localizing your theme] for more information.
## readthedocs
A clone of the default theme used by the [Read the Docs] service, which offers
the same restricted feature set as its parent theme. Like its parent theme, only
two levels of navigation are supported.
![ReadTheDocs](../img/readthedocs.png)
In addition to the default [theme configuration options][theme], the `readthedocs`
theme supports the following options:
* **`highlightjs`**: Enables highlighting of source code in code blocks using
the [highlight.js] JavaScript library. Default: `True`.
* **`hljs_languages`**: By default, highlight.js only supports 23 common
languages. List additional languages here to include support for them.
```yaml
theme:
name: readthedocs
highlightjs: true
hljs_languages:
- yaml
- rust
```
* **`analytics`**: Defines configuration options for an analytics service.
* **`gtag`**: To enable Google Analytics, set to a Google Analytics v4
tracking ID, which uses the `G-` format. See Google's documentation to
[Set up Analytics for a website and/or app (GA4)][setup-GA4] or to
[Upgrade to a Google Analytics 4 property][upgrade-GA4].
```yaml
theme:
name: readthedocs
analytics:
gtag: G-ABC123
```
When set to the default (`null`) Google Analytics is disabled for the
* **`anonymize_ip`**: To enable anonymous IP address for Google Analytics,
set this to `True`. Default: `False`.
* **`include_homepage_in_sidebar`**: Lists the homepage in the sidebar menu. As
MkDocs requires that the homepage be listed in the `nav` configuration
option, this setting allows the homepage to be included or excluded from
the sidebar. Note that the site name/logo always links to the homepage.
Default: `True`.
* **`prev_next_buttons_location`**: One of `bottom`, `top`, `both` , or `none`.
Displays the “Next” and “Previous” buttons accordingly. Default: `bottom`.
* **`navigation_depth`**: The maximum depth of the navigation tree in the
sidebar. Default: `4`.
* **`collapse_navigation`**: Only include the page section headers in the
sidebar for the current page. Default: `True`.
* **`titles_only`**: Only include page titles in the sidebar, excluding all
section headers for all pages. Default: `False`.
* **`sticky_navigation`**: If True, causes the sidebar to scroll with the main
page content as you scroll the page. Default: `True`.
* **`locale`**{ #readthedocs-locale }: The locale (language/location) used to
build the theme. If your locale is not yet supported, it will fall back
to the default.
The following locales are supported by this theme:
* `en`: English (default)
* (see the list of existing directories `mkdocs/themes/readthedocs/locales/*/`)
See the guide on [localizing your theme] for more information.
* **`logo`**: To set a logo on your project instead of the plain text
`site_name`, set this variable to be the location of your image. Default: `null`.
## Third Party Themes
A list of third party themes can be found at the [community wiki] page and [the ranked catalog][catalog]. If you have created your own, please add them there.
WARNING: Installing an MkDocs theme means installing a Python package and executing any code that the author has put in there. So, exercise the usual caution; there's no attempt at sandboxing.
[third party themes]: #third-party-themes
[theme]: configuration.md#theme
[Bootstrap]: https://getbootstrap.com/
[highlight.js]: https://highlightjs.org/
[styles]: https://highlightjs.org/static/demo/
[setup-GA4]: https://support.google.com/analytics/answer/9304153?hl=en&ref_topic=9303319
[upgrade-GA4]: https://support.google.com/analytics/answer/9744165?hl=en&ref_topic=9303319
[Read the Docs]: https://readthedocs.org/
[community wiki]: https://github.com/mkdocs/mkdocs/wiki/MkDocs-Themes
[catalog]: https://github.com/mkdocs/catalog#-theming
[localizing your theme]: localizing-your-theme.md

View File

@@ -0,0 +1,8 @@
# Command Line Interface
::: mkdocs-click
:module: mkdocs.__main__
:command: cli
:prog_name: mkdocs
:style: table
:list_subcommands: true

View File

@@ -0,0 +1,226 @@
# Customizing Your Theme
Altering a theme to suit your needs.
---
If you would like to make a few tweaks to an existing theme, there is no need
to create your own theme from scratch. For minor tweaks which only require
some CSS and/or JavaScript, you can [use the docs_dir](#using-the-docs_dir).
However, for more complex customizations, including overriding templates, you
will need to [use the theme custom_dir](#using-the-theme-custom_dir) setting.
## Using the docs_dir
The [extra_css] and [extra_javascript] configuration options can be used to
make tweaks and customizations to existing themes. To use these, you simply
need to include either CSS or JavaScript files within your [documentation
directory].
For example, to change the color of the headers in your documentation, create
a file called (for example) `style.css` and place it next to the documentation Markdown. In
that file add the following CSS.
```css
h1 {
color: red;
}
```
Then you need to add it to `mkdocs.yml`:
```yaml
extra_css:
- style.css
```
After making these changes, they should be visible when you run
`mkdocs serve` - if you already had this running, you should see that the CSS
changes were automatically picked up and the documentation will be updated.
NOTE:
Any extra CSS or JavaScript files will be added to the generated HTML
document after the page content. If you desire to include a JavaScript
library, you may have better success including the library by using the
theme [custom_dir].
## Using the theme custom_dir
The [`theme.custom_dir`][custom_dir] configuration option can be used to point
to a directory of files which override the files in a parent theme. The parent
theme would be the theme defined in the [`theme.name`][name] configuration
option. Any file in the `custom_dir` with the same name as a file in the
parent theme will replace the file of the same name in the parent theme. Any
additional files in the `custom_dir` will be added to the parent theme. The
contents of the `custom_dir` should mirror the directory structure of the
parent theme. You may include templates, JavaScript files, CSS files, images,
fonts, or any other media included in a theme.
NOTE:
For this to work, the `theme.name` setting must be set to a known
installed theme. If the `name` setting is instead set to `null` (or not
defined), then there is no theme to override and the contents of the
`custom_dir` must be a complete, standalone theme. See the [Theme
Developer Guide][custom theme] for more information.
For example, the [mkdocs] theme ([browse source]), contains the following
directory structure (in part):
```text
- css\
- fonts\
- img\
- favicon.ico
- grid.png
- js\
- 404.html
- base.html
- content.html
- nav-sub.html
- nav.html
- toc.html
```
To override any of the files contained in that theme, create a new directory
next to your `docs_dir`:
```bash
mkdir custom_theme
```
And then point your `mkdocs.yml` configuration file at the new directory:
```yaml
theme:
name: mkdocs
custom_dir: custom_theme/
```
To override the 404 error page ("file not found"), add a new template file named
`404.html` to the `custom_theme` directory. For information on what can be
included in a template, review the [Theme Developer Guide][custom theme].
To override the favicon, you can add a new icon file at
`custom_theme/img/favicon.ico`.
To include a JavaScript library, copy the library to the `custom_theme/js/`
directory.
Your directory structure should now look like this:
```text
- docs/
- index.html
- custom_theme/
- img/
- favicon.ico
- js/
- somelib.js
- 404.html
- config.yml
```
NOTE:
Any files included in the parent theme (defined in `name`) but not
included in the `custom_dir` will still be utilized. The `custom_dir` will
only override/replace files in the parent theme. If you want to remove
files, or build a theme from scratch, then you should review the [Theme
Developer Guide][custom theme].
### Overriding Template Blocks
The built-in themes implement many of their parts inside template blocks which
can be individually overridden in the `main.html` template. Simply create a
`main.html` template file in your `custom_dir` and define replacement blocks
within that file. Just make sure that the `main.html` extends `base.html`. For
example, to alter the title of the MkDocs theme, your replacement `main.html`
template would contain the following:
```django
{% extends "base.html" %}
{% block htmltitle %}
<title>Custom title goes here</title>
{% endblock %}
```
In the above example, the `htmltitle` block defined in your custom `main.html` file
will be used in place of the default `htmltitle` block defined in the parent theme.
You may re-define as many blocks as you desire, as long as those blocks are
defined in the parent. For example, you could replace the Google Analytics
script with one for a different service or replace the search feature with your
own. You will need to consult the parent theme you are using to determine what
blocks are available to override. The MkDocs and ReadTheDocs themes provide the
following blocks:
* `site_meta`: Contains meta tags in the document head.
* `htmltitle`: Contains the page title in the document head.
* `styles`: Contains the link tags for stylesheets.
* `libs`: Contains the JavaScript libraries (jQuery, etc) included in the page header.
* `scripts`: Contains JavaScript scripts which should execute after a page loads.
* `analytics`: Contains the analytics script.
* `extrahead`: An empty block in the `<head>` to insert custom tags/scripts/etc.
* `site_name`: Contains the site name in the navigation bar.
* `site_nav`: Contains the site navigation in the navigation bar.
* `search_button`: Contains the search box in the navigation bar.
* `next_prev`: Contains the next and previous buttons in the navigation bar.
* `repo`: Contains the repository link in the navigation bar.
* `content`: Contains the page content and table of contents for the page.
* `footer`: Contains the page footer.
You may need to view the source template files to ensure your modifications will
work with the structure of the site. See [Template Variables] for a list of
variables you can use within your custom blocks. For a more complete
explanation of blocks, consult the [Jinja documentation].
### Combining the custom_dir and Template Blocks
Adding a JavaScript library to the `custom_dir` will make it available, but
won't include it in the pages generated by MkDocs. Therefore, a link needs to
be added to the library from the HTML.
Starting the with directory structure above (truncated):
```text
- docs/
- custom_theme/
- js/
- somelib.js
- config.yml
```
A link to the `custom_theme/js/somelib.js` file needs to be added to the
template. As `somelib.js` is a JavaScript library, it would logically go in the
`libs` block. However, a new `libs` block that only includes the new script will
replace the block defined in the parent template and any links to libraries in
the parent template will be removed. To avoid breaking the template, a
[super block] can be used with a call to `super` from within the block:
```django
{% extends "base.html" %}
{% block libs %}
{{ super() }}
<script src="{{ base_url }}/js/somelib.js"></script>
{% endblock %}
```
Note that the [base_url] template variable was used to ensure that the link is
always relative to the current page.
Now the generated pages will include links to the template provided libraries as
well as the library included in the `custom_dir`. The same would be required for
any additional CSS files included in the `custom_dir`.
[custom theme]: ../dev-guide/themes.md
[extra_css]: ./configuration.md#extra_css
[extra_javascript]: ./configuration.md#extra_javascript
[documentation directory]: ./configuration.md#docs_dir
[custom_dir]: ./configuration.md#custom_dir
[name]: ./configuration.md#name
[mkdocs]: ./choosing-your-theme.md#mkdocs
[browse source]: https://github.com/mkdocs/mkdocs/tree/master/mkdocs/themes/mkdocs
[Template Variables]: ../dev-guide/themes.md#template-variables
[Jinja documentation]: https://jinja.palletsprojects.com/en/latest/templates/#template-inheritance
[super block]: https://jinja.palletsprojects.com/en/latest/templates/#super-blocks
[base_url]: ../dev-guide/themes.md#base_url

View File

@@ -0,0 +1,223 @@
# Deploying your docs
A basic guide to deploying your docs to various hosting providers
---
## GitHub Pages
If you host the source code for a project on [GitHub], you can easily use
[GitHub Pages] to host the documentation for your project. There are two basic
[types of GitHub Pages sites]: Project Pages sites, and User and Organization
Pages sites. They are nearly identical but have some important differences,
which require a different work flow when deploying.
### Project Pages
Project Pages sites are simpler as the site files get deployed to a branch
within the project repository (`gh-pages` by default). After you `checkout` the
primary working branch (usually `master`) of the git repository where you
maintain the source documentation for your project, run the following command:
```sh
mkdocs gh-deploy
```
That's it! Behind the scenes, MkDocs will build your docs and use the
[ghp-import] tool to commit them to the `gh-pages` branch and push the
`gh-pages` branch to GitHub.
Use `mkdocs gh-deploy --help` to get a full list of options available for the
`gh-deploy` command.
Be aware that you will not be able to review the built site before it is pushed
to GitHub. Therefore, you may want to verify any changes you make to the docs
beforehand by using the `build` or `serve` commands and reviewing the built
files locally.
WARNING:
You should never edit files in your pages repository by hand if you're using
the `gh-deploy` command because you will lose your work the next time you
run the command.
WARNING:
If there are untracked files or uncommitted work in the local repository where
`mkdocs gh-deploy` is run, these will be included in the pages that are deployed.
### Organization and User Pages
User and Organization Pages sites are not tied to a specific project, and the
site files are deployed to the `master` branch in a dedicated repository named
with the GitHub account name. Therefore, you need working copies of two
repositories on our local system. For example, consider the following file
structure:
```text
my-project/
mkdocs.yml
docs/
orgname.github.io/
```
After making and verifying updates to your project you need to change
directories to the `orgname.github.io` repository and call the
`mkdocs gh-deploy` command from there:
```sh
cd ../orgname.github.io/
mkdocs gh-deploy --config-file ../my-project/mkdocs.yml --remote-branch master
```
Note that you need to explicitly point to the `mkdocs.yml` configuration file as
it is no longer in the current working directory. You also need to inform the
deploy script to commit to the `master` branch. You may override the default
with the [remote_branch] configuration setting, but if you forget to change
directories before running the deploy script, it will commit to the `master`
branch of your project, which you probably don't want.
### Custom Domains
GitHub Pages includes support for using a [Custom Domain] for your site. In
addition to the steps documented by GitHub, you need to take one additional step
so that MkDocs will work with your custom domain. You need to add a `CNAME` file
to the root of your [docs_dir]. The file must contain a single bare domain or
subdomain on a single line (see MkDocs' own [CNAME file] as an example). You may
create the file manually, or use GitHub's web interface to set up the custom
domain (under Settings / Custom Domain). If you use the web interface, GitHub
will create the `CNAME` file for you and save it to the root of your "pages"
branch. So that the file does not get removed the next time you deploy, you need
to copy the file to your `docs_dir`. With the file properly included in your
`docs_dir`, MkDocs will include the file in your built site and push it to your
"pages" branch each time you run the `gh-deploy` command.
If you are having problems getting a custom domain to work, see GitHub's
documentation on [Troubleshooting custom domains].
[GitHub]: https://github.com/
[GitHub Pages]: https://pages.github.com/
[types of GitHub Pages sites]: https://docs.github.com/en/pages/getting-started-with-github-pages/about-github-pages#types-of-github-pages-sites
[ghp-import]: https://github.com/davisp/ghp-import
[remote_branch]: ./configuration.md#remote_branch
[Custom Domain]: https://help.github.com/articles/adding-or-removing-a-custom-domain-for-your-github-pages-site
[docs_dir]: ./configuration.md#docs_dir
[CNAME file]: https://github.com/mkdocs/mkdocs/blob/master/docs/CNAME
[Troubleshooting custom domains]: https://help.github.com/articles/troubleshooting-custom-domains/
## Read the Docs
[Read the Docs][rtd] offers free documentation hosting. You can import your docs
using the Git version control system. Read the Docs supports MkDocs out-of-the-box.
Follow the [instructions] on their site to arrange the files in your repository properly,
create an account and point it at your publicly hosted repository. If properly
configured, your documentation will update each time you push commits to your
public repository.
[rtd]: https://readthedocs.org/
[instructions]: https://docs.readthedocs.io/en/stable/intro/getting-started-with-mkdocs.html
## Other Providers
Any hosting provider which can serve static files can be used to serve
documentation generated by MkDocs. While it would be impossible to document how
to upload the docs to every hosting provider out there, the following guidelines
should provide some general assistance.
When you build your site (using the `mkdocs build` command), all of the files
are written to the directory assigned to the [site_dir] configuration option
(defaults to `"site"`) in your `mkdocs.yaml` config file. Generally, you will
simply need to copy the contents of that directory to the root directory of your
hosting provider's server. Depending on your hosting provider's setup, you may
need to use a graphical or command line [ftp], [ssh] or [scp] client to transfer
the files.
For example, a typical set of commands from the command line might look
something like this:
```sh
mkdocs build
scp -r ./site user@host:/path/to/server/root
```
Of course, you will need to replace `user` with the username you have with your
hosting provider and `host` with the appropriate domain name. Additionally, you
will need to adjust the `/path/to/server/root` to match the configuration of
your hosts' file system.
[ftp]: https://en.wikipedia.org/wiki/File_Transfer_Protocol
[ssh]: https://en.wikipedia.org/wiki/Secure_Shell
[scp]: https://en.wikipedia.org/wiki/Secure_copy
See your host's documentation for specifics. You will likely want to search
their documentation for "ftp" or "uploading site".
## Local Files
Rather than hosting your documentation on a server, you may instead distribute
the files directly, which can then be viewed in a browser using the `file://`
scheme.
Note that, due to the security settings of all modern browsers, some things
will not work the same and some features may not work at all. In fact, a few
settings will need to be customized in very specific ways.
- [site_url]:
The `site_url` must be set to an empty string, which instructs MkDocs to
build your site so that it will work with the `file://` scheme.
```yaml
site_url: ""
```
- [use_directory_urls]:
Set `use_directory_urls` to `false`. Otherwise, internal links between
pages will not work properly.
```yaml
use_directory_urls: false
```
- [search]:
You will need to either disable the search plugin, or use a third-party
search plugin which is specifically designed to work with the `file://`
scheme. To disable all plugins, set the `plugins` setting to an empty list.
```yaml
plugins: []
```
If you have other plugins enabled, simply ensure that `search` is not
included in the list.
When writing your documentation, it is imperative that all internal links use
relative URLs as [documented][internal links]. Remember, each reader of your
documentation will be using a different device and the files will likely be in a
different location on that device.
If you expect your documentation to be viewed off-line, you may also need to be
careful about which themes you choose. Many themes make use of CDNs for various
support files, which require a live Internet connection. You will need to choose
a theme which includes all support files directly in the theme.
When you build your site (using the `mkdocs build` command), all of the files
are written to the directory assigned to the [site_dir] configuration option
(defaults to `"site"`) in your `mkdocs.yaml` config file. Generally, you will
simply need to copy the contents of that directory and distribute it to your
readers. Alternatively, you may choose to use a third party tool to convert the
HTML files to some other documentation format.
## 404 Pages
When MkDocs builds the documentation it will include a 404.html file in the
[build directory][site_dir]. This file will be automatically used when
deploying to [GitHub](#github-pages) but only on a custom domain. Other web
servers may be configured to use it but the feature won't always be available.
See the documentation for your server of choice for more information.
[site_dir]: ./configuration.md#site_dir
[site_url]: ./configuration.md#site_url
[use_directory_urls]: ./configuration.md#use_directory_urls
[search]: ./configuration.md#search
[internal links]: ./writing-your-docs.md#internal-links

View File

@@ -0,0 +1,107 @@
# MkDocs Installation
A detailed guide.
---
## Requirements
MkDocs requires a recent version of [Python] and the Python package
manager, [pip], to be installed on your system.
You can check if you already have these installed from the command line:
```console
$ python --version
Python 3.8.2
$ pip --version
pip 20.0.2 from /usr/local/lib/python3.8/site-packages/pip (python 3.8)
```
If you already have those packages installed, you may skip down to [Installing
MkDocs](#installing-mkdocs).
### Installing Python
Install [Python] using your package manager of choice, or by downloading an
installer appropriate for your system from [python.org] and running it.
> NOTE:
> If you are installing Python on Windows, be sure to check the box to have
> Python added to your PATH if the installer offers such an option (it's
> normally off by default).
>
> ![Add Python to PATH](../img/win-py-install.png)
### Installing pip
If you're using a recent version of Python, the Python package manager, [pip],
is most likely installed by default. However, you may need to upgrade pip to the
lasted version:
```bash
pip install --upgrade pip
```
If you need to install pip for the first time, download [get-pip.py].
Then run the following command to install it:
```bash
python get-pip.py
```
## Installing MkDocs
Install the `mkdocs` package using pip:
```bash
pip install mkdocs
```
You should now have the `mkdocs` command installed on your system. Run `mkdocs
--version` to check that everything worked okay.
```console
$ mkdocs --version
mkdocs, version 1.2.0 from /usr/local/lib/python3.8/site-packages/mkdocs (Python 3.8)
```
> NOTE:
> If you would like manpages installed for MkDocs, the [click-man] tool can
> generate and install them for you. Simply run the following two commands:
>
> ```bash
> pip install click-man
> click-man --target path/to/man/pages mkdocs
> ```
>
> See the [click-man documentation] for an explanation of why manpages are
> not automatically generated and installed by pip.
<!-- -->
> NOTE:
> If you are using Windows, some of the above commands may not work
> out-of-the-box.
>
> A quick solution may be to preface every Python command with `python -m`
> like this:
>
> ```bash
> python -m pip install mkdocs
> python -m mkdocs
> ```
>
> For a more permanent solution, you may need to edit your `PATH` environment
> variable to include the `Scripts` directory of your Python installation.
> Recent versions of Python include a script to do this for you. Navigate to
> your Python installation directory (for example `C:\Python38\`), open the
> `Tools`, then `Scripts` folder, and run the `win_add2path.py` file by double
> clicking on it. Alternatively, you can download the [script][a2p] and run it
> (`python win_add2path.py`).
[Python]: https://www.python.org/
[python.org]: https://www.python.org/downloads/
[pip]: https://pip.readthedocs.io/en/stable/installing/
[get-pip.py]: https://bootstrap.pypa.io/get-pip.py
[click-man]: https://github.com/click-contrib/click-man
[click-man documentation]: https://github.com/click-contrib/click-man#automatic-man-page-installation-with-setuptools-and-pip
[a2p]: https://github.com/python/cpython/blob/master/Tools/scripts/win_add2path.py

View File

@@ -0,0 +1,63 @@
# Localizing Your Theme
Display your theme in your preferred language.
---
NOTE:
Theme localization only translates the text elements of the theme itself
(such as "next" and "previous" links), not the actual content of your
documentation. If you wish to create multilingual documentation, you need
to combine theme localization as described here with a third-party
internationalization/localization plugin.
## Installation
For theme localization to work, you must use a theme which supports it and
enable `i18n` (internationalization) support by installing `mkdocs[i18n]`:
```bash
pip install 'mkdocs[i18n]'
```
## Supported locales
In most cases a locale is designated by the [ISO-639-1] (2-letter) abbreviation
for your language. However, a locale may also include a territory (or region or
county) code as well. The language and territory must be separated by an
underscore. For example, some possible locales for English might include `en`,
`en_AU`, `en_GB`, and `en_US`.
For a list of locales supported by the theme you are using, see that theme's
documentation.
- [mkdocs](choosing-your-theme.md#mkdocs-locale)
- [readthedocs](choosing-your-theme.md#readthedocs-locale)
WARNING:
If you configure a language locale which is not yet supported by the theme
that you are using, MkDocs will fall back to the theme's default locale.
## Usage
To specify the locale that MkDocs should use, set the [locale]
parameter of the [theme] configuration option to the appropriate code.
For example, to build the `mkdocs` theme in French you would use the following
in your `mkdocs.yml` configuration file:
```yaml
theme:
name: mkdocs
locale: fr
```
## Contributing theme translations
If a theme has not yet been translated into your language, feel free to
contribute a translation using the [Translation Guide].
[Translation Guide]: ../dev-guide/translations.md
[locale]: configuration.md#locale
[theme]: configuration.md#theme
[ISO-639-1]: https://en.wikipedia.org/wiki/ISO_639-1

View File

@@ -0,0 +1,540 @@
# Writing your docs
How to layout and write your Markdown source files.
---
## File layout
Your documentation source should be written as regular Markdown files (see
[Writing with Markdown](#writing-with-markdown) below), and placed in the
[documentation directory](configuration.md#docs_dir). By default, this directory
will be named `docs` and will exist at the top level of your project, alongside
the `mkdocs.yml` configuration file.
The simplest project you can create will look something like this:
```text
mkdocs.yml
docs/
index.md
```
By convention your project homepage should be named `index.md` (see [Index
pages](#index-pages) below for details). Any of the following file
extensions may be used for your Markdown source files: `markdown`, `mdown`,
`mkdn`, `mkd`, `md`. All Markdown files included in your documentation
directory will be rendered in the built site regardless of any settings.
NOTE:
Files and directories with names which begin with a dot (for example: `.foo.md` or `.bar/baz.md`) are ignored by MkDocs. This can be overridden with the [`exclude_docs` config](configuration.md#exclude_docs).
You can also create multi-page documentation, by creating several Markdown
files:
```text
mkdocs.yml
docs/
index.md
about.md
license.md
```
The file layout you use determines the URLs that are used for the generated
pages. Given the above layout, pages would be generated for the following URLs:
```text
/
/about/
/license/
```
You can also include your Markdown files in nested directories if that better
suits your documentation layout.
```text
docs/
index.md
user-guide/getting-started.md
user-guide/configuration-options.md
license.md
```
Source files inside nested directories will cause pages to be generated with
nested URLs, like so:
```text
/
/user-guide/getting-started/
/user-guide/configuration-options/
/license/
```
Any files which are not identified as Markdown files (by their file extension)
within the [documentation directory](configuration.md#docs_dir) are copied by
MkDocs to the built site unaltered. See
[how to link to images and media](#linking-to-images-and-media) below for details.
### Index pages
When a directory is requested, by default, most web servers will return an index
file (usually named `index.html`) contained within that directory if one exists.
For that reason, the homepage in all of the examples above has been named
`index.md`, which MkDocs will render to `index.html` when building the site.
Many repository hosting sites provide special treatment for README files by
displaying the contents of the README file when browsing the contents of a
directory. Therefore, MkDocs will allow you to name your index pages as
`README.md` instead of `index.md`. In that way, when users are browsing your
source code, the repository host can display the index page of that directory as
it is a README file. However, when MkDocs renders your site, the file will be
renamed to `index.html` so that the server will serve it as a proper index file.
If both an `index.md` file and a `README.md` file are found in the same
directory, then the `index.md` file is used and the `README.md` file is
ignored.
### Configure Pages and Navigation
The [nav](configuration.md#nav) configuration setting in your `mkdocs.yml` file
defines which pages are included in the global site navigation menu as well as
the structure of that menu. If not provided, the navigation will be
automatically created by discovering all the Markdown files in the
[documentation directory](configuration.md#docs_dir). An automatically created
navigation configuration will always be sorted alphanumerically by file name
(except that index files will always be listed first within a sub-section). You
will need to manually define your navigation configuration if you would like
your navigation menu sorted differently.
A minimal navigation configuration could look like this:
```yaml
nav:
- index.md
- about.md
```
All paths in the navigation configuration must be relative to the `docs_dir`
configuration option. If that option is set to the default value, `docs`, the
source files for the above configuration would be located at `docs/index.md` and
`docs/about.md`.
The above example will result in two navigation items being created at the top
level and with their titles inferred from the contents of the Markdown file or,
if no title is defined within the file, of the file name. To override the title
in the `nav` setting add a title right before the filename.
```yaml
nav:
- Home: index.md
- About: about.md
```
Note that if a title is defined for a page in the navigation, that title will be
used throughout the site for that page and will override any title defined
within the page itself.
Navigation sub-sections can be created by listing related pages together under a
section title. For example:
```yaml
nav:
- Home: index.md
- User Guide:
- Writing your docs: writing-your-docs.md
- Styling your docs: styling-your-docs.md
- About:
- License: license.md
- Release Notes: release-notes.md
```
With the above configuration we have three top level items: "Home", "User Guide"
and "About." "Home" is a link to the homepage for the site. Under the "User
Guide" section two pages are listed: "Writing your docs" and "Styling your
docs." Under the "About" section two more pages are listed: "License" and
"Release Notes."
Note that a section cannot have a page assigned to it. Sections are only
containers for child pages and sub-sections. You may nest sections as deeply as
you like. However, be careful that you don't make it too difficult for your
users to navigate through the site navigation by over-complicating the nesting.
While sections may mirror your directory structure, they do not have to.
Any pages not listed in your navigation configuration will still be rendered and
included with the built site, however, they will not be linked from the global
navigation and will not be included in the `previous` and `next` links. Such
pages will be "hidden" unless linked to directly.
## Writing with Markdown
MkDocs pages must be authored in [Markdown][md], a lightweight markup language
which results in easy-to-read, easy-to-write plain text documents that can be
converted to valid HTML documents in a predictable manner.
MkDocs uses the [Python-Markdown] library to render Markdown documents to HTML.
Python-Markdown is almost completely compliant with the [reference
implementation][md], although there are a few very minor [differences].
In addition to the base Markdown [syntax] which is common across all Markdown
implementations, MkDocs includes support for extending the Markdown syntax with
Python-Markdown [extensions]. See the MkDocs' [markdown_extensions]
configuration setting for details on how to enable extensions.
MkDocs includes some extensions by default, which are highlighted below.
[Python-Markdown]: https://python-markdown.github.io/
[md]: https://daringfireball.net/projects/markdown/
[differences]: https://python-markdown.github.io/#differences
[syntax]: https://daringfireball.net/projects/markdown/syntax
[extensions]: https://python-markdown.github.io/extensions/
[markdown_extensions]: configuration.md#markdown_extensions
### Internal links
MkDocs allows you to interlink your documentation by using regular Markdown
[links]. However, there are a few additional benefits to formatting those links
specifically for MkDocs as outlined below.
[links]: https://daringfireball.net/projects/markdown/syntax#link
#### Linking to pages
When linking between pages in the documentation you can simply use the regular
Markdown [linking][links] syntax, including the *relative path* to the Markdown
document you wish to link to.
```markdown
Please see the [project license](license.md) for further details.
```
When the MkDocs build runs, these Markdown links will automatically be
transformed into an HTML hyperlink to the appropriate HTML page.
WARNING:
Using absolute paths with links is not officially supported. Relative paths
are adjusted by MkDocs to ensure they are always relative to the page. Absolute
paths are not modified at all. This means that your links using absolute paths
might work fine in your local environment but they might break once you deploy
them to your production server.
If the target documentation file is in another directory you'll need to make
sure to include any relative directory path in the link.
```markdown
Please see the [project license](../about/license.md) for further details.
```
The [toc] extension is used by MkDocs to generate an ID for every header in your
Markdown documents. You can use that ID to link to a section within a target
document by using an anchor link. The generated HTML will correctly transform
the path portion of the link, and leave the anchor portion intact.
```markdown
Please see the [project license](about.md#license) for further details.
```
Note that IDs are created from the text of a header. All text is converted to
lowercase and any disallowed characters, including white-space, are converted to
dashes. Consecutive dashes are then reduced to a single dash.
There are a few configuration settings provided by the toc extension which you
can set in your `mkdocs.yml` configuration file to alter the default behavior:
* **`permalink`**
Generate permanent links at the end of each header. Default: `False`.
When set to True the paragraph symbol (&para; or `&para;`) is used as the
link text. When set to a string, the provided string is used as the link
text. For example, to use the hash symbol (`#`) instead, do:
```yaml
markdown_extensions:
- toc:
permalink: "#"
```
* **`baselevel`**
Base level for headers. Default: `1`.
This setting allows the header levels to be automatically adjusted to fit
within the hierarchy of your HTML templates. For example, if the Markdown
text for a page should not contain any headers higher than level 2 (`<h2>`),
do:
```yaml
markdown_extensions:
- toc:
baselevel: 2
```
Then any headers in your document would be increased by 1. For example, the
header `# Header` would be rendered as a level 2 header (`<h2>`) in the HTML
output.
* **`separator`**
Word separator. Default: `-`.
Character which replaces white-space in generated IDs. If you prefer
underscores, then do:
```yaml
markdown_extensions:
- toc:
separator: "_"
```
Note that if you would like to define multiple of the above settings, you must
do so under a single `toc` entry in the `markdown_extensions` configuration
option.
```yml
markdown_extensions:
- toc:
permalink: "#"
baselevel: 2
separator: "_"
```
[toc]: https://python-markdown.github.io/extensions/toc/
#### Linking to images and media
As well as the Markdown source files, you can also include other file types in
your documentation, which will be copied across when generating your
documentation site. These might include images and other media.
For example, if your project documentation needed to include a [GitHub Pages
CNAME file] and a PNG formatted screenshot image then your file layout might
look as follows:
```text
mkdocs.yml
docs/
CNAME
index.md
about.md
license.md
img/
screenshot.png
```
To include images in your documentation source files, simply use any of the
regular Markdown image syntaxes:
```Markdown
Cupcake indexer is a snazzy new project for indexing small cakes.
![Screenshot](img/screenshot.png)
*Above: Cupcake indexer in progress*
```
Your image will now be embedded when you build the documentation, and should
also be previewed if you're working on the documentation with a Markdown editor.
[GitHub Pages CNAME file]: https://help.github.com/articles/using-a-custom-domain-with-github-pages/
#### Linking from raw HTML
Markdown allows document authors to fall back to raw HTML when the Markdown
syntax does not meets the author's needs. MkDocs does not limit Markdown in this
regard. However, as all raw HTML is ignored by the Markdown parser, MkDocs is
not able to validate or convert links contained in raw HTML. When including
internal links within raw HTML, you will need to manually format the link
appropriately for the rendered document.
### Meta-Data
MkDocs includes support for both YAML and MultiMarkdown style meta-data (often
called front-matter). Meta-data consists of a series of keywords and values
defined at the beginning of a Markdown document, which are stripped from the
document prior to it being processing by Python-Markdown. The key/value pairs
are passed by MkDocs to the page template. Therefore, if a theme includes
support, the values of any keys can be displayed on the page or used to control
the page rendering. See your theme's documentation for information about which
keys may be supported, if any.
In addition to displaying information in a template, MkDocs includes support for
a few predefined meta-data keys which can alter the behavior of MkDocs for that
specific page. The following keys are supported:
* **`template`**
The template to use with the current page.
By default, MkDocs uses the `main.html` template of a theme to render
Markdown pages. You can use the `template` meta-data key to define a
different template file for that specific page. The template file must be
available on the path(s) defined in the theme's environment.
* **`title`**
The "title" to use for the document.
MkDocs will attempt to determine the title of a document in the following
ways, in order:
1. A title defined in the [nav] configuration setting for a document.
2. A title defined in the `title` meta-data key of a document.
3. A level 1 Markdown header on the first line of the document body.
([Setext-style] headers are supported *only since MkDocs 1.5*.)
4. The filename of a document.
Upon finding a title for a page, MkDoc does not continue checking any
additional sources in the above list.
[Setext-style]: https://daringfireball.net/projects/markdown/syntax#header
#### YAML Style Meta-Data
YAML style meta-data consists of [YAML] key/value pairs wrapped in YAML style
delimiters to mark the start and/or end of the meta-data. The first line of
a document must be `---`. The meta-data ends at the first line containing an
end deliminator (either `---` or `...`). The content between the delimiters is
parsed as [YAML].
```text
---
title: My Document
summary: A brief description of my document.
authors:
- Waylan Limberg
- Tom Christie
date: 2018-07-10
some_url: https://example.com
---
This is the first paragraph of the document.
```
YAML is able to detect data types. Therefore, in the above example, the values
of `title`, `summary` and `some_url` are strings, the value of `authors` is a
list of strings and the value of `date` is a `datetime.date` object. Note that
the YAML keys are case sensitive and MkDocs expects keys to be all lowercase.
The top level of the YAML must be a collection of key/value pairs, which results
in a Python `dict` being returned. If any other type is returned or the YAML
parser encounters an error, then MkDocs does not recognize the section as
meta-data, the page's `meta` attribute will be empty, and the section is not
removed from the document.
#### MultiMarkdown Style Meta-Data
MultiMarkdown style meta-data uses a format first introduced by the
[MultiMarkdown] project. The data consists of a series of keywords and values
defined at the beginning of a Markdown document, like this:
```text
Title: My Document
Summary: A brief description of my document.
Authors: Waylan Limberg
Tom Christie
Date: January 23, 2018
blank-value:
some_url: https://example.com
This is the first paragraph of the document.
```
The keywords are case-insensitive and may consist of letters, numbers,
underscores and dashes and must end with a colon. The values consist of anything
following the colon on the line and may even be blank.
If a line is indented by 4 or more spaces, that line is assumed to be an
additional line of the value for the previous keyword. A keyword may have as
many lines as desired. All lines are joined into a single string.
The first blank line ends all meta-data for the document. Therefore, the first
line of a document must not be blank.
NOTE:
MkDocs does not support YAML style delimiters (`---` or `...`) for
MultiMarkdown style meta-data. In fact, MkDocs relies on the the presence or
absence of the delimiters to determine whether YAML style meta-data or
MultiMarkdown style meta-data is being used. If the delimiters are
detected, but the content between the delimiters is not valid YAML
meta-data, MkDocs does not attempt to parse the content as MultiMarkdown
style meta-data.
[YAML]: https://yaml.org
[MultiMarkdown]: https://fletcherpenney.net/MultiMarkdown_Syntax_Guide#metadata
[nav]: configuration.md#nav
### Tables
The [tables] extension adds a basic table syntax to Markdown which is popular
across multiple implementations. The syntax is rather simple and is generally
only useful for simple tabular data.
A simple table looks like this:
```markdown
First Header | Second Header | Third Header
------------ | ------------- | ------------
Content Cell | Content Cell | Content Cell
Content Cell | Content Cell | Content Cell
```
If you wish, you can add a leading and tailing pipe to each line of the table:
```markdown
| First Header | Second Header | Third Header |
| ------------ | ------------- | ------------ |
| Content Cell | Content Cell | Content Cell |
| Content Cell | Content Cell | Content Cell |
```
Specify alignment for each column by adding colons to separator lines:
```markdown
First Header | Second Header | Third Header
:----------- |:-------------:| -----------:
Left | Center | Right
Left | Center | Right
```
Note that table cells cannot contain any block level elements and cannot contain
multiple lines of text. They can, however, include inline Markdown as defined in
Markdown's [syntax] rules.
Additionally, a table must be surrounded by blank lines. There must be a blank
line before and after the table.
[tables]: https://python-markdown.github.io/extensions/tables/
### Fenced code blocks
The [fenced code blocks] extension adds an alternate method of defining code
blocks without indentation.
The first line should contain 3 or more backtick (`` ` ``) characters, and the
last line should contain the same number of backtick characters (`` ` ``):
````markdown
```
Fenced code blocks are like Standard
Markdowns regular code blocks, except that
theyre not indented and instead rely on
start and end fence lines to delimit the
code block.
```
````
With this approach, the language can optionally be specified on the first line
after the backticks which informs any syntax highlighters of the language used:
````markdown
```python
def fn():
pass
```
````
Note that fenced code blocks can not be indented. Therefore, they cannot be
nested inside list items, blockquotes, etc.
[fenced code blocks]: https://python-markdown.github.io/extensions/fenced_code_blocks/

View File

@@ -0,0 +1,79 @@
site_name: MkDocs
site_url: https://www.mkdocs.org/
site_description: Project documentation with Markdown.
site_author: MkDocs Team
repo_url: https://github.com/mkdocs/mkdocs/
edit_uri: blob/master/docs/
theme:
name: mkdocs
color_mode: auto
user_color_mode_toggle: true
locale: en
analytics: {gtag: 'G-274394082'}
highlightjs: true
hljs_languages:
- yaml
- django
nav:
- Home: index.md
- Getting Started: getting-started.md
- User Guide: user-guide/
- Developer Guide: dev-guide/
- About:
- Release Notes: about/release-notes.md
- Contributing: about/contributing.md
- License: about/license.md
extra_css:
- css/extra.css
exclude_docs: |
*.py
markdown_extensions:
- toc:
permalink:
- attr_list
- def_list
- tables
- pymdownx.highlight:
use_pygments: false
- pymdownx.snippets
- pymdownx.superfences
- callouts
- mdx_gh_links:
user: mkdocs
repo: mkdocs
- mkdocs-click
copyright: Copyright &copy; 2014 <a href="https://twitter.com/starletdreaming">Tom Christie</a>, Maintained by the <a href="/about/release-notes/#maintenance-team">MkDocs Team</a>.
hooks:
- docs/hooks.py
plugins:
- search
- redirects:
redirect_maps:
user-guide/plugins.md: dev-guide/plugins.md
user-guide/custom-themes.md: dev-guide/themes.md
user-guide/styling-your-docs.md: user-guide/choosing-your-theme.md
- autorefs
- literate-nav:
nav_file: README.md
implicit_index: true
- mkdocstrings:
handlers:
python:
options:
docstring_section_style: list
members_order: source
show_root_heading: true
show_source: false
show_signature_annotations: true
watch:
- mkdocs

View File

@@ -0,0 +1,112 @@
# Alternatives
There are tons of static site generators and themes out there and choosing the
right one for your tech stack is a tough decision. If you're unsure if Material
for MkDocs is the right solution for you, this section should help you evaluate
alternative solutions.
## Docusaurus
[Docusaurus] by Facebook is a very popular documentation generator and a good
choice if you or your company are already using [React] to build your site.
It will generate a [single page application] which is fundamentally different
from the site Material for MkDocs generates for you.
__Advantages__
- Very powerful, customizable and extendable
- Provides many components that aid in technical writing
- Large and rich ecosystem, backed by Facebook
__Challenges__
- High learning curve, JavaScript knowledge mandatory
- JavaScript ecosystem is very volatile, rather high maintenance
- More time needed to get up and running
While [Docusaurus] is one of the best choices when it comes to documentation
sites that output a single page application, there are many more solutions,
including [Docz], [Gatsby], [Vuepress] and [Docsify] that approach
this problem similarly.
[Docusaurus]: https://docusaurus.io/
[React]: https://reactjs.org/
[single page application]: https://en.wikipedia.org/wiki/Single-page_application
[Docz]: https://www.docz.site/
[Gatsby]: https://www.gatsbyjs.com/
[VuePress]: https://vuepress.vuejs.org/
[Docsify]: https://docsify.js.org/
## Jekyll
[Jekyll] is probably one of the most mature and widespread static site
generators and is written in [Ruby]. It is not specifically geared towards
technical project documentation and has many themes to choose from, which
can be challenging.
__Advantages__
- Battle-tested, rich ecosystem, many themes to choose from
- Brings great capabilities for blogging (permalinks, tags, etc.)
- Generates a SEO-friendly site, similar to Material for MkDocs
__Challenges__
- Not specifically geared towards technical project documentation
- Limited Markdown capabilities, not as advanced as Python Markdown
- More time needed to get up and running
[Jekyll]: https://jekyllrb.com/
[Ruby]: https://www.ruby-lang.org/de/
## Sphinx
[Sphinx] is an alternative static site generator specifically geared towards
generating reference documentation, offering powerful capabilities that are
lacking in MkDocs. It uses [reStructured text], a format similar to Markdown,
which some users find harder to use.
__Advantages__
- Very powerful, customizable and extendable
- Generates reference documentation from [Python docstrings]
- Large and rich ecosystem, used by many Python projects
__Challenges__
- High learning curve, [reStructured text] syntax might be challenging
- Search is less powerful than the one provided by MkDocs
- More time needed to get up and running
If you're considering using Sphinx because you need to generate reference
documentation, you should give [mkdocstrings] a try an actively maintained
and popular framework building on top of MkDocs, implementing Sphinx-like
functionality.
[Sphinx]: https://www.sphinx-doc.org/
[reStructured text]: https://en.wikipedia.org/wiki/ReStructuredText
[Python docstrings]: https://www.python.org/dev/peps/pep-0257/
[mkdocstrings]: https://github.com/mkdocstrings/mkdocstrings
## GitBook
[GitBook] offers a hosted documentation solution that generates a beautiful and
functional site from Markdown files in your GitHub repository. However, it was
once Open Source, but turned into a closed source solution some time ago.
__Advantages__
- Hosted solution, minimal technical knowledge required
- Custom domains, authentication and other enterprise features
- Great collaboration features for teams
__Challenges__
- Closed source, not free for proprietary projects
- Limited Markdown capabilities, not as advanced as Python Markdown
- Many Open Source projects moved away from GitBook
Many users switched from [GitBook] to Material for MkDocs, as they want to keep
control and ownership of their documentation, favoring an Open Source solution.
[GitBook]: https://www.gitbook.com/

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 193 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 170 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 609 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 744 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 319 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 184 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 184 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 203 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 184 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 177 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Some files were not shown because too many files have changed in this diff Show More