dingodart 1.0.0
dingodart: ^1.0.0 copied to clipboard
Parser and DOM for the Dingo markup language in Dart
Dingo de Dart #
Dingo is an XML-like markup language designed to address some of its shortcomings (such as poorly thought-out entities, difficult-to-escape syntax, and limited character data blocks (CDATA).)
This is a Dart implementation of Dingo with a full parser and DOM. It ignores comments, but parses documents and can even create new ones from source. It also features a fairly intuitive but powerful query builder for finding nodes within a document.
Example #
example.dml
<# yeahg #>
<!dingo version="1.0">
<# test quotes #>
<test quote1="quo\\\"tes"/>
<test quote2=`back\`ticks`/>
<test quote3='apostro\'phe'>
<# cdata test #>
[!CDATA]チーズ = Cheese[!CEND]
<# text = "[!CEND]" #>
[!CDATA]\[!CEND][!CEND]
<# non-ASCII unquoted names and values #>
<チーズ />
<translation jp=チーズ en=Cheese />
</test>
<test quote4=no-quotes boolean-attribute>
<nest>
</nest>
<nest>
<egg />
<egg fried />
<egg>
<embryo />
</egg>
<egg />
</nest>
</test>
<$weird-tag note="this should parse just like any other tag" />
<!another-declaration>
main.dart
import 'dart:io';
import 'dingo.dart';
void main(List<String> arguments) async {
// parse ./test.dml
var doc = parseDocument(await File("./example.dml").readAsString());
// create new tag called <blegh>
var node = TagNode("blegh");
node["attribute"] = "value";
// create two text nodes (one cdata, to demonstrate the different text spacing rules)
node.appendChild(TextNode("weirdly\nspaced\nstring"));
node.appendChild(CdataNode("weirdly\nspaced\nstring"));
// add to document
doc.appendChild(node);
// note that if there is no <embryo/> this next section will fail silently
// find <egg> containing <embryo> -- this is an example of the 'query' system
var egg = doc.findTag((e) => e.nameIs("egg").hasChildWhere((e) => e.nameIs("embryo")));
// rename embryo to chick
var chick = egg?.findByName("embryo");
chick?.name = "chick";
// create and add brain
var brain = TagNode("brain");
brain["size"] = "small";
chick?.appendChild(brain);
// print updated source
print(doc.outerSource());
}
Expected Output #
<!dingo version="1.0">
<!another-declaration>
<test quote1="quo\\\"tes"/>
<test quote2="back`ticks"/>
<test quote3="apostro'phe">
[!CDATA]チーズ = Cheese[!CEND]
[!CDATA]\[!CEND][!CEND]
<チーズ/>
<translation jp="チーズ" en="Cheese"/>
</test>
<test quote4="no-quotes" boolean-attribute>
<nest/>
<nest>
<egg/>
<egg fried/>
<egg>
<chick>
<brain size="small"/>
</chick>
</egg>
<egg/>
</nest>
</test>
<$weird-tag note="this should parse just like any other tag"/>
<blegh attribute="value">
weirdly spaced string
[!CDATA]weirdly
spaced
string[!CEND]
</blegh>
Specifications #
No spec has been written. I will write one eventually, but for now...
- Documents must be UTF-8
- Names can contain any character except for:
`'"<=>[/\]!&*:
- All names break on whitespace.
- Attribute names also break on
=
,/>
or>
. - Tag names (and attribute values) also break on
/>
or>
. - Attribute values can be wrapped in
`
,"
or'
. If a value is not quoted, it should be parsed as a name. - Comments (delimited by
<#
and#>
) can be nested,<# <# like so. #> #>
- Declarations (delimited by
<!
and>
or/>
) are always self-closing. - Tag openers (delimited by
<
and>
or/>
) are self-closing if they end with/>
. - Tag closers (delimited by
</
and>
) must correspond with a tag closer (that is not self-closing) and cannot contain attributes. - Whitespace is allowed between delimiters, names, equals signs and values.
- Character data (CDATA) is enclosed in
[!CDATA]
and[!CEND]
blocks.[!CEND]
blocks can be escaped with a backslash. - All syntax can be escaped with backslashes (
\
) unless it occurs within a tag opener, tag closer, declaration or attribute. - All whitespace in non-CDATA text should be trimmed and collapsed into single-spaces.
- All text in CDATA blocks should be left completely unaltered aside from backslash escapes.