Option sets: a .o target for shared parameters
A named group of optional parameters, declared once and used by several
klammers, so a writer learns one vocabulary instead of a spelling per
klammer. The "o" target is a pseudo-target beside "k": "k" declares a
klammer's interface and documents it, "o" declares an option interface and
documents it, and neither produces output for any target.
@@caption_args.o :caption :number.bool true :caption_side.side
: Arguments that define a caption for a block element @@
@@code.k :filename @hpos_args :hpos left @ @caption_args :caption_side top @
| text.literal : A source file displayed verbatim @@
A set is used only in the parameter list of a ".k" declaration -- the one
place a klammer's interface is declared once for all of its targets -- and
is resolved as that list is read. Names and types come from the set; a
default may be overridden where it is used. A klammer application in a
parameter list is now a definition-time error.
The SKS gains the sets caption_args and hpos_args (:hpos and :offset), and
@table, @image, @image_grid, @reference and @show gain .k declarations. A
distance is no longer written as a position: :hpos 4em is rejected, and the
same layout is :hpos left :offset 4em. Code listings are numbered by
default, like tables and figures.
New engine sources mac/option_set{,_registry}.{h,cpp}; tst/ ships two more
suites, option_set_test.sh and signature_test.sh (twelve in all).
(from dev 34e536cb0329)
This commit is contained in:
@@ -207,12 +207,27 @@ void Machine::process_cond_katoms(katom_list& katoms)
|
||||
}
|
||||
|
||||
|
||||
// Expand the constant klammers written in a definition's BODY. A constant is
|
||||
// expanded at definition time, which is what makes it a constant; the body is
|
||||
// where that is meaningful.
|
||||
//
|
||||
// The parameter list is deliberately excluded. A klammer application there
|
||||
// is an error (see expand_option_sets): parameters shared between klammers
|
||||
// are declared by an option set, whose ".o" declaration is resolved as the
|
||||
// parameter list is read. Expanding a constant into a parameter list used to
|
||||
// be the way to share parameters, and it silently destroyed the parameter
|
||||
// list of a ".k" declaration -- the spliced options AND the declared
|
||||
// positionals -- surfacing only as an argument error at the first
|
||||
// application, in the document rather than the declaration.
|
||||
void Machine::expand_constant_klammers(katom_list& katoms, const Katom& op, const Katom& cl)
|
||||
{
|
||||
auto [begin, end] = find_span_katoms(katoms, op, cl);
|
||||
restore_initial_type(begin + 1, end - 1);
|
||||
if (std::find_if(begin + 1, end - 1, begin_klammer_apply) == end - 1) return;
|
||||
for (const auto& [app_op, app_cl] : find_spans(begin + 1, end - 1, begin_apply, end_apply, false, "def-time")) {
|
||||
auto body_begin = std::find_if(
|
||||
begin + 1, end - 1, [](const Katom& k) { return is_deftype(k.m_type); });
|
||||
if (body_begin == end - 1) return;
|
||||
if (std::find_if(body_begin, end - 1, begin_klammer_apply) == end - 1) return;
|
||||
for (const auto& [app_op, app_cl] : find_spans(body_begin, end - 1, begin_apply, end_apply, false, "def-time")) {
|
||||
auto [app_begin, app_end] = find_span_katoms(katoms, app_op, app_cl);
|
||||
if (app_begin->m_type == katom_t::apply_begin) {
|
||||
std::string name = trim_char(app_begin->m_text, '@');
|
||||
@@ -506,14 +521,27 @@ void Machine::load_klammerset_files(const Klammerset& klammerset, katom_iter ins
|
||||
m_katoms.insert(insert_at, loaded.begin(), loaded.end());
|
||||
}
|
||||
|
||||
// Register one "@@...@@" definition. An ".o" target declares an option set
|
||||
// -- parameters shared by klammers -- and goes to its own registry: it
|
||||
// defines no klammer and produces no output for any target.
|
||||
void Machine::add_definition(katom_list& katoms, const Katom& op, const Katom& cl)
|
||||
{
|
||||
expand_constant_klammers(katoms, op, cl);
|
||||
auto [begin, end] = find_span_katoms(katoms, op, cl);
|
||||
auto [name, target] = parse_name(m_targets, *begin);
|
||||
if (target == Target_registry::optionset_name) {
|
||||
m_option_sets.add(m_argtypes, name, begin, end, katoms);
|
||||
} else {
|
||||
m_klammers.add(m_argtypes, m_targets, m_option_sets, begin, end, katoms);
|
||||
}
|
||||
}
|
||||
|
||||
void Machine::extract_klammer_definitions(katom_list katoms)
|
||||
{
|
||||
fmsg() << katoms << "\n";
|
||||
(void)K::log(3);
|
||||
for (const auto& [op, cl] : find_spans(katoms, begin_klammer_def, end_klammer_def, true, command_name)) {
|
||||
expand_constant_klammers(katoms, op, cl);
|
||||
auto [begin, end] = find_span_katoms(katoms, op, cl);
|
||||
m_klammers.add(m_argtypes, m_targets, begin, end, katoms);
|
||||
add_definition(katoms, op, cl);
|
||||
}
|
||||
m_klammers.rationalize(m_targets);
|
||||
}
|
||||
@@ -522,9 +550,7 @@ void Machine::extract_klammer_definitions()
|
||||
{
|
||||
(void)K::log(3);
|
||||
for (const auto& [op, cl] : find_spans(m_katoms, begin_klammer_def, end_klammer_def, true, command_name)) {
|
||||
expand_constant_klammers(m_katoms, op, cl);
|
||||
auto [begin, end] = find_span_katoms(m_katoms, op, cl);
|
||||
m_klammers.add(m_argtypes, m_targets, begin, end, m_katoms);
|
||||
add_definition(m_katoms, op, cl);
|
||||
}
|
||||
m_klammers.rationalize(m_targets);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user