aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander M Pickering <alex@cogarr.net>2026-08-03 21:52:33 -0500
committerAlexander M Pickering <alex@cogarr.net>2026-08-03 21:52:33 -0500
commit6705bdc69e1682982832ebea24e791581c44d0d2 (patch)
tree48ec63b522c03f4e0b5abf6a2cd520dc96ba7eee
parent21eb6acc2fdf0c43a2a1f6d4892cbd253909f82b (diff)
downloadtrbldoc-master.tar.gz
trbldoc-master.tar.bz2
trbldoc-master.zip
Allow comments to have tabsHEADmaster
Currently, comments need to be left-aligned, even if they appear in an indented block. change the comment form to strip the same whitespace as the first line so that comments can be indented without embedding indents in the stdin.
-rw-r--r--tests/fixtures/c/indented.c13
-rw-r--r--tests/fixtures/c/indented_tabs.c7
-rw-r--r--tests/helpers/common.bash33
-rw-r--r--tests/unit/extraction.bats40
-rw-r--r--trbldoc.sh42
5 files changed, 124 insertions, 11 deletions
diff --git a/tests/fixtures/c/indented.c b/tests/fixtures/c/indented.c
new file mode 100644
index 0000000..0b7a9f6
--- /dev/null
+++ b/tests/fixtures/c/indented.c
@@ -0,0 +1,13 @@
+enum my_enum {
+ /* md
+ @name my_enum/one
+ My explanation of type_one
+ */
+ type_one = 1;
+ /* md
+ @name my_enum/two
+ My explanation of type_two
+ relative indented line
+ */
+ type_two = 2;
+}
diff --git a/tests/fixtures/c/indented_tabs.c b/tests/fixtures/c/indented_tabs.c
new file mode 100644
index 0000000..5340f83
--- /dev/null
+++ b/tests/fixtures/c/indented_tabs.c
@@ -0,0 +1,7 @@
+enum e {
+ /* md
+ @name e/a
+ Tab-indented body
+ */
+ A = 1;
+}
diff --git a/tests/helpers/common.bash b/tests/helpers/common.bash
index 779cc96..12501bc 100644
--- a/tests/helpers/common.bash
+++ b/tests/helpers/common.bash
@@ -64,9 +64,18 @@ BEGIN{}
/\*\// {
if(in_comment) {print "EOF"}
in_comment=0
+ indent=""
+}
+in_comment {
+ line=\$0
+ if (indent != "" && index(line, indent) == 1) {
+ line=substr(line, length(indent)+1)
+ }
+ print line
}
-in_comment {print}
/\/\* .+/ && !/\*\// {
+ indent=\$0
+ sub(/[^[:space:]].*/, "", indent)
print "chunkfile=\$(mktemp -p ${cache}/chunks)"
print "cat > \$chunkfile << \"EOF\"\\n@file " name ":" NR ;
if(\$2) {\$1=""; print "@exec " \$0}
@@ -83,9 +92,18 @@ BEGIN{}
/\]\]/ {
if(in_comment) {print "EOF"}
in_comment=0
+ indent=""
+}
+in_comment {
+ line=\$0
+ if (indent != "" && index(line, indent) == 1) {
+ line=substr(line, length(indent)+1)
+ }
+ print line
}
-in_comment {print}
/--\[\[ .+/ && !/\]\]$/ {
+ indent=\$0
+ sub(/[^[:space:]].*/, "", indent)
print "chunkfile=\$(mktemp -p ${cache}/chunks)"
print "cat > \$chunkfile << \"EOF\"\\n@file " name ":" NR ;
if(\$2) {\$1=""; print "@exec " \$0}
@@ -103,9 +121,18 @@ BEGIN{}
/'''/ {
if(in_comment) {print "EOF"}
in_comment=0
+ indent=""
+}
+in_comment {
+ line=$0
+ if (indent != "" && index(line, indent) == 1) {
+ line=substr(line, length(indent)+1)
+ }
+ print line
}
-in_comment {print}
/'''.+/ && !/'''$/ {
+ indent=$0
+ sub(/[^[:space:]].*/, "", indent)
print "chunkfile=$(mktemp -p __PY_CACHE__/chunks)"
print "cat > $chunkfile << \"EOF\"\n@file " name ":" NR ;
renderer = $0
diff --git a/tests/unit/extraction.bats b/tests/unit/extraction.bats
index 21c6784..492d4e5 100644
--- a/tests/unit/extraction.bats
+++ b/tests/unit/extraction.bats
@@ -91,6 +91,46 @@ teardown() {
chunk_contains "$CACHE" "Second chunk content"
}
+@test "C: opening-tag indent is stripped from body lines" {
+ local prog chunk line
+ prog="$(awk_prog_c "$CACHE")"
+ run_extraction "$FIXTURES/c/indented.c" "$prog" "$CACHE"
+ assert_equal "$(chunk_count "$CACHE")" "2"
+ chunk_contains "$CACHE" "@name my_enum/one"
+ chunk_contains "$CACHE" "My explanation of type_one"
+ # Body lines must not retain the 4-space indent from before /*
+ if grep -rlE '^ @name |^ My explanation' "$CACHE/chunks" >/dev/null 2>&1; then
+ echo "FAILED: opener indent was left on body lines" >&2
+ grep -rn . "$CACHE/chunks" >&2 || true
+ return 1
+ fi
+ # Relative extra indent inside the comment is preserved after stripping opener indent
+ chunk=$(grep -rl "relative indented line" "$CACHE/chunks")
+ line=$(grep -F "relative indented line" "$chunk")
+ # shellcheck disable=SC2016
+ if [ "$line" != "$(printf '\trelative indented line')" ]; then
+ echo "FAILED: expected relative tab indent to remain after strip" >&2
+ printf 'got: %q\n' "$line" >&2
+ cat "$chunk" >&2
+ return 1
+ fi
+}
+
+@test "C: tab indent before opening tag is stripped from body lines" {
+ local prog chunk line
+ prog="$(awk_prog_c "$CACHE")"
+ run_extraction "$FIXTURES/c/indented_tabs.c" "$prog" "$CACHE"
+ assert_equal "$(chunk_count "$CACHE")" "1"
+ chunk=$(grep -rl "Tab-indented body" "$CACHE/chunks")
+ line=$(grep -F "Tab-indented body" "$chunk")
+ if [ "$line" != "Tab-indented body" ]; then
+ echo "FAILED: expected tab opener indent stripped from body" >&2
+ printf 'got: %q\n' "$line" >&2
+ cat "$chunk" >&2
+ return 1
+ fi
+}
+
# ── Lua (--[[ ... ]]) ──────────────────────────────────────────────────────
@test "Lua: single doc comment produces one chunk" {
diff --git a/trbldoc.sh b/trbldoc.sh
index 99e89be..4e27c28 100644
--- a/trbldoc.sh
+++ b/trbldoc.sh
@@ -183,18 +183,23 @@ BEGIN {
program_p = ""
ref_p = ""
}
-{sub(/\r$/, "", $0)}
/^[[:blank:]]*@file / && from_p == "" {
from_p = $0
sub(/^[[:blank:]]*@file /, "", from_p)
}
-/^[[:blank:]]*@name / && namespace_p == "" { namespace_p = $2 }
-/^[[:blank:]]*@priority / && priority_p == "" { priority_p = $2 }
+/^[[:blank:]]*@name / && namespace_p == "" {
+ namespace_p = $2
+}
+/^[[:blank:]]*@priority / && priority_p == "" {
+ priority_p = $2
+}
/^[[:blank:]]*@exec / && program_p == "" {
program_p = $0
sub(/^[[:blank:]]*@exec /, "", program_p)
}
-/^[[:blank:]]*@ref / && ref_p == "" { ref_p = $2 }
+/^[[:blank:]]*@ref / && ref_p == "" {
+ ref_p = $2
+}
END {
printf "%s%s%s%s%s%s%s%s%s\n", from_p, us, namespace_p, us, priority_p, us, program_p, us, ref_p
}
@@ -452,15 +457,27 @@ lua,\]\],\-\-\[\[
# Helper: write comment-extraction awk script from start/end regex pair.
# Uses single-quote splicing to inject shell variables into awk source.
+# Opening-tag indent (spaces/tabs before the start delimiter) is recorded and
+# stripped from subsequent body lines so indented source comments do not become
+# accidental Markdown code blocks.
_write_comment_form() {
printf '%s\n' '
BEGIN{}
/'"$2"'/ {
if(in_comment) {print "EOF"}
in_comment=0
+ indent=""
+}
+in_comment {
+ line=$0
+ if (indent != "" && index(line, indent) == 1) {
+ line=substr(line, length(indent)+1)
+ }
+ print line
}
-in_comment {print}
/'"$3"' .+/ && !/'"$2"'$/ {
+ indent=$0
+ sub(/[^[:space:]].*/, "", indent)
print "chunkfile=$(mktemp -p '"${cache_dir}"'/chunks)"
print "cat > $chunkfile << \"EOF\"\n@file " name ":" NR ;
if($2) {$1=""; print "@exec " $0}
@@ -488,17 +505,26 @@ for _alias_ext in moon tl; do
cp "$comment_form_dir/lua.awk" "$comment_form_dir/${_alias_ext}.awk" 2>/dev/null || true
done
-# Python: ''' is both the open and close delimiter. Renderer name is
+# Python: ''' is both the open and close delimiter; the renderer name is
# glued directly after the opening ''' with no space required (e.g. '''md).
-# Custom AWK uses sub() for renderer extraction instead of field splitting.
+# A custom AWK uses sub() for renderer extraction instead of field splitting.
sed "s|__PY_CACHE__|${cache_dir}|g" << 'PYAWK' > "$comment_form_dir/py.awk"
BEGIN{}
/'''/ {
if(in_comment) {print "EOF"}
in_comment=0
+ indent=""
+}
+in_comment {
+ line=$0
+ if (indent != "" && index(line, indent) == 1) {
+ line=substr(line, length(indent)+1)
+ }
+ print line
}
-in_comment {print}
/'''.+/ && !/'''$/ {
+ indent=$0
+ sub(/[^[:space:]].*/, "", indent)
print "chunkfile=$(mktemp -p __PY_CACHE__/chunks)"
print "cat > $chunkfile << \"EOF\"\n@file " name ":" NR ;
renderer = $0