ArgInfo constructor
ArgInfo(
- TagContext tc,
- String data, {
- bool idFirst = true,
- bool stringFirst = true,
Parses the given string.
idFirst
: whether ID can be the first argumentstringFirst
: whether string can be the first argument
Notice: if idFirst
or stringFirst
is true, the first argument can not
be a name-value pair.
If both are false, you can use parse
instead. It is simpler.
Implementation
factory ArgInfo(TagContext tc, String data,
{bool idFirst = true, bool stringFirst = true}) {
if (!idFirst && !stringFirst)
return ArgInfo._('', false, parseArgs(data));
String? first;
bool isID = false;
if ((data = data.trim()).isNotEmpty) {
final c0 = data.codeUnitAt(0), len = data.length;
if (stringFirst && (c0 == $double_quote || c0 == $single_quote)) {
for (int i = 1; i < len; ++i) {
final cc = data.codeUnitAt(i);
if (cc == c0) {
first = data.substring(1, i);
data = data.substring(i + 1);
break; //done
}
if (cc == $backslash && i + 1 < len)
++i; //skip
}
} else if (idFirst) {
int i = 0;
for (; i < len && isValidVarCharCode(data.codeUnitAt(i), i == 0); ++i)
;
if (i > 0) {
first = data.substring(0, i);
data = data.substring(i).trim();
isID = true;
if (!data.isEmpty && data.codeUnitAt(0) == $equal)
tc.error("Unexpected '=' after an ID, $first"); //highlight common error
}
}
}
if (first != null)
return ArgInfo._(first, isID, parseArgs(data));
final sb = StringBuffer("The first argument must be ");
if (idFirst) {
sb.write("an ID");
if (stringFirst)
sb.write(" or ");
}
if (stringFirst)
sb.write("a string");
tc.error(sb.toString());
}