Repository navigation
XML Plus Compiler
xmlinc reads a skin source file that mixes ordinary enigma2 XML with a small set of extra constructs, resolves all of it, and writes out a single plain XML file with nothing left in it that enigma2 wouldn't understand natively.
-
Hierarchical includes —
<xmlinc file="name" .../>pulls inname.xmlinc(or any file with an explicit extension) in place, recursively. Included files are searched in order next to the source file, in its parent directory, in a shared "common" directory, and in that common directory's parent — so a plugin can override a shared building block just by placing a same-named file closer to its own skin. -
Parameters on includes, as
$vars— every extra attribute on an<xmlinc>tag becomes a$namevariable visible inside the included file (size=additionally exposes$width/$height). This is what makes an include reusable rather than a copy-paste target:<!-- Example.xml --> <xmlinc file="test" source="title"/>
<!-- test.xmlinc --> <widget ... source=$source .../>
compiles to:
<widget ... source="title" .../>
-
Relative positioning — a
position="x,y"attribute on an<xmlinc>tag is added to every widget position inside that include, recursively through nested includes. A sharedbuttons.xmlincblock of four pixmaps at0,0/300,0/600,0/900,0becomes a single reusable "button bar" you place anywhere just by choosing where to<xmlinc>it:<xmlinc file="buttons" position="100,200"/>
places the first button at
100,200, the second at400,200, and so on. -
An include's own size is exposed back to its parent — every
<xmlinc>sets$child_width/$child_heightto the bounding box (furthest right/bottom edge) of the content it just pulled in, measured in that file's own local 0,0-based coordinates, once its content is fully processed but before its ownposition=is resolved — so the include can reference its own just-measured size to place itself, with nothing hand-computed or hardcoded:<xmlinc file="screenpart_PRSPluginBody.xmlinc" position="eval(($screen_width-$child_width)/2),150"/>
centers that include horizontally, whatever width its content actually adds up to. The name is fixed, not per-file, so each
<xmlinc>overwrites it — only reliable for the include that was just processed (this one, on its ownposition=, or the very next thing after it), not an earlier sibling. -
Global variables —
<global name="x" value="y"/>defines$x;<screen size="w,h" .../>implicitly defines$screen_width/$screen_heightfor the whole file.$varsdon't need to be their own token —picon$indexsubstitutes just the$indexpart, so variables can be embedded in literals. -
Colors, checked at compile time — any
...Color="name"attribute is validated against colors declared via<color name="x" value="y"/>(normally collected from a sharedcolors.xmlinc) -
Per-tag defaults —
<default tag="widget" zPosition="1" transparent="1" .../>(normally collected from a sharedscreenpart_defaults.xmlinc, the same way colors are) fills in any attribute awidgetelement doesn't set itself; an attribute the element does set always wins. This is for a uniform look across plugins — change a value in one shared file instead of on every widget in every screen.tagcan optionally be narrowed to onerendervariant, e.g.<default tag="widget[render=Label]" font="$event_font"/>only fills widgets whose ownrender="Label"— since a plaintag="widget"block otherwise applies to every widget regardless of what it renders (Label, Pixmap, ProgressBar, ...). A render-specific block and a plaintag="widget"block can coexist: for a given attribute, the render-specific one wins if it sets that attribute, the plain one fills anything still unset, and the element's own attributes always win over both. Defaults are matched by tag name (plus optionalrender) only — no per-screen targeting — and, like colors, only take effect once the file declaring them has actually been reached via an<xmlinc>include — conventionally near the top ofskin.yml/skin.xml, alongsidecolors/fonts. A<default>element itself never appears in the compiled output. -
Formula evaluation —
eval(...)runs the enclosed expression as real arithmetic, so positions and sizes can be computed instead of hand-calculated:eval(($width-100)/2)centers a 100px-wide element. Division is automatically treated as integer (floor) division since pixel coordinates can't be fractional; if a formula still produces a float (e.g. from a scaling ratio) the result is rounded to the nearest pixel rather than truncated. -
Font/size sanity check — every widget with both a
fontand asizeis checked against a minimum-line-height heuristic; asizetoo short for itsfontproduces a warning identifying the screen, widget, font variable, and both values, catching text that would otherwise render clipped on the actual device. -
Verbatim passthrough — an include named
applet_*is inlined as raw text without any of the above processing, for embedding pre-rendered or foreign XML snippets unchanged.
xmlinc <source-file> <destination-file> <destination-dir> <common-dir>
-
source-file— the hierarchical skin source (e.g.skin.xml, or a screen's own.xml) -
destination-file— where the fully-resolved, flat XML is written -
destination-dir— the directoryxmlinctreats as the plugin's own skin directory when searching for includes -
common-dir— a shared directory of reusable.xmlincbuilding blocks (buttons, title bars, colors, ...) used across plugins
xmlcompile/ymlcompile call this per skin variant as part of a full build; run it directly only when working on a single file in isolation.