fix(convert): track code fences when splitting OpenClaw sections, and pin it with an invariant (#855)

convert_openclaw() split on `## ` without tracking fenced code blocks, tearing six fenced examples across SOUL.md/AGENTS.md in five agents and leaving dangling fences in each. Implementation from #854 (@guozi-lab): fence helpers in lib.sh used by convert.sh and lint-agents.sh, CommonMark indent aware. Regression test from #853 (@dajiaohuang): every source fenced block must land whole in exactly one output file — verified to fail on the unfixed converter.

Reported by @AmineOzil. Closes #849. Supersedes #853 and #854.

Co-Authored-By: fruit <200041037+guozi-lab@users.noreply.github.com>
Co-Authored-By: Wu Shuwen <108231307+dajiaohuang@users.noreply.github.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Michael Sitarzewski
2026-09-12 11:57:20 -05:00
committed by GitHub
co-authored by fruit Wu Shuwen Claude Opus 5
parent 6d29a9b087
commit ad9264e309
5 changed files with 140 additions and 5 deletions
+28
View File
@@ -63,6 +63,34 @@ is_agent_file() {
[[ -f "$1" ]] && [[ "$(head -1 "$1")" == "---" ]]
}
# ---------------------------------------------------------------------------
# 1b. Markdown fenced-code-block helpers (issue #849)
# ---------------------------------------------------------------------------
# fence_open_p <line> — 0 if <line> opens a fence (3+ ` or ~, 03 leading
# spaces); sets BASH_REMATCH[1]=indent, [2]=marker run. Read those directly,
# not via $(), so the per-line convert/lint loops stay subshell-free. Else 1.
fence_open_p() {
local line="$1"
local re='^( {0,3})(`{3,}|~{3,})'
[[ "$line" =~ $re ]]
}
# fence_closes_p <line> <open_marker> <open_len> <open_indent> — 0 if <line>
# closes the open fence (same char, run len >= open, indent <= open); 1
# otherwise, including non-fence lines (callers need not pre-classify).
fence_closes_p() {
local line="$1" open_marker="$2" open_len="$3" open_indent="$4"
local re='^( {0,3})(`{3,}|~{3,})'
[[ "$line" =~ $re ]] || return 1
local close_indent=${#BASH_REMATCH[1]}
local close_run="${BASH_REMATCH[2]}"
[[ "${close_run:0:1}" == "$open_marker" ]] || return 1
(( ${#close_run} >= open_len )) || return 1
(( close_indent <= open_indent )) || return 1
return 0
}
# ---------------------------------------------------------------------------
# 2. set -e-safe primitives (absorbs #505 — no more `(( x++ )) || true`)
# ---------------------------------------------------------------------------