#!/bin/sh # Lists the docs pages and paragraphs that are too long, worst first. # # Pages have no size limit, so the worst offenders can't be found by eye. # This prints every markdown file under the given directory (default `docs`) # over a line limit, then every paragraph over a word limit, each sorted by # size. It is a report, not a gate: it exits 0 and is not in CI. Enforcement # comes once the list is worked down. # # scripts/doc-lengths.sh [-l LINES] [-w WORDS] [DIR] # # Defaults: 400 lines per page, 100 words per paragraph. # # A paragraph is a run of prose lines ended by a blank line, a heading, a table # row, a code fence or the next list item; a list item with its continuation # lines counts as one. Fenced code, tables, headings and HTML lines are not # paragraphs. set -eu lines=400 words=100 while getopts l:w: opt; do case $opt in l) lines=$OPTARG ;; w) words=$OPTARG ;; *) echo "usage: $0 [-l LINES] [-w WORDS] [DIR]" >&2; exit 2 ;; esac done shift $((OPTIND - 1)) dir=${1:-docs} [ -d "$dir" ] || { echo "$0: no such directory: $dir" >&2; exit 2; } find "$dir" -name '*.md' -type f | sort | xargs awk -v maxlines="$lines" -v maxwords="$words" ' function flush() { if (nwords > maxwords) { text = substr(first, 1, 60) para[np++] = sprintf("%6d %s:%d %s", nwords, para_file, para_line, text) } nwords = 0 first = "" } FNR == 1 { flush() if (prev_file != "" && prev_lines > maxlines) page[npg++] = sprintf("%6d %s", prev_lines, prev_file) prev_file = FILENAME fence = 0 para_file = FILENAME } { prev_lines = FNR } /^[ \t]*(```|~~~)/ { flush(); fence = !fence; next } fence { next } /^[ \t]*$/ { flush(); next } /^[ \t]*#+[ \t]/ { flush(); next } /^[ \t]*\|/ { flush(); next } /^[ \t]* maxlines) page[npg++] = sprintf("%6d %s", prev_lines, prev_file) printf "Pages over %d lines:\n", maxlines for (i = 0; i < npg; i++) print page[i] | "sort -rn" close("sort -rn") printf "\nParagraphs over %d words:\n", maxwords for (i = 0; i < np; i++) print para[i] | "sort -rn" close("sort -rn") }'