Patrick@260: Patrick@260: start = publimeta Patrick@260: Patrick@260: Patrick@260: publimeta = element publimeta { Patrick@260: publimeta.attributes, Patrick@260: publimeta.content Patrick@260: } Patrick@260: Patrick@260: publimeta.attributes = Patrick@260: version.attribute Patrick@260: version.attribute = attribute version { "1.0" } Patrick@260: Patrick@260: publimeta.content = Patrick@260: metadatas Patrick@260: Patrick@260: Patrick@260: # ============================================================================= Patrick@260: # TOP LEVEL Patrick@260: # ============================================================================= Patrick@260: Patrick@260: # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ metadatas ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Patrick@260: Patrick@260: metadatas = element metadatas { metadatas.content } Patrick@260: Patrick@260: metadatas.content = Patrick@260: metadata+ Patrick@260: Patrick@260: # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Patrick@260: Patrick@260: metadata = element metadata { metadata.attributes, metadata.content } Patrick@260: Patrick@260: metadata.attributes = Patrick@260: metadata.for.attribute Patrick@260: & lang.attribute? Patrick@260: metadata.for.attribute = attribute for { xsd:NMTOKEN } Patrick@260: lang.attribute = attribute xml:lang { xsd:language } Patrick@355: Patrick@260: metadata.content = Patrick@384: (title & shorttitle? & subtitle*)? Patrick@260: & identifier* Patrick@260: & copyright* Patrick@260: & collection? Patrick@260: & contributors? Patrick@260: & date? Patrick@260: & keywordset? Patrick@260: & subjectset? Patrick@260: & abstract? Patrick@262: & price* Patrick@260: Patrick@260: Patrick@260: # ============================================================================= Patrick@260: # METADATA LEVEL Patrick@260: # ============================================================================= Patrick@260: Patrick@260: # ~~~~~~~~~~~~~~~~~~~~~~~ title, shorttitle, subtitle ~~~~~~~~~~~~~~~~~~~~~~~~~ Patrick@260: Patrick@260: title = element title { title.content } Patrick@260: shorttitle = element shorttitle { title.content } Patrick@260: subtitle = element subtitle { title.content } Patrick@260: Patrick@260: title.content = inlines Patrick@260: Patrick@260: # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ identifier ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Patrick@260: Patrick@260: # ~~~~~~ identifier Patrick@260: identifier = element identifier { Patrick@260: (attribute type { "ean" }, for.attribute?, xsd:token {pattern = "\d{13}"}) Patrick@260: | (attribute type { "uri" }, for.attribute?, xsd:anyURI) Patrick@260: } Patrick@260: Patrick@260: for.attribute = attribute for { xsd:NCName } Patrick@260: Patrick@260: # ~~~~~~ identifier.ean Patrick@260: identifier.ean = element identifier { Patrick@260: attribute type { "ean" }, for.attribute?, xsd:token {pattern = "\d{13}"} Patrick@260: } Patrick@260: Patrick@260: # ~~~~~~ identifier.uri Patrick@260: identifier.uri = element identifier { Patrick@260: attribute type { "uri" }, for.attribute?, xsd:anyURI Patrick@260: } Patrick@260: Patrick@260: # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ copyright ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Patrick@260: Patrick@260: copyright = element copyright { copyright.content } Patrick@260: Patrick@260: copyright.content = inlines Patrick@260: Patrick@260: # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ collection ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Patrick@260: Patrick@260: collection = element collection { collection.content } Patrick@260: Patrick@260: collection.content = inlines Patrick@260: Patrick@260: # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ contributors ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Patrick@260: Patrick@260: # ~~~~~~ contributors Patrick@260: contributors = element contributors { contributors.content } Patrick@260: Patrick@260: contributors.content = Patrick@260: contributor+ Patrick@260: Patrick@260: # ~~~~~~ contributor Patrick@260: contributor = element contributor { contributor.content } Patrick@260: Patrick@260: contributor.content = Patrick@263: identifier.uri?, Patrick@260: (((firstname, secondname?)?, lastname) | label), Patrick@260: address?, Patrick@260: link?, Patrick@260: role+ Patrick@260: Patrick@260: # ~~~~~~ firstname, secondname, lastname, label Patrick@260: firstname = element firstname { firstname.content } Patrick@260: secondname = element secondname { secondname.content } Patrick@260: lastname = element lastname { lastname.content } Patrick@260: label = element label { label.content } Patrick@260: Patrick@260: firstname.content = inlines Patrick@260: secondname.content = inlines Patrick@260: lastname.content = inlines Patrick@260: label.content = inlines Patrick@260: Patrick@260: # ~~~~~~ address Patrick@260: address = element address { address.content } Patrick@260: Patrick@260: address.content = inlines Patrick@260: Patrick@260: # ~~~~~~ role Patrick@260: role = element role { role.content } Patrick@260: Patrick@260: role.content = "author" | "illustrator" | "publisher" | "packager" Patrick@260: Patrick@260: # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ keyword & subject ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Patrick@260: Patrick@260: # ~~~~~~ keywordset Patrick@260: keywordset = element keywordset { keywordset.content } Patrick@260: Patrick@260: keywordset.content = keyword+ Patrick@260: Patrick@260: # ~~~~~~ keyword Patrick@260: keyword = element keyword { keyword.content } Patrick@260: Patrick@260: keyword.content = mixed { sup*, sub* } Patrick@260: Patrick@260: # ~~~~~~ subjectset Patrick@260: subjectset = element subjectset { subjectset.content } Patrick@260: Patrick@260: subjectset.content = subject+ Patrick@260: Patrick@260: # ~~~~~~ subject Patrick@260: subject = element subject { subject.content } Patrick@260: Patrick@260: subject.content = mixed { sup*, sub* } Patrick@260: Patrick@260: # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ abstract ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Patrick@260: Patrick@260: abstract = element abstract { abstract.content } Patrick@260: Patrick@260: abstract.content = Patrick@260: p+ Patrick@260: Patrick@260: # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ price ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Patrick@260: Patrick@260: price = element price { price.attributes, price.content } Patrick@260: Patrick@260: price.attributes = Patrick@260: currency.attribute Patrick@262: & excluding_tax.attribute Patrick@262: & tax.attribute? Patrick@265: & territory.attribute? Patrick@262: currency.attribute = attribute currency { Patrick@262: "EUR" | "USD" | "GBP" | "CAD" | "CHF" | "JPY" | "MXN" | "KRW" | "BRL" Patrick@262: | "INR" | "AUD" | "RUB" | "CNY" | "NOK" | "SEK" | "DKK" } Patrick@262: excluding_tax.attribute = attribute excluding-tax { xsd:boolean } Patrick@262: tax.attribute = attribute tax { xsd:float } Patrick@265: territory.attribute = attribute territory { xsd:NMTOKENS } Patrick@260: Patrick@260: price.content = xsd:float Patrick@355: Patrick@260: Patrick@260: # ============================================================================= Patrick@260: # BLOCK LEVEL Patrick@260: # ============================================================================= Patrick@260: Patrick@260: # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ p ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Patrick@260: Patrick@260: p = element p { p.content } Patrick@260: Patrick@260: p.content = Patrick@260: inlines Patrick@260: Patrick@260: Patrick@260: # ============================================================================= Patrick@260: # INLINE LEVEL Patrick@260: # ============================================================================= Patrick@260: Patrick@260: # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ inlines ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Patrick@260: Patrick@260: inlines = mixed { Patrick@260: sup* Patrick@260: & sub* Patrick@260: & date* Patrick@260: & name* Patrick@260: & highlight* Patrick@260: & link* Patrick@260: } Patrick@260: Patrick@260: # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ sub, sup ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Patrick@260: Patrick@260: sup = element sup { inlines } Patrick@260: Patrick@260: sub = element sub { inlines } Patrick@260: Patrick@260: # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ date ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Patrick@260: Patrick@260: date = element date { date.attributes, date.content } Patrick@260: Patrick@260: date.attributes = Patrick@260: date.value.attribute Patrick@260: date.value.attribute = attribute value { xsd:date | xsd:gYearMonth | xsd:gYear } Patrick@260: Patrick@260: date.content = mixed { sup* } Patrick@260: Patrick@260: # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ name ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Patrick@260: Patrick@260: name = element name { name.attributes, name.content } Patrick@260: Patrick@260: name.attributes = Patrick@260: name.of.attribute? Patrick@260: name.of.attribute = attribute of { Patrick@260: "person" | "company" | "book" | "newspaper" | "party" | "painting" Patrick@260: | "movie" } Patrick@260: Patrick@260: name.content = mixed { sup* } Patrick@260: Patrick@260: # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ highlight ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Patrick@260: Patrick@260: highlight = element highlight { highlight.content } Patrick@260: Patrick@260: highlight.content = inlines Patrick@260: Patrick@260: # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ link ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Patrick@260: Patrick@260: link = element link { link.attributes, link.content } Patrick@260: Patrick@260: link.attributes = Patrick@260: uri.attribute Patrick@260: uri.attribute = attribute uri { xsd:anyURI } Patrick@260: Patrick@260: link.content = mixed { sup* & sub* & date* & name* & highlight* } Patrick@260: Patrick@260: Patrick@260: # ============================================================================= Patrick@260: # REMAP ATTRIBUTES Patrick@260: # ============================================================================= Patrick@260: Patrick@260: remap.attributes = Patrick@260: as.attribute? Patrick@260: & attributes.attribute? Patrick@260: & transform.attribute? Patrick@260: as.attribute = attribute as { xsd:QName } Patrick@260: attributes.attribute = Patrick@260: attribute attributes {list { (xsd:token {pattern = "\c+=\S+"})+ }} Patrick@260: transform.attribute = attribute transform { xsd:anyURI }