ometa XmlParser <: Parser {
document = preamble processingInstruction* element,
preamble = processingInstruction:pi ?(pi.name == "xml") ?(pi.attrs.version=="1.0"),
processingInstruction = tag( '', '?>' ),
element = startTag:s content:c endTag:e ?(s.name==e.name) -> [ '\'' + s.name + '\'', s.getId(), s.getVisual(), c ]
| emptyElement,
emptyElement = tag('<','/>'):t -> [ t ],
tag :startsWith :endsWith = token(startsWith) name:n attrs:a token(endsWith) -> { new Tag(n, a) },
startTag = tag('<','>'),
endTag = tag('','>'):t ?(!t.attrs._length) -> t,
name = ( '_' | letterOrDigit )+:n -> n.join(''),
attr = name:n "=" spaces quotedText:v -> ( [n, v] ),
attrs = ( spaces attr )*:a -> ( a.pairsToHash() ),
content = (textContent:c -> ( '"' + c.strip() + '"' )
| element:e)*,
textContent = (~'<' ( entity | anything ) )+:x -> x.join(''),
entity = '&' entityName:n ?(self.allowedEntityName( n ) ) ';' -> self.entityValue(n),
entityName = (~';' anything)+:x -> x.join(''),
quotedText = '"' (~'"' anything)+:x '"' -> x.join(''),
fromTo :x :y = seq(x) (~seq(y) char)* seq(y),
space = ^space | fromTo( '' )
}
XmlParser.allowedEntityName = function(name) {
return !! this.entities[name];
}
XmlParser.entityValue = function(name) {
return this.entities[name];
}
XmlParser.initialize = function() {
this.entities = { lt:'<', gt:'>', amp:'&' }
}
Array.prototype.pairsToHash = function() {
var hash = {};
for (var i = 0; i < this.length; i++) {
hash[this[i][0]] = this[i][1];
}
hash._length = this.length; /* Necessary for determining empty hashs */
return hash;
}
Object.prototype.keys = function() {
var keys = [];
for (i in this) if (this.hasOwnProperty(i)) {
keys.push(i);
}
return keys;
}
function Tag(name, attrs) {
this.name = name;
this.attrs = attrs;
this.content = null;
}
Tag.prototype.getKey = function(key) {
var value = this.attrs[key];
return (value == undefined) ? "''" : "'" + value + "'";
}
Tag.prototype.getId = function() {
return this.getKey("id");
}
Tag.prototype.getVisual = function() {
return this.getKey("visual");
}
Tag.prototype.setContent = function(content) {
this.content = content;
}
Tag.prototype.getAttrs = function() {
var keys = this.attrs.keys();
var r = "";
for (var i = 0; i < keys.length; i++) {
if (keys[i] != "_length") r += keys[i] + "=" + this.attrs[keys[i]] + " ";
}
return r;
}
Tag.prototype.getContent = function() {
if (typeof this.content == "string") return this.content;
if (this.content.length) {
var r = this.name + " " + this.getAttrs();
for (var i = 0; i < this.content.length; i++) {
if (typeof this.content[i] == "string") {
r += this.content[i];
} else {
r += " " + this.content[i].getContent();
}
}
return r;
} else {
return this.content.print();
}
}
Tag.prototype.print = function() {
return this.getContent();
}
ometa CodeTranslator {
trans = [:t ] -> ans,
a :id interp:t -> 'AA',
b :id interp:t -> 'BB',
c :id interp:t -> 'CC',
d :id interp:t -> 'DD'
}
/*x = XmlParser.matchAll('foothis is d', "document"); */
x = XmlParser.matchAll('', "document");
code = CodeTranslator.match(x, "trans");