A rest argument keeps an empty first element; a removal block keeps its neighbour; the Markdown converter reads paragraphs whole; Smart App Control on the Windows page (from dev 1083db946f05)

- A rest argument (a list's or a table's items) now strips exactly ONE
  leading bar -- the separator from what precedes it -- so a second one is
  an empty first element: a table with an empty header corner is written
  `@table |` then ` | Maskulinum | ...`. Before, every leading bar was
  dropped and such a header row shifted one column left. New shipped suite
  tst/rest_test.sh.
- Text written hard against a closing ]# (a period, a letter) is no longer
  removed with the block; a following space or line break still is.
- sks/tns/md_to_sks.py converts inline Markdown per paragraph, so emphasis
  that wraps is converted and not mis-paired; bold may contain italic;
  tables are unnumbered; links to sibling .md files converted alongside
  become links to their html pages; the arrow becomes @rightarrow@.
- doc/install/windows_source_install.md: Smart App Control must be off --
  it blocks MSYS2's unsigned toolchain, and its Evaluation state turns
  itself on later.
This commit is contained in:
ack committed 2026-10-04 13:18:06 +02:00
1 parent 6e9889f7ae
commit bc2b3d8461
8 files changed
+244 -23

No files matched your search

+46 -8
View File
@@ -225,6 +225,17 @@ katom_list trim_part(katom_list part)
return trim(part, {katom_t::space, katom_t::newline, katom_t::bar});
}
// The trailing half of trim_part(): the leading side of a rest argument is
// decided bar by bar in argument_split().
static katom_list trim_trailing_part(katom_list part)
{
const std::set<katom_t> trim_types {katom_t::space, katom_t::newline, katom_t::bar};
while (!part.empty() && trim_types.contains(part.back().m_type)) {
part.pop_back();
}
return part;
}
std::tuple<katom_lists,katom_lists>
parameter_split(katom_list::const_iterator kbegin, katom_list::const_iterator kend)
{
@@ -330,24 +341,51 @@ argument_split(katom_list::const_iterator kbegin, katom_list::const_iterator ken
katom_lists optional {};
katom_list rest {};
for (auto p : parts) {
// function_symbol_parts() opens the first part with a bar of its own
// when the arguments do not begin with an option. Without positional
// parameters that bar is the first katom of the rest, and it is not
// the writer's.
bool rest_opens_synthetic = false;
for (std::size_t i = 0; i < parts.size(); i++) {
const auto& p = parts[i];
if (p[0].m_type == katom_t::option_name) {
optional.push_back(p);
} else if (positional.size() < positional_limit) {
positional.push_back(trim_part(p));
} else {
// Parts were trimmed, so adjacent parts would abut their bar
// katoms (a row separator "||" next to an empty cell's "|"
// would serialize as "|||"). A space keeps the writer's
// bar/double-bar distinction parseable.
if (!rest.empty()) {
if (rest.empty()) {
rest_opens_synthetic = (i == 0) && positional_limit == 0;
} else {
// Parts were trimmed, so adjacent parts would abut their bar
// katoms (a row separator "||" next to an empty cell's "|"
// would serialize as "|||"). A space keeps the writer's
// bar/double-bar distinction parseable.
rest.push_back(Katom(" ", katom_t::space, p[0].m_loc));
}
rest.insert(rest.end(), p.begin(), p.end());
}
}
return {positional, optional, trim_part(rest)};
}
// Exactly ONE written leading bar is stripped from the rest (decided
// 2026-10-01): it is the bar that separates the rest from what
// precedes it -- the last positional, the options, or the klammer name
// in the opening-bar idiom `@table |` with the rows on the lines below.
// Every further leading bar delimits an EMPTY FIRST ELEMENT the writer
// meant (`@table | | M | F ||` has an empty corner cell), mirroring
// kutil.rest_split, which strips one trailing delimiter and keeps all
// other empty elements. Trailing bars and whitespace are trimmed as
// before.
rest = trim_whitespace(rest);
if (rest_opens_synthetic && !rest.empty() && rest[0].m_type == katom_t::bar) {
rest.erase(rest.begin());
rest = trim_whitespace(rest);
}
if (!rest.empty() && rest[0].m_type == katom_t::bar && rest[0].m_text == "|") {
rest.erase(rest.begin());
rest = trim_whitespace(rest);
}
return {positional, optional, trim_trailing_part(rest)};
}
// Parameter/argument mapping