25 Commits

Author SHA1 Message Date
Tony
a2f97343af dumb mistake
All checks were successful
Build and publish CMBA rulebooks (Gitea) / build-release (push) Successful in 13s
2026-01-15 11:17:53 -06:00
Tony
b16532d937 fix some workflow bugs
Some checks failed
Build and publish CMBA rulebooks (Gitea) / build-release (push) Failing after 9s
2026-01-15 11:15:13 -06:00
Tony
941c74fa8e left extension
All checks were successful
Build and publish CMBA rulebooks (Gitea) / build-release (push) Successful in 17s
2026-01-15 11:08:40 -06:00
Tony
4051e27a53 update workflow for new structure
Some checks failed
Build and publish CMBA rulebooks (Gitea) / build-release (push) Failing after 18s
2026-01-15 11:06:13 -06:00
Tony
d089951f60 move js 2026-01-15 11:06:01 -06:00
Tony
d851081d17 split bylaws and constitution 2026-01-15 10:49:37 -06:00
Tony
5c59f746bf split bylaws from constitution 2026-01-15 10:48:15 -06:00
Tony
e7ba209f6c re-structure 2026-01-15 10:42:45 -06:00
Tony
cd6c579d9c remove text
All checks were successful
Build and publish CMBA rulebooks (Gitea) / build-release (push) Successful in 12s
2026-01-14 15:07:34 -06:00
Tony
a1dcd70043 use icon instead of "quote"
All checks were successful
Build and publish CMBA rulebooks (Gitea) / build-release (push) Successful in 12s
2026-01-14 15:03:26 -06:00
Tony
b9603e70e0 fix quote location
All checks were successful
Build and publish CMBA rulebooks (Gitea) / build-release (push) Successful in 11s
2026-01-14 14:50:13 -06:00
Tony
e655b12300 try quote button js
Some checks failed
Build and publish CMBA rulebooks (Gitea) / build-release (push) Failing after 11s
2026-01-14 14:45:55 -06:00
Tony
bbca3b724e more space error
All checks were successful
Build and publish CMBA rulebooks (Gitea) / build-release (push) Successful in 12s
2026-01-14 11:08:43 -06:00
Tony
a47e9f5d1d space issue?
Some checks failed
Build and publish CMBA rulebooks (Gitea) / build-release (push) Failing after 8s
2026-01-14 11:05:03 -06:00
Tony
40a0624ab2 update css and pandoc options
Some checks failed
Build and publish CMBA rulebooks (Gitea) / build-release (push) Failing after 9s
2026-01-14 11:02:46 -06:00
Tony
e0ee5899c0 try css styling
All checks were successful
Build and publish CMBA rulebooks (Gitea) / build-release (push) Successful in 7s
2026-01-14 10:53:40 -06:00
Tony
a2d3fad8df try embed css in html
All checks were successful
Build and publish CMBA rulebooks (Gitea) / build-release (push) Successful in 9s
2026-01-14 10:36:57 -06:00
Tony
3db8d566e6 update dependencies
All checks were successful
Build and publish CMBA rulebooks (Gitea) / build-release (push) Successful in 9s
2026-01-14 10:29:08 -06:00
Tony
79ebe28ecc add github css
Some checks failed
Build and publish CMBA rulebooks (Gitea) / build-release (push) Failing after 8s
2026-01-14 10:27:19 -06:00
Tony
cdf3479260 fix curl
All checks were successful
Build and publish CMBA rulebooks (Gitea) / build-release (push) Successful in 1m20s
2026-01-14 10:05:14 -06:00
Tony
245c4ed28f think i fixed yaml
All checks were successful
Build and publish CMBA rulebooks (Gitea) / build-release (push) Successful in 1m42s
2026-01-14 10:01:22 -06:00
Tony
f78172f2af maybe fix curl issue 2026-01-14 09:50:03 -06:00
Tony
163af81f31 try new api url
All checks were successful
Build and publish CMBA rulebooks (Gitea) / build-release (push) Successful in 1m18s
2026-01-14 09:37:52 -06:00
Tony
7fd132dec0 add missing dollar sign
Some checks failed
Build and publish CMBA rulebooks (Gitea) / build-release (push) Failing after 1m6s
2026-01-14 09:21:48 -06:00
Tony
40c9f27952 test workflow
Some checks failed
Build and publish CMBA rulebooks (Gitea) / build-release (push) Failing after 1m18s
2026-01-14 09:18:21 -06:00
24 changed files with 1101 additions and 432 deletions

View File

@@ -1,57 +0,0 @@
name: CI - Docs build check
on:
push:
branches:
- main
- develop
- release-candidate
workflow_dispatch:
permissions:
contents: read
env:
MKDOCS_STRICT: ${{ vars.MKDOCS_STRICT || 'true' }}
MKDOCS_CONFIG: mkdocs/mkdocs.yml
MKDOCS_OFFLINE: false
CSPELL_CONFIG: tools/spellcheck/cspell.yml
CSPELL_TARGETS: docs/**/*.md README.md
jobs:
build-check:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Spellcheck
run: |
set -euo pipefail
npx --yes cspell \
--config ${CSPELL_CONFIG} \
${CSPELL_TARGETS}
- name: Install build dependencies
run: |
set -euo pipefail
pip install -r mkdocs/requirements.txt
- name: MkDocs build (strict default)
run: |
set -euo pipefail
echo "Strict is set to ${MKDOCS_STRICT}"
FLAGS=()
if [ "${MKDOCS_STRICT}" = "true" ]; then
FLAGS+=(--strict)
fi
MKDOCS_OUTPUT_DIR="${RUNNER_TEMP:-${TMPDIR:-/tmp}}/dist"
mkdocs build "${FLAGS[@]}" -f "${MKDOCS_CONFIG}" -d "${MKDOCS_OUTPUT_DIR}"

135
.github/workflows/release-docs.yml vendored Normal file
View File

@@ -0,0 +1,135 @@
name: Build and publish CMBA rulebooks (Gitea)
on:
push:
tags:
- "v*"
jobs:
build-release:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install dependencies
run: |
sudo apt-get update
# texlive-latex-recommended \
# texlive-fonts-recommended \
# texlive-latex-extra \
sudo apt-get install -y pandoc \
jq \
curl
- name: Build pandoc after-body include from .js files
run: |
set -euo pipefail
mkdir -p build
out="build/after-body.html"
: > "$out" # truncate
# Ensure deterministic order
shopt -s nullglob
files=(js/*.js)
if [ ${#files[@]} -eq 0 ]; then
echo "No JS files found in js/; generating empty after-body.html"
exit 0
fi
for f in "${files[@]}"; do
{
echo "<script>"
echo "$f"
echo "</script>"
} >> "$out"
done
- name: Build artifacts
run: |
set -euo pipefail
mkdir -p dist
for doc in *.md; do
# Skip README.md
[[ "$doc" == "README.md" ]] && continue
basename="${doc%.md}"
# Mobile-friendly HTML with TOC + serif styling
pandoc "${doc}" \
--toc \
--standalone \
--number-sections \
--toc-depth=2 \
--lua-filter pandoc-filters/shift-numbering.lua \
--metadata-file metadata.yml \
--embed-resources \
--metadata title="CMBA ${basename}" \
--include-after-body=build/after-body.html \
--css styles/style.css \
-o "dist/${basename}.html"
# PDF
# pandoc "${doc}" \
# --metadata title="CMBA ${doc}" \
# -o "dist/${doc}.pdf"
# Include source markdown for transparency
cp ${doc} dist/
done
- name: Create or update Gitea Release and upload assets
env:
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
GITEA_BASE_URL: ${{ secrets.GITEA_BASE_URL }}
# Gitea provides these variables in Actions:
REPO: ${{ gitea.repository }} # "owner/repo"
TAG: ${{ gitea.ref_name }} # e.g. "v2026.0"
run: |
set -euo pipefail
OWNER="$(echo "$REPO" | cut -d/ -f1)"
NAME="$(echo "$REPO" | cut -d/ -f2)"
API="${GITHUB_API_URL}"
AUTH="Authorization: token ${GITEA_TOKEN}"
echo "Repo: $OWNER/$NAME"
echo "Tag: $TAG"
echo "API: $API"
# Check if release exists for this tag
existing_release_json="$(curl -sS -H "$AUTH" \
"$API/repos/$OWNER/$NAME/releases/tags/$TAG" || true)"
if echo "$existing_release_json" | jq -e '.id' >/dev/null 2>&1; then
RELEASE_ID="$(echo "$existing_release_json" | jq -r '.id')"
echo "Release exists (id=$RELEASE_ID)."
else
echo "Creating release for tag $TAG..."
create_json="$(curl -sS -X POST -H "$AUTH" -H "Content-Type: application/json" \
"$API/repos/$OWNER/$NAME/releases" \
-d "$(jq -n --arg tag "$TAG" --arg name "$TAG" \
'{tag_name:$tag, name:$name, draft:false, prerelease:false, body:"CMBA rulebooks release."}')")"
RELEASE_ID="$(echo "$create_json" | jq -r '.id')"
echo "Created release (id=$RELEASE_ID)."
fi
# Upload each file as an asset. If an asset already exists with same name, delete then re-upload.
assets_json="$(curl -sS -H "$AUTH" "$API/repos/$OWNER/$NAME/releases/$RELEASE_ID/assets" || echo '[]')"
for f in dist/*; do
filename="$(basename "$f")"
existing_asset_id="$(echo "$assets_json" | jq -r --arg n "$filename" '.[] | select(.name==$n) | .id' | head -n1 || true)"
if [ -n "${existing_asset_id:-}" ] && [ "$existing_asset_id" != "null" ]; then
echo "Deleting existing asset: $filename (id=$existing_asset_id)"
curl -sS -X DELETE -H "$AUTH" \
"$API/repos/$OWNER/$NAME/releases/$RELEASE_ID/assets/$existing_asset_id" >/dev/null
fi
echo "Uploading $filename"
curl -sS --fail -X POST -H "$AUTH" -H "Accept: application/json" -F "attachment=@$f" "$API/repos/$OWNER/$NAME/releases/$RELEASE_ID/assets?name=$filename" >/dev/null
done
echo "Done. Release page: ${GITEA_BASE_URL}/${OWNER}/${NAME}/releases/tag/${TAG}"

View File

@@ -1,114 +0,0 @@
name: Build & publish docs (rc + release)
on:
push:
tags:
- "rc*"
- "v*"
workflow_dispatch:
permissions:
contents: write
env:
MKDOCS_CONFIG: mkdocs/mkdocs.yml
MKDOCS_STRICT: ${{ vars.MKDOCS_STRICT || 'true' }}
jobs:
publish:
runs-on: ubuntu-latest
steps:
- name: Checkout (tag)
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install deps
run: |
set -euo pipefail
pip install -r mkdocs/requirements.txt
- name: Build docs (normal + offline, strict gate)
run: |
set -euo pipefail
FLAGS=()
if [ "${MKDOCS_STRICT}" = "true" ]; then
FLAGS+=(--strict)
fi
OUT_BASE="${RUNNER_TEMP}/mkdocs_out"
SITE="${OUT_BASE}/site"
SITE_OFFLINE="${OUT_BASE}/site_offline/${GITHUB_REF_NAME}"
rm -rf "${OUT_BASE}"
mkdir -p "${SITE}" "${SITE_OFFLINE}"
mkdocs build "${FLAGS[@]}" -f "${MKDOCS_CONFIG}" -d "${SITE}"
OFFLINE=true mkdocs build "${FLAGS[@]}" -f "${MKDOCS_CONFIG}" -d "${SITE_OFFLINE}"
- name: Zip offline site
run: |
set -euo pipefail
cd "${RUNNER_TEMP}/mkdocs_out/site_offline/"
zip -r "${GITHUB_REF_NAME}.zip" ./${GITHUB_REF_NAME}
- name: Publish prerelease
if: startsWith(github.ref_name, 'rc')
uses: softprops/action-gh-release@v2
with:
prerelease: true
name: ${{ github.ref_name }}
tag_name: ${{ github.ref_name }}
body: |
Release candidate preview (if deployed): /rc/
files: |
${{ runner.temp }}/mkdocs_out/${{ github.ref_name }}.zip
- name: Publish release
if: startsWith(github.ref_name, 'v')
uses: softprops/action-gh-release@v2
with:
name: ${{ github.ref_name }}
tag_name: ${{ github.ref_name }}
files: |
${{ runner.temp }}/mkdocs_out/site_offline/${{ github.ref_name }}.zip
- name: Checkout gh-pages branch
uses: actions/checkout@v4
with:
ref: gh-pages
fetch-depth: 0
- name: Deploy release to gh-pages root
if: startsWith(github.ref_name, 'v')
run: |
set -euo pipefail
rm -rf ./*
cp -a ${RUNNER_TEMP}/mkdocs_out/site/. .
git add -A
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git commit -m "Deploy release ${GITHUB_REF_NAME}" || echo "No changes to commit"
git push origin gh-pages
- name: Deploy RC preview to /rc/
if: startsWith(github.ref_name, 'rc')
run: |
set -euo pipefail
rm -rf rc
mkdir -p rc
cp -a ${RUNNER_TEMP}/mkdocs_out/site/. rc/
printf '{"tag":"%s"}\n' "${GITHUB_REF_NAME}" > rc/rc.json
git add -A
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git commit -m "Deploy RC preview ${GITHUB_REF_NAME}" || echo "No changes to commit"
git push origin gh-pages

View File

@@ -0,0 +1 @@
personal_repl-1.1 en 0

View File

@@ -0,0 +1,22 @@
personal_ws-1.1 en 19
BBCOR
MLB
RO
Rawlings
chicagoland
cmba
cp
ePUB
epub
gh
gitdriver
github
html
jgm
lua
md
pandoc
repo
rostered
src
timeframe

189
.spell-check/git-spell-check Executable file
View File

@@ -0,0 +1,189 @@
#!/bin/bash
# mprpic/git-spell-check
# https://github.com/mprpic/git-spell-check/
set -e
#adding this for use on a Mac
if command -v gsed &> /dev/null
then
sed=gsed
else
sed=sed
fi
# Instructions:
#
# This script is a Git pre-commit hook that spell checks any content you are about to commit.
#
# Place this script into the ".git/hooks/" directory in your repository. It must be called "pre-commit" and be
# executable. A Git hook only works in a single repository. You need to copy this hook into every repository you wish to
# use it in manually. Optionally, you can set up a symlink in the ".git/hooks/" directory pointing to the script.
#
# Each time you try to commit something, this script is run and spell checks the content you are committing.
#
# Should you want to bypass the pre-commit hook (though not recommended), you can commit with "git commit --no-verify".
# The following is a text file that represents your custom dictionary; edit as necessary. Add words to it that you wish
# to ignore for the spell check.
dict=~/.git-spell-check
if [ ! -f $dict ]; then
touch ~/.git-spell-check
dict=~/.git-spell-check
printf "%s\n" "Custom dictionary not found. Created ~/.git-spell-check..."
fi
# The following is a temporary dictionary (a binary file) created from the dict text file. It is deleted after the
# script finishes.
temp_dict=$(mktemp docs-dictionary-XXXXXX)
# Language of your doc. When using a non-English language, make sure you have the appropriate aspell libraries
# installed: "yum search aspell". For example, to spell check in Slovak, you must have the aspell-sk package installed.
lang=en
# Define an extension for any additional dictionaries (containing words that are ignored during the spell check) that
# are kept locally in your repository. These dictionaries will be loaded on top of the existing global dictionary (by
# default ~/.git-spell-check).
extension=pws
# Clean up if script is interrupted or terminated.
trap "cleanup" SIGINT SIGTERM
# Prepares the dictionary from scratch in case new words were added since last time.
function prepare_dictionary() {
local_dict=$(find . -name *.$extension -exec ls {} \;)
if [ -z "$local_dict" ]; then
sort -u $temp_dict -o $temp_dict
aspell --lang="$lang" create master "$temp_dict" < "$dict"
else
temp_file=$(mktemp temp_file-XXXXXX)
for file in $local_dict; do
cat $file >> $temp_file
done
cat $dict >> $temp_file
## Remove header line
$sed -i '/personal_ws-/d' "${temp_file}"
sort -u $temp_file -o $temp_file
aspell --lang="$lang" create master "$temp_dict" < "$temp_file"
/bin/rm -f "$temp_file"
fi
}
# Removes the temporary dictionary.
function cleanup() {
/bin/rm -f "$temp_dict"
}
# Spell checks content you're about to commit. Writes out words that are misspelled or exits with 0 (i.e. continues with
# commit).
function spell_check() {
words=$(git diff --cached | grep -e "^+[^+]" | aspell --mode=sgml list --add-sgml-skip={ulink,code,literal,firstname,parameter,option,package,replaceable,programlisting,userinput,screen,filename,command,computeroutput,abbrev,accel,orgname,surname,foreignphrase,acronym,hardware,keycap,systemitem,application} --lang="$lang" --extra-dicts="$temp_dict" | sort -u)
if [ ! "$words" ]; then
printf "%s\n" "No typos found. Proceeding with commit..."
cleanup; exit 0
fi
printf "%s\n" "Spell check failed on the following words:
-------------------------------------------------"
echo $words
for word in $words; do
grep --color=always --exclude-dir={.git,tmp} -HIrone "\<$word\>" $(git diff --cached --name-only --diff-filter=ACMRTUXB) | awk -F ":" '{print "File: " $1 "\ton line: " $2 "\tTypo: " $3}'
printf "%s\n" "-------------------"
done
}
# Adds all, some, or none of the misspelled words to the custom dictionary.
function add_words_to_dict() {
printf "%s\n" "
Add any of the misspelled words into your custom dictionary?
* a[ll] (add all words into dict, continue with commit)
* s[ome] (add some words into dict, fix others, no commit)
* i[gnore] (add some words into dict, ignore rest, continue with commit)
* n[one] (no commit)
"
while true; do
exec < /dev/tty # Simply reading user input does not work because Git hooks have stdin detached.
read answer
shopt -s nocasematch
case "$answer" in
a|all)
add_all
cleanup; exit 0
;;
s|some)
add_some
printf "%s\n" "Please fix remaining typos, use \"git add\" to add fixed files, and commit."
cleanup; exit 1
;;
i|ignore)
add_some
cleanup; exit 0
;;
n|none)
add_none
cleanup; exit 1
;;
*)
printf "%s\n" "Incorrect answer. Try again."
continue
esac
shopt -u nocasematch
done
}
# Adds all words to the custom dictionary and continues with the commit.
function add_all() {
for word in $words; do
echo $word >> "$dict"
done
}
# Adds some (selected by user) of the words to the dictionary and exits with 1.
function add_some() {
for word in $words; do
printf "%s\n" "Do you want to add the following word to your custom dictionary: $word (y[es] or n[o])"
while true; do
exec < /dev/tty
read answer
shopt -s nocasematch
case "$answer" in
y|yes)
echo $word >> "$dict"
printf "%s\n" "\"$word\" added to your custom dictionary."
break ;;
n|no)
break ;;
*)
printf "%s\n" "Incorrect answer. Try again."
continue
esac
shopt -u nocasematch
done
done
}
# Adds none of the words and exits with 1.
function add_none() {
printf "%s\n" "No words were added to your custom dictionary."
printf "%s\n" "Please fix remaining typos, use \"git add\" to add fixed files, and commit."
}
prepare_dictionary
spell_check
add_words_to_dict

10
.spell-check/spell-check Executable file
View File

@@ -0,0 +1,10 @@
#!/bin/bash
set -e
extension_files_to_check=md
function spell_check(){
find . -type f -name "*.${extension_files_to_check}" -exec aspell check {} --mode=markdown --home-dir=./.spell-check \;
}
spell_check

View File

@@ -1,27 +1,95 @@
<p align="center">
<img src="docs/assets/cmba-logo.svg" width="200">
<img src="https://github.com/anthonyscorrea/silver-memory/blob/a712bca2516c3e860f2c61ea383a3132ead0614b/cmba-logo.svg" width="200">
</p>
# CMBA Constitution and Bylaws
The Constitution and Bylaws for the baseball league known as the [Chicago Metropolitan Baseball Association (CMBA)](#about-the-cmba).
The compiled, published text can be found in the following formats:
- [PDF](build/cmba-bylaws.pdf)
- [HTML](build/cmba-bylaws.html)
- [ePUB](build/cmba-bylaws.epub)
The source text for this document can be found in Markdown format in [src/cmba-bylaws.md](src/cmba-bylaws.md).
## Building from source
### Requirements
Building from source requires:
- [Pandoc](https://pandoc.org)
- [GNU Make](https://www.gnu.org/software/make/)
### Steps
1. Download the latest release or clone the repo:
```
git clone https://github.com/anthonyscorrea/cmba-bylaws.git
```
2. Navigate to the root directory:
```
cd cmba-bylaws-master
```
3. Publish into desired format:
```
make {format}
```
were `{format}` is one of the below:
- All [default]: `make all` or `make`
- PDF: `make pdf`
- html: `make html`
- epub: `make epub`
5. Built files will be in the `build/` directory
## Markdown formatting
- `#` or `h1` is used for either "Constitution" or "Bylaws". They are not numbered, necessitating an `{.unnumbered}` class.
- Note: to get the numbering to match existing convention, a [Lua filter](https://github.com/jgm/pandoc/issues/5071#issuecomment-856918980) was required, see [jgm/pandoc#5701](https://github.com/jgm/pandoc/issues/5071)
- `##` or `h2` is used for sections
- `###` or `h3` is used for subsections
## Metadata
Metadata is stored in the `metadata.yml` file.
## Project history
The constitution and bylaws were modernized in 2021, using Google Docs. This project brings that effort into Git and Github. Previous commits show a generated plain-text history of the changes prior to this project (thanks to [gitdriver](https://github.com/larsks/gitdriver)), with the first being the version from 2016.
## Spell-checking
Spell-checking is performed on the pre-commit via [.spell-check/git-spell-check](.spell-check/git-spell-check) (courtesy of [mprpic/git-spell-check](https://github.com/mprpic/git-spell-check))
You can manually run spell-checking of all markdown files by running the script (requires [aspell](http://aspell.net)):
```console
./.spell-check/spell-check
```
Should you want to bypass the pre-commit hook (though not recommended), you can commit with
```console
git commit --no-verify".
```
## GitHub Pages
The html output can be hosted on GitHub Pages. Currently the site is hosted at the branch [gh-pages](https://github.com/anthonyscorrea/cmba-bylaws/tree/gh-pages). To update this page, you should:
1. First build from the main branch and build html
```console
git clone https://github.com/anthonyscorrea/cmba-bylaws.git
make html
```
2. Then clone the gh-pages branch and replace `index.html` with the updated page.
```console
git clone https://github.com/anthonyscorrea/cmba-bylaws.git --branch gh-pages cmba-bylaws-gh-pages
cp ../cmba-bylaws/build/cmba-bylaws.html ./cmba-bylaws-gh-pages/index.html
git push origin
```
## To-Do
- [X] Spell Checking
- [ ] Remove dependence on make, verify Windows support
## About the CMBA
This baseball league known as the [Chicago Metropolitan Baseball Association (CMBA)](http://cmbabaseball.com) has been formed for the purpose of providing the finest amateur baseball league in the State of Illinois and Midwest; a league where an up and coming young prospect for professional baseball may play and develop; where the talented veteran player can enjoy playing among the best competition; and bring friendship and sportsmanship to the Association.

View File

Before

Width:  |  Height:  |  Size: 199 KiB

After

Width:  |  Height:  |  Size: 199 KiB

View File

@@ -1,5 +1,4 @@
# By-Laws
# By-Laws {.unnumbered}
## Definition; Amendments
These By-Laws shall stand as the official rules of the CMBA.
@@ -193,6 +192,160 @@ All players in the CMBA are expected to pay their team fees. Players will not be
### Free Agents
A player must inform the League President and his manager no later than February 15 of the upcoming season if he wishes to leave his team and become a free agent. After this he is free to play for another team in the CMBA. A manager may waive this deadline for an individual player at the managers discretion. If the player fails to notify as specified, that player shall be disqualified from playing on another CMBA team for that season.
## General Play
### Playing Rules
Except where specified in this document, the CMBA shall follow the Official Baseball Rules of Major League Baseball.
The CMBA shall not incorporate the following rules of Major League Baseball:
- Rule 4.03(c)(4) specifying limitations on when a position player can pitch.
- Rule 5.02(c) specifying limitations on infielder placement.
- Rule 7.01(b) incorporating the parameters of the Extra Innings Rule, which includes starting each half-inning following the last regulation inning with a runner on second base.
- Rule 5.10(m)(1) limiting the number of mound visits.
- Rule 5.10(g) requiring that pitchers must face at least three batters.
- Rules 5.07(c) specifying time limits on pitchers and batters. Limitations on pitcher disengagements (i.e. pick-offs) shall also not be incorporated.
### Regulation Games
Games played under the auspices of both recognized Managers of the participating teams shall count as official. A regulation game is defined as follows
1. A regulation game consists of seven (7) innings, unless extended because of a tie score, or shortened because the home team needs none of its half of the seventh inning or only a fraction of it, or because the umpire calls the game in accordance with [Reasons for a Game to be Called](#reasons-for-a-game-to-be-called).
1. If the score is tied after seven completed innings play shall continue until (1) the visiting team has scored more total runs than the home team at the end of a completed inning, or (2) the home team scores the winning run in an uncompleted inning. If a regulation game is called with the score tied, it shall remain a tie game.
1. If a game is called by the umpire, per [Reasons for a Game to be Called](#reasons-for-a-game-to-be-called), it is a regulation (official) game:
1. If four innings have been completed;
1. If the home team has scored more runs in four or three and a fraction half-innings than the visiting team has scored in four completed half-innings;
1. If the home team scores one or more runs in its half of the fourth inning to tie the score.
Postseason games are exempt from this definition as specified in [Completion of Playoff Games](#completion-of-playoff-games).
1. Slaughter Rule: The game shall be ended and the leading team declared the winner:
1. If after 4 complete innings the visiting team is ahead in the score by 15 or more runs, or if after 3½ innings the home team is ahead by the same, the game will be ended and the leading team declared the winner.
1. If after 5 or more complete innings the visiting team is ahead in the score by 12 or more runs, or if after 4½ innings or more the home team is ahead by the same, the game will be ended and the leading team declared the winner.
The Slaughter Rule is applicable for the playoffs as specified in [Completion of Playoff Games](#completion-of-playoff-games).
1. If a game is called after 3 complete innings and one team is ahead by 10 or more runs, the game will be ended and the leading team declared the winner.
Postseason games are exempt from this definition as specified in [Completion of Playoff Games](#completion-of-playoff-games).
1. If a game is postponed or otherwise called before it has become a regulation game, the umpire-in-chief shall declare it “No Game,” meaning the game must be restarted (not resumed) at a later date.
Postseason games are exempt from this definition as specified in [Completion of Playoff Games](#completion-of-playoff-games).
### Reasons for a Game to be Called
An umpire, in their discretion, may declare a game called if
1. Darkness prevents further safe play.
1. Rain, lightning, or other inclement weather precludes safe conditions.
1. A new inning would start after 8:15 p.m at a field without lights.
1. Local laws or field rules (e.g. lightning detector) prevent continuation of the game.
1. Other circumstances prevent further safe play. The Rules and Competition Committee may rule on any forfeit or loss of points as applicable.
### Game Time
The starting time for all weeknight games shall be 5:50 p.m. for fields without lights. Starting times for games played at lighted fields and on the weekends shall be determined by the League and may legally begin after 6:30PM. Forfeit time shall be 20 minutes after the scheduled starting time.
### Player Uniforms
All players must be in proper uniform in order to be eligible to participate in games, as specified in [Uniform](#uniform).
### Minimum Number of Players
Teams must start the game at the scheduled starting time if they have at least eight (8) players present. A team may not wait until forfeit time for players to arrive, the game must begin as soon as a team has 8 players present. If a ninth player does not arrive or arrives after forfeit time, the team shall be in technical forfeit, as defined in [Forfeits](#forfeits).
1. In the event a team starts a game with eight (8) players, the ninth spot in the batting order shall be considered an out recorded to the pitcher. A team may insert a ninth player in the vacant ninth spot after the start of play.
1. A team may begin a game with eight (8) players up to two (2) times in one season. A team that fails to field nine (9) players at the start of the game after receiving 2 (two) prior technical forfeits shall forfeit all subsequent games.
1. A team in technical forfeit shall remain in technical forfeit, regardless of the number of players with which it finished the game.
A team may finish the game a player short, that is one (1) player less than they started the game with (eight (8) players for a nine (9) man line-up, nine (9) players for a ten (10) man), provided the team does not fall below this minimum.
1. The vacated spot in the batting order shall be considered an automatic out.
1. Should a team fall below the minimum, the game is terminated and the team loses by forfeit.
### Player Injuries
Should a player suffer a debilitating injury during the game and cannot continue, and a team has no more eligible players on its bench, a team can use a player that was removed from the game to replace him. This replacement player must be the first player removed from the game, and if this player is unavailable the next player is used (and so on). If no reserve is present, the vacated spot in the lineup is skipped and all batters move up accordingly, with no penalty to the affected team.
1. If a substantial case can be made that a team skipped a spot with the intent to gain a competitive advantage, a protest by the opposing team may retroactively be ruled as a forfeit.
### Equipment
1. Baseballs: Only Major League regulation balls will be allowed for game play. Accepted brands and ball types include, but are not limited to, the Rawlings RO series, Wilson A1000 series, and Diamond D-1 series. The home team must supply two (2) and the visitors one (1) ball at the start of each game. Additional balls shall be supplied alternately by each team beginning with the visiting team. Teams that supply non-approved balls shall forfeit the game.
1. Bats: All bats must be wood or BBCOR certified. Use of an illegal bat shall be subject to the Major League rules that govern this area.
1. Bases, home plate, and pitching rubber: All teams are expected to have a set of bases, a home plate, and a pitching rubber. These items shall conform to Major League Baseball specifications. Items conforming to 2022 specifications shall also be considered legal.
The home team shall be responsible for accurately setting up the bases, and if necessary, home plate and the pitching rubber. Should the home team fail to have these necessities by the start of the game, they will lose by forfeit. The visiting team can lend the equipment, although they are not required to do so.
### Field Maintenance
All teams are responsible for the maintenance and cleanup of the field and dugout areas after a game. Both teams must fill in all infield, batters box, and pitching mound holes. Additionally, both teams must have adequate equipment on hand for field maintenance. Teams who repeatedly fail to do proper post-game maintenance shall be fined.
### Payment of Umpires
Umpires are to be paid on the field promptly upon request.
### Designated Hitter
The Association shall follow the Major League designated hitter rule at all times, with the exception that a team may designate a D.H. for any position on the field.
### Designated Runner
The Association shall elect to use a designated runner rule, similar to the designated hitter rule.
1. A runner may be designated to run for a specified player in any game without otherwise affecting the status of the player(s) in the game.
1. The designated runner must take the place of the specified player whenever that player reaches base or the designated runner.
1. If the specified player is substituted, this substitute player may inherit the designated runner.
1. Designated runners are subject to the same substitution rules as the designated hitter as defined in [Designated Hitter](#designated-hitter)
1. Teams with no eligible players remaining on the bench (i.e. all players are in the batting lineup) may elect to use the player that made the last out as the designated runner.
### Extra Hitter
Prior to the start of the game a team may choose to play an extra hitter (EH). If the team uses this option, the following conditions apply:
1. An EH shall only bat. They cannot take a position in the field as a tenth fielder.
1. The EH shall be treated like any other position in the field. He can be substituted for, switch positions, or anything else that a position player can do.
1. There is no limit to the number of extra hitters a team may elect to use, provided the names and numbers of these players are included in the lineup exchanged before the game.
### Courtesy Runner
Teams may use courtesy runners for pitchers and catchers at any time. It is not mandatory to do so (speed-up rule), but the umpire(s) are required to keep the game moving expeditiously.
1. Courtesy runners for pitchers and catchers cannot be, or have been, in the game at any time other than as a courtesy runner. Teams with no eligible players remaining on the bench must use the first player taken out of the game or the player that made the last out.
1. The pitcher or catcher must play at least one (1) defensive out to be eligible for a courtesy runner unless they reach base in the first inning as a member of the visiting team.
### Batting Lineup
The batting lineup shall consist of at minimum 9 slots (or 8 adhering to section [Minimum Number of Players](#minimum-number-of-players)). Additional slots may be used without limit (see [Extra Hitter](#extra-hitter)). Any player may be substituted in their batting lineup slot by using a pinch-hitter or pinch-runner for that player. The original player may not re-enter the game as a hitter.
### A/B Batting Lineup Slots
In regular season play, any batting lineup slot may be optionally designated as an "A/B" batting slot, meaning it is shared between two players adhering to the following rules:
1. The batter designated "A" shall bat the first time through the lineup and the batter designated "B" batting the second time through the lineup, continuing in alternating fashion for the remainder of the game.
2. Rules for the substitutions of either "A" or "B" batter are the same as any other batting lineup slot.
3. In the event of injury of either player when there are no reserve players available, the uninjured player shall bat in place of the injured player without penalty.
In postseason play, the A/B batting slot rule defined above shall not be applicable.
### Defensive Lineup
In regular season play, the defensive line-up is independent of the batting lineup and substitutions shall be allowed as follows:
1. Any player may be freely substituted in the defensive line-up at any time, without affecting the players in the batting line-up. Players may enter, exit, and re-enter the game in the defensive line-up without limitation.
In postseason play, the free defensive substitution rule defined above shall not be applicable and substitutions shall be made in accordance to applicable CMBA and MLB rules.
### Field Status
The home team shall be responsible for checking the status of the field in the event of rain. The home team must report the status of the field to the President and the assigned umpire no later than 2:00 pm for a weeknight game, and at least 2 hrs. before a weekend game. As a courtesy, the home team should also notify the visiting manager, but the visiting manager may also contact the President for information regarding the status of the field.
1. Any manager who knowingly falsifies information regarding the status of the field to avoid playing the game will be fined and the team will forfeit the game.
### Rescheduling
In the discretion of the president, a game may be postponed due to extraordinary circumstances. In the event a game is to be postponed, the president shall alert the managers in an expedient manner.
Managers from both teams must contact the President to confirm any changes that they wish to make to the official schedule. Teams may not change times, places, or dates of games without the consent of the President. Any such games played shall be considered unofficial.
Any postponed or suspended games must be rescheduled in a timely fashion by the managers of that game for the next possible date. If managers cannot come to an agreement in a timely fashion, the President may reschedule the game.
### Notification of Results
The winning team shall be responsible for notifying the President of the score of the game no later than 10:00 AM the day after the game was played via text message, email, or telephone call.
### Uncompleted Games
All games not completed by the end of the regular season shall count as losses for both teams unless a team deliberately attempts to avoid playing a sanctioned game. The team that was willing to play the game will be judged the forfeit winner if so ruled by the President.
### Substitution of an Umpire
Should a league sanctioned umpire fail to appear at game time, the teams can choose to play the game with an umpire(s) of mutual choosing. The President needs to be informed by both teams prior to the start of the game to make it official.
### Collisions
NO COLLISIONS ARE ALLOWED, UNLESS THE CONTACT RESULTS FROM A SLIDE. It is the base runners responsibility to slide or avoid contact. Fielders and runners must abide by Official Baseball Rules regarding Interference, Obstruction, and Catcher Collisions..
Unless the umpire rules that the contact was incidental or the result of Obstruction by the fielder, the runner shall be called out, the ball declared dead and the runner automatically ejected from the game. Per [Flagrant Collisions](#flagrant-collisions). if the collision is determined by the umpire to be flagrant the player may be subject to the further penalty as defined in that section.
### Umpire Disputes
Discussion of a disputed umpires call shall be limited to the managers, base coaches and the “aggrieved player. No player or other coach (third party) shall be allowed to leave the dugout or his defensive position to join in. The penalty for violating this rule shall be the immediate ejection from the game.
## Protest and Forfeits
### Timeframe and Reporting

View File

@@ -1,4 +1,4 @@
# Constitution
# Constitution {.unnumbered}
## Name; Objective

View File

@@ -1,154 +0,0 @@
# Playing Rules
## Playing Rules
Except where specified in this document, the CMBA shall follow the Official Baseball Rules of Major League Baseball.
The CMBA shall not incorporate the following rules of Major League Baseball:
- Rule 4.03(c)(4) specifying limitations on when a position player can pitch.
- Rule 5.02(c) specifying limitations on infielder placement.
- Rule 7.01(b) incorporating the parameters of the Extra Innings Rule, which includes starting each half-inning following the last regulation inning with a runner on second base.
- Rule 5.10(m)(1) limiting the number of mound visits.
- Rule 5.10(g) requiring that pitchers must face at least three batters.
- Rules 5.07(c) specifying time limits on pitchers and batters. Limitations on pitcher disengagements (i.e. pick-offs) shall also not be incorporated.
## Regulation Games
Games played under the auspices of both recognized Managers of the participating teams shall count as official. A regulation game is defined as follows
1. A regulation game consists of seven (7) innings, unless extended because of a tie score, or shortened because the home team needs none of its half of the seventh inning or only a fraction of it, or because the umpire calls the game in accordance with [Reasons for a Game to be Called](#reasons-for-a-game-to-be-called).
1. If the score is tied after seven completed innings play shall continue until (1) the visiting team has scored more total runs than the home team at the end of a completed inning, or (2) the home team scores the winning run in an uncompleted inning. If a regulation game is called with the score tied, it shall remain a tie game.
1. If a game is called by the umpire, per [Reasons for a Game to be Called](#reasons-for-a-game-to-be-called), it is a regulation (official) game:
1. If four innings have been completed;
1. If the home team has scored more runs in four or three and a fraction half-innings than the visiting team has scored in four completed half-innings;
1. If the home team scores one or more runs in its half of the fourth inning to tie the score.
Postseason games are exempt from this definition as specified in [Completion of Playoff Games](#completion-of-playoff-games).
1. Slaughter Rule: The game shall be ended and the leading team declared the winner:
1. If after 4 complete innings the visiting team is ahead in the score by 15 or more runs, or if after 3½ innings the home team is ahead by the same, the game will be ended and the leading team declared the winner.
1. If after 5 or more complete innings the visiting team is ahead in the score by 12 or more runs, or if after 4½ innings or more the home team is ahead by the same, the game will be ended and the leading team declared the winner.
The Slaughter Rule is applicable for the playoffs as specified in [Completion of Playoff Games](#completion-of-playoff-games).
1. If a game is called after 3 complete innings and one team is ahead by 10 or more runs, the game will be ended and the leading team declared the winner.
Postseason games are exempt from this definition as specified in [Completion of Playoff Games](#completion-of-playoff-games).
1. If a game is postponed or otherwise called before it has become a regulation game, the umpire-in-chief shall declare it “No Game,” meaning the game must be restarted (not resumed) at a later date.
Postseason games are exempt from this definition as specified in [Completion of Playoff Games](#completion-of-playoff-games).
## Reasons for a Game to be Called
An umpire, in their discretion, may declare a game called if
1. Darkness prevents further safe play.
1. Rain, lightning, or other inclement weather precludes safe conditions.
1. A new inning would start after 8:15 p.m at a field without lights.
1. Local laws or field rules (e.g. lightning detector) prevent continuation of the game.
1. Other circumstances prevent further safe play. The Rules and Competition Committee may rule on any forfeit or loss of points as applicable.
## Game Time
The starting time for all weeknight games shall be 5:50 p.m. for fields without lights. Starting times for games played at lighted fields and on the weekends shall be determined by the League and may legally begin after 6:30PM. Forfeit time shall be 20 minutes after the scheduled starting time.
## Player Uniforms
All players must be in proper uniform in order to be eligible to participate in games, as specified in [Uniform](#uniform).
## Minimum Number of Players
Teams must start the game at the scheduled starting time if they have at least eight (8) players present. A team may not wait until forfeit time for players to arrive, the game must begin as soon as a team has 8 players present. If a ninth player does not arrive or arrives after forfeit time, the team shall be in technical forfeit, as defined in [Forfeits](#forfeits).
1. In the event a team starts a game with eight (8) players, the ninth spot in the batting order shall be considered an out recorded to the pitcher. A team may insert a ninth player in the vacant ninth spot after the start of play.
1. A team may begin a game with eight (8) players up to two (2) times in one season. A team that fails to field nine (9) players at the start of the game after receiving 2 (two) prior technical forfeits shall forfeit all subsequent games.
1. A team in technical forfeit shall remain in technical forfeit, regardless of the number of players with which it finished the game.
A team may finish the game a player short, that is one (1) player less than they started the game with (eight (8) players for a nine (9) man line-up, nine (9) players for a ten (10) man), provided the team does not fall below this minimum.
1. The vacated spot in the batting order shall be considered an automatic out.
1. Should a team fall below the minimum, the game is terminated and the team loses by forfeit.
## Player Injuries
Should a player suffer a debilitating injury during the game and cannot continue, and a team has no more eligible players on its bench, a team can use a player that was removed from the game to replace him. This replacement player must be the first player removed from the game, and if this player is unavailable the next player is used (and so on). If no reserve is present, the vacated spot in the lineup is skipped and all batters move up accordingly, with no penalty to the affected team.
1. If a substantial case can be made that a team skipped a spot with the intent to gain a competitive advantage, a protest by the opposing team may retroactively be ruled as a forfeit.
## Equipment
1. Baseballs: Only Major League regulation balls will be allowed for game play. Accepted brands and ball types include, but are not limited to, the Rawlings RO series, Wilson A1000 series, and Diamond D-1 series. The home team must supply two (2) and the visitors one (1) ball at the start of each game. Additional balls shall be supplied alternately by each team beginning with the visiting team. Teams that supply non-approved balls shall forfeit the game.
1. Bats: All bats must be wood or BBCOR certified. Use of an illegal bat shall be subject to the Major League rules that govern this area.
1. Bases, home plate, and pitching rubber: All teams are expected to have a set of bases, a home plate, and a pitching rubber. These items shall conform to Major League Baseball specifications. Items conforming to 2022 specifications shall also be considered legal.
The home team shall be responsible for accurately setting up the bases, and if necessary, home plate and the pitching rubber. Should the home team fail to have these necessities by the start of the game, they will lose by forfeit. The visiting team can lend the equipment, although they are not required to do so.
## Field Maintenance
All teams are responsible for the maintenance and cleanup of the field and dugout areas after a game. Both teams must fill in all infield, batters box, and pitching mound holes. Additionally, both teams must have adequate equipment on hand for field maintenance. Teams who repeatedly fail to do proper post-game maintenance shall be fined.
## Payment of Umpires
Umpires are to be paid on the field promptly upon request.
## Designated Hitter
The Association shall follow the Major League designated hitter rule at all times, with the exception that a team may designate a D.H. for any position on the field.
## Designated Runner
The Association shall elect to use a designated runner rule, similar to the designated hitter rule.
1. A runner may be designated to run for a specified player in any game without otherwise affecting the status of the player(s) in the game.
1. The designated runner must take the place of the specified player whenever that player reaches base or the designated runner.
1. If the specified player is substituted, this substitute player may inherit the designated runner.
1. Designated runners are subject to the same substitution rules as the designated hitter as defined in [Designated Hitter](#designated-hitter)
1. Teams with no eligible players remaining on the bench (i.e. all players are in the batting lineup) may elect to use the player that made the last out as the designated runner.
## Extra Hitter
Prior to the start of the game a team may choose to play an extra hitter (EH). If the team uses this option, the following conditions apply:
1. An EH shall only bat. They cannot take a position in the field as a tenth fielder.
1. The EH shall be treated like any other position in the field. He can be substituted for, switch positions, or anything else that a position player can do.
1. There is no limit to the number of extra hitters a team may elect to use, provided the names and numbers of these players are included in the lineup exchanged before the game.
## Courtesy Runner
Teams may use courtesy runners for pitchers and catchers at any time. It is not mandatory to do so (speed-up rule), but the umpire(s) are required to keep the game moving expeditiously.
1. Courtesy runners for pitchers and catchers cannot be, or have been, in the game at any time other than as a courtesy runner. Teams with no eligible players remaining on the bench must use the first player taken out of the game or the player that made the last out.
1. The pitcher or catcher must play at least one (1) defensive out to be eligible for a courtesy runner unless they reach base in the first inning as a member of the visiting team.
## Batting Lineup
The batting lineup shall consist of at minimum 9 slots (or 8 adhering to section [Minimum Number of Players](#minimum-number-of-players)). Additional slots may be used without limit (see [Extra Hitter](#extra-hitter)). Any player may be substituted in their batting lineup slot by using a pinch-hitter or pinch-runner for that player. The original player may not re-enter the game as a hitter.
## A/B Batting Lineup Slots
In regular season play, any batting lineup slot may be optionally designated as an "A/B" batting slot, meaning it is shared between two players adhering to the following rules:
1. The batter designated "A" shall bat the first time through the lineup and the batter designated "B" batting the second time through the lineup, continuing in alternating fashion for the remainder of the game.
2. Rules for the substitutions of either "A" or "B" batter are the same as any other batting lineup slot.
3. In the event of injury of either player when there are no reserve players available, the uninjured player shall bat in place of the injured player without penalty.
In postseason play, the A/B batting slot rule defined above shall not be applicable.
## Defensive Lineup
In regular season play, the defensive line-up is independent of the batting lineup and substitutions shall be allowed as follows:
1. Any player may be freely substituted in the defensive line-up at any time, without affecting the players in the batting line-up. Players may enter, exit, and re-enter the game in the defensive line-up without limitation.
In postseason play, the free defensive substitution rule defined above shall not be applicable and substitutions shall be made in accordance to applicable CMBA and MLB rules.
## Field Status
The home team shall be responsible for checking the status of the field in the event of rain. The home team must report the status of the field to the President and the assigned umpire no later than 2:00 pm for a weeknight game, and at least 2 hrs. before a weekend game. As a courtesy, the home team should also notify the visiting manager, but the visiting manager may also contact the President for information regarding the status of the field.
1. Any manager who knowingly falsifies information regarding the status of the field to avoid playing the game will be fined and the team will forfeit the game.
## Rescheduling
In the discretion of the president, a game may be postponed due to extraordinary circumstances. In the event a game is to be postponed, the president shall alert the managers in an expedient manner.
Managers from both teams must contact the President to confirm any changes that they wish to make to the official schedule. Teams may not change times, places, or dates of games without the consent of the President. Any such games played shall be considered unofficial.
Any postponed or suspended games must be rescheduled in a timely fashion by the managers of that game for the next possible date. If managers cannot come to an agreement in a timely fashion, the President may reschedule the game.
## Notification of Results
The winning team shall be responsible for notifying the President of the score of the game no later than 10:00 AM the day after the game was played via text message, email, or telephone call.
## Uncompleted Games
All games not completed by the end of the regular season shall count as losses for both teams unless a team deliberately attempts to avoid playing a sanctioned game. The team that was willing to play the game will be judged the forfeit winner if so ruled by the President.
## Substitution of an Umpire
Should a league sanctioned umpire fail to appear at game time, the teams can choose to play the game with an umpire(s) of mutual choosing. The President needs to be informed by both teams prior to the start of the game to make it official.
## Collisions
NO COLLISIONS ARE ALLOWED, UNLESS THE CONTACT RESULTS FROM A SLIDE. It is the base runners responsibility to slide or avoid contact. Fielders and runners must abide by Official Baseball Rules regarding Interference, Obstruction, and Catcher Collisions..
Unless the umpire rules that the contact was incidental or the result of Obstruction by the fielder, the runner shall be called out, the ball declared dead and the runner automatically ejected from the game. Per [Flagrant Collisions](#flagrant-collisions). if the collision is determined by the umpire to be flagrant the player may be subject to the further penalty as defined in that section.
## Umpire Disputes
Discussion of a disputed umpires call shall be limited to the managers, base coaches and the “aggrieved player. No player or other coach (third party) shall be allowed to leave the dugout or his defensive position to join in. The penalty for violating this rule shall be the immediate ejection from the game.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

View File

@@ -1,3 +0,0 @@
# CMBA Constitution and By-Laws
2024-06-06

View File

@@ -1,10 +0,0 @@
@import url('https://fonts.googleapis.com/css2?family=Nunito+Sans:ital,opsz,wght@0,6..12,200..1000;1,6..12,200..1000&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Merriweather:ital,opsz,wght@0,18..144,300..900;1,18..144,300..900&display=swap');
:root {
--md-text-font: "Merriweather"
}
.md-nav__title {
font-family: "Nunito Sans";
}

185
js/quote.js Normal file
View File

@@ -0,0 +1,185 @@
(() => {
// Inject Quote buttons into Pandoc-style headings and copy a section-range quote to clipboard.
//
// Assumptions (matches your sample):
// - Headings are h1/h2 with stable ids (anchors).
// - A "section" is: the heading + all following sibling elements until the next heading
// of the same or higher level (H2 stops at next H2 or H1; H1 stops at next H1).
//
// Primary target: GroupMe. We optimize text/plain to be readable and "quote-like".
// We still provide text/html for rich paste targets (Docs/Email).
//
// No dependencies.
const HEADING_SELECTOR = "h1[id], h2[id]"; // change to "h2[id]" if you only want section-level
document.addEventListener("DOMContentLoaded", () => {
injectQuoteButtons();
});
function injectQuoteButtons() {
document.querySelectorAll(HEADING_SELECTOR).forEach((heading) => {
// Avoid double-injection
if (heading.querySelector(":scope > .quote-btn")) return;
const btn = document.createElement("button");
btn.type = "button";
btn.className = "quote-btn";
btn.textContent = "";
btn.innerHTML = `
<span class="quote-icon" aria-hidden="true"></span>
`;
btn.addEventListener("click", (e) => {
e.preventDefault();
e.stopPropagation();
onQuoteClick(btn, heading);
});
// Add a little separation from heading text
heading.appendChild(document.createTextNode(" "));
heading.appendChild(btn);
});
}
async function onQuoteClick(btn, heading) {
const originalText = btn.textContent;
try {
btn.textContent = "Copying…";
btn.disabled = true;
await copyQuotedSection(heading);
btn.textContent = "Copied";
setTimeout(() => {
btn.textContent = originalText;
btn.disabled = false;
}, 800);
} catch (err) {
console.error(err);
btn.textContent = "Failed";
setTimeout(() => {
btn.textContent = originalText;
btn.disabled = false;
}, 1200);
}
}
async function copyQuotedSection(heading) {
if (!heading.id) throw new Error("Heading missing id.");
const level = heading.tagName; // H1 or H2
// Clone heading + subsequent siblings for the quote range
const nodes = [];
nodes.push(heading.cloneNode(true));
let el = heading.nextElementSibling;
while (el) {
if (isBoundary(level, el)) break;
nodes.push(el.cloneNode(true));
el = el.nextElementSibling;
}
// Remove injected button from cloned heading (so it doesn't show up in pasted content)
nodes[0].querySelector(".quote-btn")?.remove();
const container = document.createElement("div");
nodes.forEach((n) => container.appendChild(n));
const href = buildAnchorUrl(heading.id);
// HTML (for rich paste targets)
const html = buildHtmlQuote(container.innerHTML, href);
// Plain text (optimized for GroupMe)
const plain = buildGroupMePlainQuote(container, href);
await writeClipboardMultiFormat({ html, plain, url: href });
}
function isBoundary(level, el) {
// Stop at next heading of same or higher rank.
// H2 stops at next H1 or H2.
// H1 stops at next H1.
if (level === "H1") return el.tagName === "H1";
if (level === "H2") return el.tagName === "H1" || el.tagName === "H2";
return false;
}
function buildAnchorUrl(id) {
const url = new URL(window.location.href);
url.hash = id;
return url.toString();
}
function buildHtmlQuote(innerHtml, href) {
const safeHref = escapeHtmlAttr(href);
const safeText = escapeHtml(href);
return `
<blockquote>
${innerHtml}
<p><a href="${safeHref}">${safeText}</a></p>
</blockquote>
`.trim();
}
function buildGroupMePlainQuote(container, href) {
// Create a readable quote-like block:
// - Prefix lines with "> " to visually indicate quoting (works even if not rendered specially)
// - Include Source link
const text = normalizePlainText(container);
const quoted = text
.split("\n")
.map((line) => (line.trim().length ? `> ${line}` : `>`))
.join("\n");
return `${quoted}\n> \n> Source: ${href}`;
}
function normalizePlainText(container) {
// Use innerText to approximate what the user sees (captures list numbering reasonably in many browsers).
// Then normalize spacing.
return (container.innerText || "")
.replace(/\r\n/g, "\n")
.replace(/\n{3,}/g, "\n\n")
.trim();
}
async function writeClipboardMultiFormat({ html, plain, url }) {
// Best path: multi-format clipboard write (Chromium/Edge, etc.)
if (navigator.clipboard?.write) {
const item = new ClipboardItem({
"text/html": new Blob([html], { type: "text/html" }),
"text/plain": new Blob([plain], { type: "text/plain" }),
// Best-effort URL type; some paste targets prefer this
"text/uri-list": new Blob([url], { type: "text/uri-list" }),
});
await navigator.clipboard.write([item]);
return;
}
// Fallback: plain text only
if (navigator.clipboard?.writeText) {
await navigator.clipboard.writeText(plain);
return;
}
throw new Error("Clipboard API unavailable.");
}
function escapeHtml(s) {
return String(s)
.replaceAll("&", "&amp;")
.replaceAll("<", "&lt;")
.replaceAll(">", "&gt;")
.replaceAll('"', "&quot;")
.replaceAll("'", "&#39;");
}
function escapeHtmlAttr(s) {
return escapeHtml(s);
}
})();

5
metadata.yml Normal file
View File

@@ -0,0 +1,5 @@
---
title: Chicago Metropolitan Baseball Association
subtitle: Constitution and By-Laws
date: 2024-06-06
---

View File

@@ -1,43 +0,0 @@
site_name: CMBA Constitution and By-Laws
docs_dir: ../docs
# Prevent accidental publishing of repo/CI/dev clutter
theme:
name: material
palette:
scheme: default
primary: blue
accent: red
features:
- navigation.instant
- navigation.tracking
- navigation.top
- toc.integrate
- search.highlight
- search.suggest
logo: assets/cmba-logo.svg
favicon: assets/cmba-favicon.png
extra_css:
- styles/extra.css
markdown_extensions:
- toc:
permalink: true
- admonition:
# - tables
nav:
- Home: index.md
- 01-consitution.md
- 02-bylaws.md
- 03-playing-rules.md
plugins:
- search
- offline
- enumerate-headings:
toc_depth: 2
exclude:
- index.md
validation:
links:
anchors: warn #this defaults to info, but it will cause broken links in anchor headers

View File

@@ -1,2 +0,0 @@
mkdocs-enumerate-headings-plugin==0.6
mkdocs-material==9.7

View File

@@ -0,0 +1,20 @@
-- Based on https://github.com/jgm/pandoc/issues/5071#issuecomment-856918980
-- For LaTeX documents, shift all headings down by one.
-- Make Level 1 unnumbered, or remove it if it contains the "hidden" class. (`# Title {.hidden}`)
function Header(el)
if el.level == 1 then
--check for hidden class. (Why didn't pandoc make this a set? `{class_name = true}`)
for i, v in ipairs(el.classes) do
if v == "hidden" then
--The empty list means remove the element
return {}
end
end
-- this may mean that there are two unnumbered classes, but that doesn't matter.
el.classes[#el.classes + 1] = "unnumbered"
else
-- all headings > 1 are shifted down so that you don't end up with 0.x.y headings.
el.level = el.level - 1
end
return el
end

309
styles/style.css Normal file
View File

@@ -0,0 +1,309 @@
/* CMBA Rulebook CSS for Pandoc HTML
Compatible with Pandoc's default HTML structure:
- header#title-block-header
- nav#TOC[role="doc-toc"]
- headings with ids/classes like .unnumbered
*/
@import url("https://fonts.googleapis.com/css2?family=Merriweather:ital,wght@0,400;0,700;1,400;1,700&display=swap");
:root{
--bg: #ffffff;
--fg: #111827; /* slate-900 */
--muted: #6b7280; /* gray-500 */
--border: #e5e7eb; /* gray-200 */
--card: #f9fafb; /* gray-50 */
--link: #1d4ed8; /* blue-700 */
--link-hover: #1e40af; /* blue-800 */
--code-bg: #0b1020; /* dark */
--code-fg: #e5e7eb;
--radius: 12px;
--content-max: 980px;
--toc-max: 320px;
}
/* Base */
html { scroll-behavior: smooth; }
body{
margin: 0;
background: var(--bg);
color: var(--fg);
/* Rulebook serif stack */
font-family:
"Merriweather",
"Georgia",
"Times New Roman",
Times,
"Liberation Serif",
serif;
line-height: 1.6;
font-size: 16px;
text-rendering: optimizeLegibility;
}
/* Layout: single column on mobile, TOC sidebar on wide screens */
body{
display: block;
}
/* Give anchored headings a little offset for mobile browser bars */
h1[id], h2[id], h3[id], h4[id], h5[id], h6[id]{
scroll-margin-top: 84px;
}
/* Main document container: Pandoc outputs direct children; we style them */
header#title-block-header,
nav#TOC,
main,
body > h1, body > h2, body > h3, body > h4, body > h5, body > h6,
body > p, body > ul, body > ol, body > table, body > blockquote, body > pre, body > hr,
body > dl{
max-width: var(--content-max);
margin-left: auto;
margin-right: auto;
}
/* Title block */
header#title-block-header{
padding: 20px 16px 8px;
border-bottom: 1px solid var(--border);
margin-bottom: 8px;
}
header#title-block-header .title{
margin: 0 0 6px;
font-size: 1.75rem;
line-height: 1.2;
letter-spacing: -0.02em;
}
header#title-block-header .subtitle{
margin: 0 0 8px;
color: var(--muted);
}
header#title-block-header .author,
header#title-block-header .date{
margin: 0;
color: var(--muted);
font-size: 0.95rem;
}
/* TOC card */
nav#TOC{
padding: 0 16px 12px;
margin-bottom: 10px;
}
nav#TOC > ul{
margin: 0;
padding: 14px 16px;
background: var(--card);
border: 1px solid var(--border);
border-radius: var(--radius);
}
nav#TOC ul{
list-style: none;
}
nav#TOC li{
margin: 6px 0;
}
nav#TOC a{
color: var(--link);
text-decoration: none;
}
nav#TOC a:hover{
color: var(--link-hover);
text-decoration: underline;
}
nav#TOC ul ul{
margin-top: 6px;
padding-left: 14px;
border-left: 2px solid var(--border);
}
/* Content padding */
body > *{
padding-left: 16px;
padding-right: 16px;
box-sizing: border-box;
}
/* Headings */
h1, h2, h3, h4, h5, h6{
line-height: 1.25;
margin: 22px auto 10px;
letter-spacing: -0.01em;
}
h1{ font-size: 1.55rem; }
h2{ font-size: 1.25rem; }
h3{ font-size: 1.1rem; }
h4{ font-size: 1.0rem; }
h5{ font-size: 0.95rem; }
h6{ font-size: 0.9rem; color: var(--muted); }
/* Unnumbered headings (Pandoc uses .unnumbered sometimes) */
.unnumbered{
scroll-margin-top: 84px;
}
/* Paragraphs and lists */
p{
margin: 0 auto 12px;
}
ul, ol{
margin: 0 auto 14px;
padding-left: 1.25rem;
}
li{
margin: 6px 0;
}
/* Links */
a{
color: var(--link);
text-decoration-thickness: 2px;
text-underline-offset: 3px;
}
a:hover{
color: var(--link-hover);
}
/* Blockquotes */
blockquote{
margin: 14px auto;
padding: 10px 14px;
border-left: 4px solid var(--border);
background: var(--card);
border-radius: 10px;
color: #111827;
}
blockquote p{ margin: 0; }
/* Horizontal rule */
hr{
border: 0;
border-top: 1px solid var(--border);
margin: 18px auto;
}
/* Tables */
table{
width: 100%;
border-collapse: collapse;
margin: 14px auto 18px;
overflow: hidden;
border: 1px solid var(--border);
border-radius: var(--radius);
display: block; /* enables horizontal scroll on small screens */
}
thead th{
background: var(--card);
text-align: left;
font-weight: 600;
}
th, td{
padding: 10px 12px;
border-bottom: 1px solid var(--border);
vertical-align: top;
}
tbody tr:last-child td{ border-bottom: 0; }
/* Code */
code{
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
font-size: 0.95em;
background: #f3f4f6;
padding: 0.12em 0.32em;
border-radius: 6px;
}
pre{
margin: 14px auto 18px;
padding: 12px 14px;
background: var(--code-bg);
color: var(--code-fg);
border-radius: var(--radius);
overflow: auto;
border: 1px solid rgba(255,255,255,0.08);
}
pre code{
background: transparent;
color: inherit;
padding: 0;
}
.quote-icon {
display: inline-block;
width: 0.9em;
height: 0.9em;
vertical-align: middle;
background-repeat: no-repeat;
background-size: contain;
background-image: url("data:image/svg+xml;utf8,\
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 448 512'>\
<path fill='currentColor' d='M96 224c0-35.3 28.7-64 64-64h32V64H160C71.6 64 0 135.6 0 224v64c0 70.7 57.3 128 128 128h32V288h-32c-17.7 0-32-14.3-32-32v-32zm256 0c0-35.3 28.7-64 64-64h32V64h-32c-88.4 0-160 71.6-160 160v64c0 70.7 57.3 128 128 128h32V288h-32c-17.7 0-32-14.3-32-32v-32z'/>\
</svg>");
}
.quote-btn {
margin-left:.5rem;
font-size:.8em;
vertical-align:middle;
}
/* Small-screen polish */
@media (max-width: 520px){
header#title-block-header .title{ font-size: 1.45rem; }
body{ font-size: 16px; }
nav#TOC > ul{ padding: 12px 14px; }
}
/* Wide-screen layout: TOC sidebar + content */
@media (min-width: 1080px){
body{
display: grid;
grid-template-columns: minmax(260px, var(--toc-max)) minmax(0, 1fr);
gap: 18px;
align-items: start;
padding: 18px;
}
/* Remove the auto max-width behavior inside grid; we manage widths here */
header#title-block-header,
nav#TOC,
body > h1, body > h2, body > h3, body > h4, body > h5, body > h6,
body > p, body > ul, body > ol, body > table, body > blockquote, body > pre, body > hr,
body > dl{
max-width: none;
margin-left: 0;
margin-right: 0;
}
header#title-block-header{
grid-column: 1 / -1;
padding: 16px 18px 10px;
border: 1px solid var(--border);
border-radius: var(--radius);
background: var(--bg);
margin-bottom: 0;
}
nav#TOC{
grid-column: 1;
padding: 0;
margin: 0;
position: sticky;
top: 18px;
max-height: calc(100vh - 36px);
overflow: auto;
}
nav#TOC > ul{
margin: 0;
}
/* Treat the rest of the content as column 2 */
body > :not(header#title-block-header):not(nav#TOC){
grid-column: 2;
padding-left: 0;
padding-right: 0;
max-width: var(--content-max);
}
}

View File

@@ -1,15 +0,0 @@
#!/bin/bash
set -euo pipefail
MKDOCS_STRICT="${MKDOCS_STRICT:-true}"
TMPDIR="${RUNNER_TEMP:-$TMPDIR}"
OUTPUT_DIR="${OUTPUT_DIR:-${TMPDIR}/dist/}"
# OFFLINE="${OFFLINE:-false}" # This doesn't seem to do anything, set by mkdocs.yml
MKDOCS_CONFIG="${MKDOCS_CONFIG:-mkdocs/mkdocs.yml}"
STRICT_FLAG=""
if [ "${MKDOCS_STRICT}" = "true" ]; then
STRICT_FLAG="--strict"
fi
echo "MKDOCS_STRICT: $MKDOCS_STRICT, STRICT_FLAG: $STRICT_FLAG"
mkdocs build ${STRICT_FLAG} -f $MKDOCS_CONFIG -d $OUTPUT_DIR

View File

@@ -1,5 +0,0 @@
BBCOR
MLB
RO
Rawlings
rostered

View File

@@ -1,25 +0,0 @@
# yaml-language-server: $schema=https://raw.githubusercontent.com/streetsidesoftware/cspell/main/cspell.schema.json
# The version of the configuration file format.
version: "0.2"
# The locale to use when spell checking. (e.g., en, en-GB, de-DE
language: en-US
useGitignore: true
globRoot: "../.."
allowCompoundWords: true
files:
- "**/*.md"
- ./README.md
dictionaryDefinitions:
- name: baseball-words
path: ./baseball-words.txt
dictionaries:
- baseball-words
words:
- cmba
- chicagoland
- gitdriver