# HG changeset patch # User hartmut@demetrius.muc.goebel-consult.de # Date 1213700450 -7200 # Node ID aa3ae3d6c2cbfcdd42deb67d6b66259b59bbc5d5 # Parent 50d9f2b13a006d21340748ae0487fea0a07f305b Adding Relax NG schemas for XML files. diff -r 50d9f2b13a00 -r aa3ae3d6c2cb trytond/ir/ui/board.rnc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/trytond/ir/ui/board.rnc Tue Jun 17 13:00:50 2008 +0200 @@ -0,0 +1,145 @@ +namespace a = "http://relaxng.org/ns/compatibility/annotations/1.0" + +board = + element board { + attlist.board, + (image + | separator + | labe + | newline + | notebook + | group + | hpaned + | vpaned + | action)* + } +attlist.board &= + [ a:defaultValue = "Unknown" ] attribute string { text }? +attlist.board &= [ a:defaultValue = "4" ] attribute col { text }? +image = element image { attlist.image, empty } +attlist.image &= attribute name { text } +attlist.image &= [ a:defaultValue = "1" ] attribute colspan { text }? +attlist.image &= + [ a:defaultValue = "0" ] attribute expand { "0" | "1" }? +attlist.image &= [ a:defaultValue = "0" ] attribute fill { "0" | "1" }? +attlist.image &= attribute help { text }? +attlist.image &= attribute states { text }? +separator = element separator { attlist.separator, empty } +attlist.separator &= [ a:defaultValue = "" ] attribute string { text }? +attlist.separator &= attribute name { text }? +attlist.separator &= attribute states { text }? +attlist.separator &= + [ a:defaultValue = "0.0" ] attribute align { text }? +attlist.separator &= + [ a:defaultValue = "1" ] attribute colspan { text }? +attlist.separator &= + [ a:defaultValue = "0" ] attribute expand { "0" | "1" }? +attlist.separator &= + [ a:defaultValue = "0" ] attribute fill { "0" | "1" }? +attlist.separator &= attribute help { text }? +label = element label { attlist.label, empty } +attlist.label &= [ a:defaultValue = "" ] attribute string { text }? +attlist.label &= attribute name { text }? +attlist.label &= attribute states { text }? +attlist.label &= [ a:defaultValue = "0.0" ] attribute align { text }? +attlist.label &= + [ a:defaultValue = "0" ] attribute expand { "0" | "1" }? +attlist.label &= [ a:defaultValue = "0" ] attribute fill { "0" | "1" }? +attlist.label &= + [ a:defaultValue = "0" ] attribute xexpand { "0" | "1" }? +attlist.label &= [ a:defaultValue = "1" ] attribute xfill { "0" | "1" }? +attlist.label &= [ a:defaultValue = "1" ] attribute colspan { text }? +attlist.label &= attribute help { text }? +newline = element newline { attlist.newline, empty } +attlist.newline &= empty +notebook = element notebook { attlist.notebook, page* } +attlist.notebook &= + attribute tabpos { "up" | "down" | "left" | "right" }? +attlist.notebook &= [ a:defaultValue = "4" ] attribute colspan { text }? +page = + element page { + attlist.page, + (image + | separator + | labe + | newline + | notebook + | group + | hpaned + | vpaned + | action)* + } +attlist.page &= attribute angle { text }? +attlist.page &= + [ a:defaultValue = "Unknown" ] attribute string { text }? +attlist.page &= [ a:defaultValue = "4" ] attribute col { text }? +group = + element group { + attlist.group, + (image + | separator + | labe + | newline + | notebook + | group + | hpaned + | vpaned + | action)* + } +attlist.group &= attribute string { text }? +attlist.group &= [ a:defaultValue = "1" ] attribute colspan { text }? +attlist.group &= + [ a:defaultValue = "0" ] attribute expand { "0" | "1" }? +attlist.group &= [ a:defaultValue = "1" ] attribute fill { "0" | "1" }? +attlist.group &= [ a:defaultValue = "1" ] attribute rowspan { text }? +attlist.group &= [ a:defaultValue = "4" ] attribute col { text }? +hpaned = element hpaned { attlist.hpaned, child1?, child2? } +attlist.hpaned &= [ a:defaultValue = "4" ] attribute colspan { text }? +attlist.hpaned &= attribute position { text }? +vpaned = element vpaned { attlist.vpaned, child1?, child2? } +attlist.vpaned &= [ a:defaultValue = "4" ] attribute colspan { text }? +attlist.vpaned &= attribute position { text }? +child1 = + element child1 { + attlist.child1, + (image + | separator + | labe + | newline + | notebook + | group + | hpaned + | vpaned + | action)* + } +attlist.child1 &= empty +child2 = + element child2 { + attlist.child2, + (image + | separator + | labe + | newline + | notebook + | group + | hpaned + | vpaned + | action)* + } +attlist.child2 &= empty +data = element data { attlist.data, xpath+ } +attlist.data &= empty +xpath = element xpath { attlist.xpath, any } +attlist.xpath &= attribute expr { text } +attlist.xpath &= + [ a:defaultValue = "inside" ] + attribute position { "inside" | "replace" | "after" | "before" }? +action |= notAllowed +labe |= notAllowed +start = data | board | label +any = + (element * { + attribute * { text }*, + any + } + | text)* diff -r 50d9f2b13a00 -r aa3ae3d6c2cb trytond/ir/ui/board.rng --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/trytond/ir/ui/board.rng Tue Jun 17 13:00:50 2008 +0200 @@ -0,0 +1,477 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 1 + + + + + + + + + 0 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 1 + + + + + + + + + 0 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 1 + + + + + + + + + 0 + 1 + + + + + + + + + 0 + 1 + + + + + + + + + 0 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + up + down + left + right + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 1 + + + + + + + + + 0 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + inside + replace + after + before + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 50d9f2b13a00 -r aa3ae3d6c2cb trytond/ir/ui/form.rnc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/trytond/ir/ui/form.rnc Tue Jun 17 13:00:50 2008 +0200 @@ -0,0 +1,256 @@ +namespace a = "http://relaxng.org/ns/compatibility/annotations/1.0" + +form = + element form { + attlist.form, + (label + | field + | image + | separator + | newline + | button + | notebook + | group + | hpaned + | vpaned + | properties)* + } +attlist.form &= + [ a:defaultValue = "Unknown" ] attribute string { text }? +attlist.form &= attribute on_write { text }? +attlist.form &= [ a:defaultValue = "4" ] attribute col { text }? +attlist.form &= attribute cursor { text }? + +tree = element tree { attlist.tree, field+ } +attlist.tree &= + [ a:defaultValue = "Unknown" ] attribute string { text }? +attlist.tree &= attribute on_write { text }? +attlist.tree &= attribute editable { "top" | "bottom" }? +attlist.tree &= attribute sequence { text }? +attlist.tree &= attribute colors { text }? + +graph = element graph { attlist.graph, x, y } +attlist.graph &= + [ a:defaultValue = "vbar" ] + attribute type { "vbar" | "hbar" | "line" | "pie" }? +attlist.graph &= + [ a:defaultValue = "Unknown" ] attribute string { text }? +attlist.graph &= + [ a:defaultValue = "#f5f5f5" ] attribute background { text }? +attlist.graph &= [ a:defaultValue = "blue" ] attribute color { text }? +attlist.graph &= + [ a:defaultValue = "1" ] attribute legend { "0" | "1" }? + +x = element x { attlist.x, field } +attlist.x &= empty + +y = element y { attlist.y, field+ } +attlist.y &= empty + +label = element label { attlist.label, empty } +attlist.label &= [ a:defaultValue = "" ] attribute string { text }? +attlist.label &= attribute name { text }? +attlist.label &= attribute states { text }? +attlist.label &= [ a:defaultValue = "0.0" ] attribute align { text }? +attlist.label &= + [ a:defaultValue = "0" ] attribute expand { "0" | "1" }? +attlist.label &= [ a:defaultValue = "0" ] attribute fill { "0" | "1" }? +attlist.label &= + [ a:defaultValue = "0" ] attribute xexpand { "0" | "1" }? +attlist.label &= [ a:defaultValue = "1" ] attribute xfill { "0" | "1" }? +attlist.label &= [ a:defaultValue = "1" ] attribute colspan { text }? +attlist.label &= attribute help { text }? + +field = element field { attlist.field, (tree | form | graph)* } +attlist.field &= attribute name { text } +attlist.field &= [ a:defaultValue = "1" ] attribute colspan { text }? +attlist.field &= + attribute widget { + "date" + | "char" + | "many2one" + | "date" + | "one2many" + | "selection" + | "float" + | "numeric" + | "float_time" + | "interger" + | "datetime" + | "boolean" + | "text" + | "url" + | "email" + | "callto" + | "sip" + | "sha" + | "reference" + | "binary" + | "many2many" + | "image" + }? +attlist.field &= attribute saves { "0" | "1" }? +attlist.field &= attribute expand { "0" | "1" }? +attlist.field &= attribute fill { "0" | "1" }? +attlist.field &= attribute empty { "0" | "1" }? +attlist.field &= + [ a:defaultValue = "1" ] attribute xexpand { "0" | "1" }? +attlist.field &= [ a:defaultValue = "1" ] attribute xfill { "0" | "1" }? +attlist.field &= attribute help { text }? +attlist.field &= attribute width { text }? +attlist.field &= attribute height { text }? +attlist.field &= attribute readonly { text }? +attlist.field &= attribute required { text }? +attlist.field &= + [ a:defaultValue = "0" ] attribute tree_invisible { "0" | "1" }? +attlist.field &= attribute mode { text }? +attlist.field &= + [ a:defaultValue = "0" ] attribute completion { "0" | "1" }? +attlist.field &= + [ a:defaultValue = "0" ] attribute invisible { "0" | "1" }? +attlist.field &= attribute sum { text }? +attlist.field &= attribute key { text }? +attlist.field &= attribute domain { text }? +attlist.field &= attribute color { text }? +image = element image { attlist.image, empty } +attlist.image &= attribute name { text } +attlist.image &= [ a:defaultValue = "1" ] attribute colspan { text }? +attlist.image &= + [ a:defaultValue = "0" ] attribute expand { "0" | "1" }? +attlist.image &= [ a:defaultValue = "0" ] attribute fill { "0" | "1" }? +attlist.image &= attribute help { text }? +attlist.image &= attribute states { text }? +separator = element separator { attlist.separator, empty } +attlist.separator &= [ a:defaultValue = "" ] attribute string { text }? +attlist.separator &= attribute name { text }? +attlist.separator &= attribute states { text }? +attlist.separator &= + [ a:defaultValue = "0.0" ] attribute align { text }? +attlist.separator &= + [ a:defaultValue = "1" ] attribute colspan { text }? +attlist.separator &= + [ a:defaultValue = "0" ] attribute expand { "0" | "1" }? +attlist.separator &= + [ a:defaultValue = "0" ] attribute fill { "0" | "1" }? +attlist.separator &= attribute help { text }? +newline = element newline { attlist.newline, empty } +attlist.newline &= empty +button = element button { attlist.button, empty } +attlist.button &= [ a:defaultValue = "1" ] attribute colspan { text }? +attlist.button &= attribute help { text }? +attlist.button &= + [ a:defaultValue = "Unknown" ] attribute string { text }? +attlist.button &= attribute icon { text }? +attlist.button &= + [ a:defaultValue = "workflow" ] + attribute type { "workflow" | "object" | "action" }? +attlist.button &= attribute confirm { text }? +attlist.button &= attribute name { text } +attlist.button &= attribute states { text }? +notebook = element notebook { attlist.notebook, page* } +attlist.notebook &= + attribute tabpos { "up" | "down" | "left" | "right" }? +attlist.notebook &= [ a:defaultValue = "4" ] attribute colspan { text }? +page = + element page { + attlist.page, + (label + | field + | image + | separator + | newline + | button + | notebook + | group + | hpaned + | vpaned + | properties)* + } +attlist.page &= attribute angle { text }? +attlist.page &= + [ a:defaultValue = "Unknown" ] attribute string { text }? +attlist.page &= [ a:defaultValue = "4" ] attribute col { text }? +group = + element group { + attlist.group, + (label + | field + | image + | separator + | newline + | button + | notebook + | group + | hpaned + | vpaned + | properties)* + } +attlist.group &= attribute string { text }? +attlist.group &= [ a:defaultValue = "1" ] attribute colspan { text }? +attlist.group &= + [ a:defaultValue = "0" ] attribute expand { "0" | "1" }? +attlist.group &= [ a:defaultValue = "1" ] attribute fill { "0" | "1" }? +attlist.group &= [ a:defaultValue = "1" ] attribute rowspan { text }? +attlist.group &= [ a:defaultValue = "4" ] attribute col { text }? + +hpaned = element hpaned { attlist.hpaned, child1?, child2? } +attlist.hpaned &= [ a:defaultValue = "4" ] attribute colspan { text }? +attlist.hpaned &= attribute position { text }? + +vpaned = element vpaned { attlist.vpaned, child1?, child2? } +attlist.vpaned &= [ a:defaultValue = "4" ] attribute colspan { text }? +attlist.vpaned &= attribute position { text }? + +child1 = + element child1 { + attlist.child1, + (label + | field + | image + | separator + | newline + | button + | notebook + | group + | hpaned + | vpaned + | properties)* + } +attlist.child1 &= empty + +child2 = + element child2 { + attlist.child2, + (label + | field + | image + | separator + | newline + | button + | notebook + | group + | hpaned + | vpaned + | properties)* + } +attlist.child2 &= empty + +properties = element properties { attlist.properties, empty } +attlist.properties &= empty + +data = element data { attlist.data, xpath+ } +attlist.data &= empty + +xpath = element xpath { attlist.xpath, any } +attlist.xpath &= attribute expr { text } +attlist.xpath &= + [ a:defaultValue = "inside" ] + attribute position { "inside" | "replace" | "after" | "before" }? + +any = + (element * { + attribute * { text }*, + any + } + | text)* +start = data | form diff -r 50d9f2b13a00 -r aa3ae3d6c2cb trytond/ir/ui/form.rng --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/trytond/ir/ui/form.rng Tue Jun 17 13:00:50 2008 +0200 @@ -0,0 +1,841 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + top + bottom + + + + + + + + + + + + + + + + + + + + + + + + + + vbar + hbar + line + pie + + + + + + + + + + + + + + + + + + + + + + + + 0 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 1 + + + + + + + + + 0 + 1 + + + + + + + + + 0 + 1 + + + + + + + + + 0 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + date + char + many2one + date + one2many + selection + float + numeric + float_time + interger + datetime + boolean + text + url + email + callto + sip + sha + reference + binary + many2many + image + + + + + + + + + 0 + 1 + + + + + + + + + 0 + 1 + + + + + + + + + 0 + 1 + + + + + + + + + 0 + 1 + + + + + + + + + 0 + 1 + + + + + + + + + 0 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 1 + + + + + + + + + + + + + + 0 + 1 + + + + + + + + + 0 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 1 + + + + + + + + + 0 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 1 + + + + + + + + + 0 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + workflow + object + action + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + up + down + left + right + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 1 + + + + + + + + + 0 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + inside + replace + after + before + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 50d9f2b13a00 -r aa3ae3d6c2cb trytond/ir/ui/graph.rnc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/trytond/ir/ui/graph.rnc Tue Jun 17 13:00:50 2008 +0200 @@ -0,0 +1,40 @@ +namespace a = "http://relaxng.org/ns/compatibility/annotations/1.0" + +graph = element graph { attlist.graph, x, y } +attlist.graph &= + [ a:defaultValue = "vbar" ] + attribute type { "vbar" | "hbar" | "line" | "pie" }? +attlist.graph &= + [ a:defaultValue = "Unknown" ] attribute string { text }? +attlist.graph &= + [ a:defaultValue = "#f5f5f5" ] attribute background { text }? +attlist.graph &= [ a:defaultValue = "blue" ] attribute color { text }? +attlist.graph &= + [ a:defaultValue = "1" ] attribute legend { "0" | "1" }? +x = element x { attlist.x, field } +attlist.x &= empty +y = element y { attlist.y, field+ } +attlist.y &= empty +field = element field { attlist.field, empty } +attlist.field &= attribute name { text } +attlist.field &= attribute string { text }? +attlist.field &= attribute key { text }? +attlist.field &= attribute domain { text }? +attlist.field &= attribute fill { "0" | "1" }? +attlist.field &= attribute empty { "0" | "1" }? +attlist.field &= attribute color { text }? +attlist.field &= attribute widget { "float_time" }? +data = element data { attlist.data, xpath+ } +attlist.data &= empty +xpath = element xpath { attlist.xpath, any } +attlist.xpath &= attribute expr { text } +attlist.xpath &= + [ a:defaultValue = "inside" ] + attribute position { "inside" | "replace" | "after" | "before" }? +start = data | graph +any = + (element * { + attribute * { text }*, + any + } + | text)* diff -r 50d9f2b13a00 -r aa3ae3d6c2cb trytond/ir/ui/graph.rng --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/trytond/ir/ui/graph.rng Tue Jun 17 13:00:50 2008 +0200 @@ -0,0 +1,177 @@ + + + + + + + + + + + + + + vbar + hbar + line + pie + + + + + + + + + + + + + + + + + + + + + + + + 0 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 1 + + + + + + + + + 0 + 1 + + + + + + + + + + + + + float_time + + + + + + + + + + + + + + + + + + + + + + + + + + + + inside + replace + after + before + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 50d9f2b13a00 -r aa3ae3d6c2cb trytond/ir/ui/tree.rnc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/trytond/ir/ui/tree.rnc Tue Jun 17 13:00:50 2008 +0200 @@ -0,0 +1,55 @@ +namespace a = "http://relaxng.org/ns/compatibility/annotations/1.0" + +tree = element tree { attlist.tree, field+ } +attlist.tree &= + [ a:defaultValue = "Unknown" ] attribute string { text }? +attlist.tree &= attribute on_write { text }? +attlist.tree &= attribute editable { "top" | "bottom" }? +attlist.tree &= attribute sequence { text }? +attlist.tree &= attribute colors { text }? +attlist.tree &= + [ a:defaultValue = "0" ] attribute toolbar { "0" | "1" }? +field = element field { attlist.field, empty } +attlist.field &= attribute name { text } +attlist.field &= attribute readonly { text }? +attlist.field &= attribute required { text }? +attlist.field &= + attribute widget { + "char" + | "many2one" + | "date" + | "one2many" + | "selection" + | "float" + | "numeric" + | "float_time" + | "interger" + | "datetime" + | "boolean" + | "text" + | "url" + | "email" + | "callto" + | "sip" + }? +attlist.field &= + [ a:defaultValue = "0" ] attribute select { "0" | "1" | "2" }? +attlist.field &= + [ a:defaultValue = "0" ] attribute tree_invisible { "0" | "1" }? +attlist.field &= attribute icon { text }? +attlist.field &= attribute sum { text }? +attlist.field &= attribute width { text }? +data = element data { attlist.data, xpath+ } +attlist.data &= empty +xpath = element xpath { attlist.xpath, any } +attlist.xpath &= attribute expr { text } +attlist.xpath &= + [ a:defaultValue = "inside" ] + attribute position { "inside" | "replace" | "after" | "before" }? +start = tree | data +any = + (element * { + attribute * { text }*, + any + } + | text)* diff -r 50d9f2b13a00 -r aa3ae3d6c2cb trytond/ir/ui/tree.rng --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/trytond/ir/ui/tree.rng Tue Jun 17 13:00:50 2008 +0200 @@ -0,0 +1,184 @@ + + + + + + + + + + + + + + + + + + + + + + + + + top + bottom + + + + + + + + + + + + + + + + + + + 0 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + char + many2one + date + one2many + selection + float + numeric + float_time + interger + datetime + boolean + text + url + email + callto + sip + + + + + + + + + 0 + 1 + 2 + + + + + + + + + 0 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + inside + replace + after + before + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 50d9f2b13a00 -r aa3ae3d6c2cb trytond/tryton.rnc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/trytond/tryton.rnc Tue Jun 17 13:00:50 2008 +0200 @@ -0,0 +1,28 @@ +namespace a = "http://relaxng.org/ns/compatibility/annotations/1.0" + +tryton = element tryton { attlist.tryton, data* } +attlist.tryton &= empty +data = element data { attlist.data, (record | menuitem)* } +attlist.data &= + [ a:defaultValue = "0" ] attribute noupdate { "0" | "1" }? +record = element record { attlist.record, field* } +attlist.record &= attribute model { text } +attlist.record &= attribute id { text } +attlist.record &= + [ a:defaultValue = "0" ] attribute update { "0" | "1" }? +field = element field { attlist.field, text } +attlist.field &= attribute name { text } +attlist.field &= attribute search { text }? +attlist.field &= attribute model { text }? +attlist.field &= attribute ref { text }? +attlist.field &= attribute eval { text }? +attlist.field &= attribute type { "xml" }? +menuitem = element menuitem { attlist.menuitem, empty } +attlist.menuitem &= attribute id { text } +attlist.menuitem &= attribute name { text }? +attlist.menuitem &= attribute icon { text }? +attlist.menuitem &= attribute sequence { text }? +attlist.menuitem &= attribute parent { text }? +attlist.menuitem &= attribute action { text }? +attlist.menuitem &= attribute groups { text }? +start = tryton