diff --git a/scripts/autogen.sh b/scripts/autogen.sh new file mode 100644 index 0000000..602a45d --- /dev/null +++ b/scripts/autogen.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +# Download libs +apk add --no-cache curl jq +npm install --save-dev xml-js + +# Download spec from source of truth +curl https://raw.githubusercontent.com/ietf-wg-cellar/matroska-specification/master/ebml_matroska.xml -o ebml_matroska.xml + +# Generate normalised schema +node convert.js | jq . > converted.json +node baseline.js | jq . > baselined.json + +# Compare +#diff --color=always -u baselined.json converted.json | less -r diff --git a/scripts/baseline.js b/scripts/baseline.js new file mode 100644 index 0000000..d8f98cf --- /dev/null +++ b/scripts/baseline.js @@ -0,0 +1,3 @@ +const schema = require("../lib/schema.js") + +console.log(JSON.stringify(schema.byEbmlID)) diff --git a/scripts/convert.js b/scripts/convert.js new file mode 100644 index 0000000..473fb37 --- /dev/null +++ b/scripts/convert.js @@ -0,0 +1,85 @@ +const convert = require("xml-js"), + fs = require("fs") + +const mapType = type => { + switch(type) { + case "binary": + return "b"; + case "date": + return "d"; + case "float": + return "f"; + case "integer": + return "i"; + case "master": + return "m"; + case "string": + return "s"; + case "uinteger": + return "u"; + case "utf-8": + return "8"; + default: + throw `Type ${type} not found`; + } +} + +fs.readFile("ebml_matroska.xml", (err, xml) => { + if (err) throw err; + const json = convert.xml2js(xml, {compact: true}) + + var out = {} + for (element of json.EBMLSchema.element) { + const key = parseInt(element._attributes["id"], 16) + + const docs = "documentation" in element + ? (Array.isArray(element.documentation) ? element.documentation : [element.documentation]) + : [] + const extensions = "extension" in element + ? (Array.isArray(element.extension) ? element.extension : [element.extension]) + : [] + + let value = {} + value["name"] = element._attributes["name"] + for (ext of extensions) { + if (ext._attributes.type == "libmatroska" && ("cppname" in ext._attributes)) { + value["cppname"] = ext._attributes.cppname + } + } + value["level"] = element._attributes["path"].split("\\").length - 2 + value["type"] = mapType(element._attributes["type"]) + if ("minOccurs" in element._attributes && element._attributes.minOccurs == 1) { + value["mandatory"] = true + } + if (!("maxOccurs" in element._attributes) || element._attributes.maxOccurs > 1) { + value["multiple"] = true + } + for (attr of ["minver", "maxver"]) { + if (attr in element._attributes) { + value[attr] = parseInt(element._attributes[attr]) + } + } + for (ext of extensions) { + if (ext._attributes.type == "webmproject.org" && ext._attributes.webm == "1") { + value["webm"] = true + } + if (ext._attributes.type == "divx.com" && ext._attributes.divx == "1") { + value["divx"] = true + } + } + for (attr of ["default", "range"]) { + if (attr in element._attributes) { + value[attr] = element._attributes[attr] + } + } + for (doc of docs) { + if (doc._attributes.purpose == "definition") { + value["description"] = doc._text.replace("\n", " ") + } + } + + out[key] = value + } + + console.log(JSON.stringify(out)) +})