Files
klammertext/mac/argtype_set.h
Andy Kopra cacff229a1 feat(argtype): :alone - the value of an option written without one
An optional argument has three values: the default (the name is absent),
the argument type's :alone value (the name is written alone), and a
written value.

:alone is declared by the argument type only, never by a klammer's
parameter declaration -- a default is what one klammer means by silence,
but a bare option name must read the same way in every klammer.  The bool
type declares :alone true, which is the whole of the convention that a
bare boolean option means true; there is no boolean special case in the
engine.  A type whose pattern matches running text cannot declare :alone,
since an option's value runs to the next bar or option name and would
swallow the following text.

kdesc and `ktext -m` now show [default: X] and [alone: Y] per argument
type.

In the Standard Klammer Set: @code :number becomes a bool (it was an
untyped string tested only for truthiness, so a bare :number was a
no-op); decimal_mark declares :alone comma; table_hline and table_vline
declare :alone all.  The 35 bools that default false gained the bare form
for free.

Tests: tst/alone_test.sh (21 cases) joins the shipped suite.

(from dev 6024f49c2859)
2026-07-28 22:24:32 +02:00

93 lines
3.0 KiB
C++

#pragma once
#include <string>
#include <vector>
#include <map>
#include "argtype.h"
#include "katom.h"
#include "argument_set.h"
class Argtype_set
{
public:
static Parameter_set& parameters();
Argtype_set();
std::string replace_symbols(const std::string& pattern, const Locator& loc);
void check_for_existing_definition(const std::string& name, const Locator& loc);
void add(const std::string& name, const std::string& desc,
const std::string& pattern, const std::string& default_value,
const std::string& alone_value,
const std::string& python_cast, modify_string_f python_format,
const Locator& loc);
void add(std::vector<Katom>::iterator begin, std::vector<Katom>::iterator end, std::vector<Katom>& katoms);
Argtype get(const std::string& name, const Locator& loc) const;
std::string eval(const std::string& value, const std::string& type_name, const Locator& loc);
std::string describe(bool long_form=false, int indent_width=4) const;
inline bool is_defined(std::string name) {
return count(m_names.begin(), m_names.end(), name) > 0;
}
std::vector<std::string> m_names {};
std::map<std::string, Argtype> m_types {};
size_t m_name_size = 0;
size_t m_pattern_size = 0;
};
const
std::string default_argtype = "string";
const
std::vector<std::tuple<std::string, std::string, std::string, std::string, modify_string_f>> base_argtypes = {
{ "string", "arbitrary text",
R"((?:.|\n)*)", "str",
pyformat_string },
{ "word", "a series of characters without a space",
R"([^\s]+)", "str",
pyformat_string },
{ "bool", "a Boolean value of 'false', 'False', '0', 'true', 'True', or '1'",
R"(0|1|true|false|True|False)",
"(lambda b : True if b not in {'0','false','False'} else False)",
pyformat_bool },
{ "uint", "an integer greater than or equal to zero",
R"(\d\d*)", "int",
pyformat_number },
{ "int","an integer",
R"([-+]?'uint')", "int",
pyformat_number },
{ "float", "a floating-point number",
R"([-+]?(\d+(\.\d*)?|\.\d+))", "float",
pyformat_number },
{ "fraction", "a number in the form 'n/d'",
R"('int'/'uint')", "(lambda f : float(f.split('/')[0]) / float(f.split('/')[1]))",
pyformat_number },
{ "list", "list of elements separated by whitespace",
R"((?:.|\n)*)", "(lambda s : s.split())",
pyformat_list },
{ "dlist", "list of elements separated by the first word",
R"((?:.|\n)*)", "",
pyformat_dlist },
{ "rest", "the remaining arguments as a list nested to N dimensions "
"(rest(N)); the delimiter for dimension n is a run of n bar "
"characters, so | separates elements and || lists of elements",
R"((?:.|\n)*)", R"((lambda s : __import__("kutil").rest_split(s, N)))",
nullptr },
{ "literal", "literal text passed without interpretation",
R"((?:.|\n)*)", "str",
pyformat_string },
};