mlt-xml
Version:
A module to construct Media Lovin' Toolkit (MLT) projects and export them in XML.
227 lines (206 loc) • 8.8 kB
JavaScript
function isPrimitive(value) {
const valueType = typeof value;
return valueType === "string" || valueType === "boolean" || valueType === "number" && !Number.isNaN(value);
}
const XML_CHARACTER_MAP = {
"&": "&",
'"': """,
"'": "'",
"<": "<",
">": ">"
};
function espaceValueForXml(value) {
if (typeof value === "boolean") {
return value ? "1" : "0";
}
if (typeof value === "number") {
return `${value}`;
}
return value.replace(/([&"<>'])/g, (_str, item) => XML_CHARACTER_MAP[item]);
}
function attributesToXml(obj, attributeKeys) {
return Object.entries(obj).filter((entry) => attributeKeys.has(entry[0]) && isPrimitive(entry[1])).map(([key, value]) => `${espaceValueForXml(key)}="${espaceValueForXml(value)}"`).join(" ");
}
function propertiesToXml(obj, propertyKeys, depth = "") {
return Object.entries(obj).filter((entry) => propertyKeys.has(entry[0]) && isPrimitive(entry[1])).map(([name, value]) => `${depth} <property name="${espaceValueForXml(name)}">${espaceValueForXml(value)}</property>`);
}
function objToXml(obj, attributeKeys, propertyKeys, children, depth = "") {
const attributes = attributesToXml(obj.attributes, attributeKeys);
const properties = propertiesToXml(obj.attributes, propertyKeys, depth);
const allChidren = [...properties, ...children];
if (allChidren.length > 0) {
return `${depth}<${obj.name}${attributes.length > 0 ? " " : ""}${attributes}>
${allChidren.join("\n")}
${depth}</${obj.name}>`;
}
return `${depth}<${obj.name}${attributes.length > 0 ? " " : ""}${attributes}/>`;
}
const isBlank = (obj) => obj.name === "blank";
const BLANK_ATTRIBUTES_SET = /* @__PURE__ */ new Set(["length"]);
const BLANK_PROPERTIES_SET = /* @__PURE__ */ new Set();
function blankToXml(blank, depth) {
return objToXml(blank, BLANK_ATTRIBUTES_SET, BLANK_PROPERTIES_SET, [], depth);
}
const isChain = (obj) => obj.name === "chain";
const CHAIN_ATTRIBUTES_SET = /* @__PURE__ */ new Set(["id", "in", "out"]);
function chainToXml(chain, depth = "") {
const propertiesSet = new Set(Object.keys(chain.attributes).filter((key) => !CHAIN_ATTRIBUTES_SET.has(key)));
const children = elementsToXML(chain.elements || [], depth);
return objToXml(chain, CHAIN_ATTRIBUTES_SET, propertiesSet, children, depth);
}
const isConsumer = (obj) => obj.name === "consumer";
const CONSUMER_ATTRIBUTES_SET = /* @__PURE__ */ new Set(["id"]);
function consumerToXml(consumer, depth) {
const propertiesSet = new Set(Object.keys(consumer.attributes).filter((key) => key !== "id"));
return objToXml(consumer, CONSUMER_ATTRIBUTES_SET, propertiesSet, [], depth);
}
const isEntry = (obj) => obj.name === "entry";
const ENTRY_ATTRIBUTES_SET = /* @__PURE__ */ new Set(["producer", "in", "out"]);
const ENTRY_PROPERTIES_SET = /* @__PURE__ */ new Set([]);
function entryToXml(entry, depth = "") {
const children = elementsToXML(entry.elements || [], depth);
return objToXml(entry, ENTRY_ATTRIBUTES_SET, ENTRY_PROPERTIES_SET, children, depth);
}
const isFilter = (obj) => obj.name === "filter";
const FILTER_ATTRIBUTES_SET = /* @__PURE__ */ new Set(["id", "in", "out"]);
function filterToXml(filter, depth) {
const propertiesSet = new Set(Object.keys(filter.attributes).filter((key) => !FILTER_ATTRIBUTES_SET.has(key)));
return objToXml(filter, FILTER_ATTRIBUTES_SET, propertiesSet, [], depth);
}
const isLink = (obj) => obj.name === "link";
const LINK_ATTRIBUTES_SET = /* @__PURE__ */ new Set(["id", "in", "out"]);
function linkToXml(link, depth) {
const propertiesSet = new Set(Object.keys(link.attributes).filter((key) => !LINK_ATTRIBUTES_SET.has(key)));
return objToXml(link, LINK_ATTRIBUTES_SET, propertiesSet, [], depth);
}
const isMultitrack = (obj) => obj.name === "multitrack";
const MULTITRACK_ATTRIBUTES_SET = /* @__PURE__ */ new Set(["id"]);
const MULTITRACK_PROPERTIES_SET = /* @__PURE__ */ new Set([]);
function multitrackToXml(multitrack, depth = "") {
const children = elementsToXML(multitrack.elements, depth);
return objToXml(multitrack, MULTITRACK_ATTRIBUTES_SET, MULTITRACK_PROPERTIES_SET, children, depth);
}
const isPlaylist = (obj) => obj.name === "playlist";
const PLAYLIST_ATTRIBUTES_SET = /* @__PURE__ */ new Set(["id", "in", "out", "title"]);
const PLAYLIST_PROPERTIES_SET = /* @__PURE__ */ new Set(["autoclose", "meta.fx_cut", "hide", "mix_in", "mix_out"]);
function playlistToXml(playlist, depth = "") {
const children = elementsToXML(playlist.elements || [], depth);
return objToXml(playlist, PLAYLIST_ATTRIBUTES_SET, PLAYLIST_PROPERTIES_SET, children, depth);
}
const isProducer = (obj) => obj.name === "producer";
const PRODUCER_ATTRIBUTES_SET = /* @__PURE__ */ new Set(["id", "in", "out"]);
function producerToXml(producer, depth = "") {
const propertiesSet = new Set(Object.keys(producer.attributes).filter((key) => !PRODUCER_ATTRIBUTES_SET.has(key)));
const children = elementsToXML(producer.elements || [], depth);
return objToXml(producer, PRODUCER_ATTRIBUTES_SET, propertiesSet, children, depth);
}
const isProfile = (obj) => obj.name === "profile";
const PROFILE_ATTRIBUTES_SET = /* @__PURE__ */ new Set([
"name",
"colorspace",
"description",
"display_aspect_den",
"display_aspect_num",
"frame_rate_den",
"frame_rate_num",
"height",
"name",
"progressive",
"sample_aspect_den",
"sample_aspect_num",
"width"
]);
const PROFILE_PROPERTIES_SET = /* @__PURE__ */ new Set();
function profileToXml(profile, depth) {
return objToXml(profile, PROFILE_ATTRIBUTES_SET, PROFILE_PROPERTIES_SET, [], depth);
}
const isTrack = (obj) => obj.name === "track";
const TRACK_ATTRIBUTES_SET = /* @__PURE__ */ new Set(["producer", "hide"]);
const TRACK_PROPERTIES_SET = /* @__PURE__ */ new Set([]);
function trackToXml(track, depth = "") {
const children = elementsToXML(track.elements || [], depth);
return objToXml(track, TRACK_ATTRIBUTES_SET, TRACK_PROPERTIES_SET, children, depth);
}
const isTransition = (obj) => obj.name === "transition";
const TRANSITION_ATTRIBUTES_SET = /* @__PURE__ */ new Set(["id", "in", "out"]);
function transitionToXml(transition, depth) {
const propertiesSet = new Set(Object.keys(transition.attributes).filter((key) => !TRANSITION_ATTRIBUTES_SET.has(key)));
return objToXml(transition, TRANSITION_ATTRIBUTES_SET, propertiesSet, [], depth);
}
const isTractor = (obj) => obj.name === "tractor";
const TRACTOR_ATTRIBUTES_SET = /* @__PURE__ */ new Set(["id", "in", "out", "title"]);
function tractorToXml(tractor, depth = "") {
const propertiesSet = new Set(Object.keys(tractor.attributes).filter((key) => !TRACTOR_ATTRIBUTES_SET.has(key)));
const tracks = elementsToXML(
tractor.elements.filter((elem) => isMultitrack(elem) || isTrack(elem)),
depth
);
const children = elementsToXML(
tractor.elements.filter((elem) => isFilter(elem) || isTransition(elem)),
depth
);
return objToXml(tractor, TRACTOR_ATTRIBUTES_SET, propertiesSet, [...tracks, ...children], depth);
}
const EMPTY_SET = /* @__PURE__ */ new Set();
const elementsToXML = (elements = [], depth = "") => {
const newDepth = `${depth} `;
return elements.map((element) => {
if (isBlank(element)) {
return blankToXml(element, newDepth);
}
if (isChain(element)) {
return chainToXml(element, newDepth);
}
if (isConsumer(element)) {
return consumerToXml(element, newDepth);
}
if (isEntry(element)) {
return entryToXml(element, newDepth);
}
if (isFilter(element)) {
return filterToXml(element, newDepth);
}
if (isLink(element)) {
return linkToXml(element, newDepth);
}
if (isMultitrack(element)) {
return multitrackToXml(element, newDepth);
}
if (isPlaylist(element)) {
return playlistToXml(element, newDepth);
}
if (isProducer(element)) {
return producerToXml(element, newDepth);
}
if (isProfile(element)) {
return profileToXml(element, newDepth);
}
if (isTrack(element)) {
return trackToXml(element, newDepth);
}
if (isTractor(element)) {
return tractorToXml(element, newDepth);
}
if (isTransition(element)) {
return transitionToXml(element, newDepth);
}
return objToXml(element, EMPTY_SET, new Set(Object.keys(element.attributes)), [], newDepth);
});
};
const MLT_ATTRIBUTES_SET = /* @__PURE__ */ new Set(["LC_NUMERIC", "version", "root", "profile", "title", "producer"]);
const MLT_PROPERTIES_SET = /* @__PURE__ */ new Set([]);
function mltToXml(mlt) {
const { elements, ...attributes } = mlt;
const children = elementsToXML(elements);
return `<?xml version="1.0" encoding="utf-8"?>
${objToXml(
{
name: "mlt",
attributes
},
MLT_ATTRIBUTES_SET,
MLT_PROPERTIES_SET,
children
)}`;
}
export { mltToXml };