Research
Security News
Malicious npm Packages Inject SSH Backdoors via Typosquatted Libraries
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Remixml is a sophisticated XML/XHTML macro language/templating compiler engine in Javascript.
The Remixml templating engine has the following features:
The language and primitives used, blend in completely with standard XML/XHTML syntax and therefore integrate smoothly with existing XML/XHTML syntax colouring editors.
Compiling and processing XML, XHTML and Remixml automatically performs sanity checks and shows clear and precise warnings about missing opening or closing tags.
The package includes a comprehensive regression-testsuite to assure code quality.
It runs inside any webbrowser or NodeJS environment supporting at least ECMAScript ES2018.
Minified and gzip-compressed, it is less than 7 KB of code.
It has zero dependencies on other modules.
It supports (but does not require) output to the incremental-dom.
In essence Remixml is a macro language that has XHTML/XML-like syntax and uses special entities to fill in templates. The entities that are recognised by Remixml are always of the form: &scope.varname; I.e. they distinguish themselves from regular HTML entities by always having at least one dot in the entity name.
The following sample Javascript code will illustrate the point:
Remixml.parse2txt(`
<h1>Title of &_.sitename; for &_.description;</h1>
<p at="&anything.whatever;">
Some global variables &var.some; or &var.globalvars; or
&var.arrays.1; or &var.arrays.2; or &var.objects.foo; or
&anything.really;
</p>
`,
{_: {
sitename: "foo.bar",
description: "faster than lightning templates"
},
var: {
some: "other",
globalvars: 7,
arrays: ["abc", 14, "def"],
objects: {"foo":"bar", "indeed":"yes"}
},
anything: {
really: "other",
whatever: 7
}
});
Simple assigment:
<set var="_.variablename">the new value</set>
Simple calculations:
<set var="_.variablename" expr="_.variablename + 1" />
Conditionals:
<if expr="_.variablename > 1">
yes
</if>
<elif expr="_.variablename == 'foobar'">
second condition valid
</elif>
<else>
otherwise
</else>
Counted loop:
<for from="1" to="42">
This is line &_._recno;<br />
</for>
Iterating through an object or array:
<set var="_.foo" split=",">aa,b,cc,d,eee,f</set>
<for in="_.foo">
This is record &_._recno; value: &_._value;<br />
</for>
Defining your own HTML to make it more readable, maintainable and DRY:
<comment> First define some macros </comment>
<set tag="literallink">
<a href="&_.href;">&_.href;</a>
</set>
<set tag="decorate">
You can click towards <literallink href="&_.link;"/>. <br/>
</set>
<comment> Now use them </comment>
<decorate link="https://some.where/foo/bar" />
<decorate link="https://some.where/bar/foo" />
Even recursive functions are possible:
<set tag="faculty">
<if expr="_.val <= 1"> 1 </if>
<else>
<set var="_.oneless" expr="_.val - 1" />
<insert expr=""> _.val * <faculty val="&_.oneless;" /> </insert>
</else>
</set>
<set tag="facultyverbose">
<h1>Faculty calculation of &_.valinput;</h1>
<p>
&_.valinput;! = <faculty val="&_.valinput;" />
</p>
</set>
<comment> Now call our custom HTML tag </comment>
<facultyverbose valinput="7" />
& scope . variablename : encoding % formatting ;
scope
context
object.variablename
context
object (can contain multiple dots to designate deeper levels, is used
to access both objects and arrays).
Variables from the parent scope can always be referenced:
e.g. &_.foo;
is a variable named foo in the current scope, whereas
&_._.foo;
refers to a variable named foo in the parent scope.
By prepending _.
to the path every time, you go one level deeper.encoding
(optional)add_filter()
):
html
uric
json
none
recurse
or r
none
but immediately searches for new entities to substitute
inside the replaced content.formatting
(optional)remixml-fmt
module must have been
loaded.%t
: any string following it will be parsed
as a strftime()-like formatting
specification
.Note: all entity references evaluate safely. If the entity contains undefined parts, the resulting substitution string will always be empty.
Note: the entity reference must not contain spaces (the spaces shown
above are there to clarify the format, they should not be used in a real
entity reference). The scope and variablename parts can be described
using the following regular expression: [_$a-zA-Z0-9]+
.
All tags strip fully enclosed whitespace patches between tags on the first level
if a single -
parameter is given.
<div ->
<p>
This will strip all fully enclose whitespace
(between the div and p tags).
</p>
</div>
<set var="" variable="" expr="" regexp="" split="" join="" mkmapping="" selector="" json="" clone="" tag="" args="" scope="">...</set>
Attributes:
var
or variable
expr
regexp
split
join
mkmapping
selector
clone
json
tag
&_._contents;
can be used to reference
the contents of the tag. All argument values are accessible
as variables from the local scope (_
). E.g. an attribute
foo="bar"
can be referenced as &_.foo;
inside the tag definition.args
&_._restargs;
.
Using something like <img ::="&_._restargs;" />
allows you to pass
on all the remaining arguments. The special argument ::
accepts
an object and spreads out the elements as individual attributes.
Note that all locally defined variables in the current _.
scope
not mentioned in the args
argument will be included in &_._restargs;
.scope
<unset var="" variable="" tag=""></unset>
Attributes:
var
or variable
tag
<if expr="">...</if>
Attributes:
expr
<then>...</then>
If the last truth value was true, include the content
of the then tag. Not needed for a typical if/else
construction; usually used after a for tag
to specify code that needs to be included if the for tag
actually completed at least one iteration.
<elif expr="">...</elif>
Attributes:
expr
<else>...</else>
If the last truth value was false, include the content of
the else tag. Can also be used after a for to specify
code that needs to be included if the for tag did not iterate
at all.
<for from="" to="" step="" in="" orderby="" scope="" mkmapping="">...</for>
Upon iteration the following special variables are defined:
&_._recno;
&_._index;
&_._value;
Attributes:
from
to
step
in
orderby
_
scope to designate elements from the current element.
There is shortcut reference _index
which refers to the index
of the current element.scope
mkmapping
mkmapping=""
and the object in _._value
already has members,
then these members are simply copied into the _
scope;
i.e. _._value.foo
becomes accessible as _.foo
as well.<delimiter>...</delimiter>
Should be used inside a for loop. It will suppress its content
upon the first iteration.
<insert var="" variable="" quote="" format="" offset="" limit="" join="" variables="" scope="" expr=""></insert>
More explicit way to access variable content instead of through
entities.
Attributes:
var
or variable
quote
none
(contrary to the
entities, which default to html
).format
offset
limit
join
variables
dump
scope
expr
<replace from="" regexp="" flags="" to="" expr="">...</replace>
Attributes:
from
regexp
flags
to
$
characters here have special meaning.expr
<washtags keep="" strip="">...</washtags>
Attributes:
keep
strip
<trim>...</trim>
Truncates whitespace at both ends, and reduce other whitespace runs of
more than one character to a single space.
<maketag name="">...</maketag>
Attributes:
name
<attrib name="">...</attrib>
name
<eval recurse="">...</eval>
Reevaluate the content (e.g. useful to execute a tag
created with maketag).
Attributes:
recurse
0
.
Specifying no value sets the maximum depth to unlimited.
Evaluation stops automatically as soon as no changes are detected
anymore.<script>...</script>
Copy the contents of this tag verbatim without further parsing
(and leave the script
tag itself). To force parsing inside
script
tags use <maketag name="script">...</maketag>
instead.
<style>...</style>
Treated exactly like <script>
tags.
<noparse>...</noparse>
Copy the contents of this tag verbatim without further parsing
(but strip the noparse
tag itself). The content needs to be well-formed
XHTML (no dangling tags).
<?noparse ...?>
Copy the contents of this tag verbatim without further parsing
(but strip the noparse
tag itself).
<nooutput>...</nooutput>
Suppress output inside this tag. The content needs to be well-formed
XHTML (no dangling tags).
<comment>...</comment>
Strip and skip this tag with content. The content needs to be well-formed
XHTML (no dangling tags).
<?comment ...?>
Strip and skip this tag with content.
<cache var="" variable="" key="" shared="" ttl="">...</cache>
Caches the content.
Attributes:
var
or variable
key
var
instead.shared
<cache>
reference distinct caches that
use an integer number to indicate different cache contexts.
By defining this you can explicitly define the cache context to
store and retrieve from.ttl
maxttl
.<nocache>...</nocache>
Mark sections inside a <cache>
section to be uncached instead.
These are extra helperfunctions which are available in the context of inline Remixml Javascript scripts.
sizeof(x)
Returns the number of elements in an array or object, or the size of the
string. It is implemented as a definition in the global scope.
desc(x)
This function is only available inside the orderby
parameter of the
for
loop. It causes the argument to be sorted in reverse.
abstract2txt(abstract, html?)
A shortcut reference to Remixml.abstract2txt()
.
abstract2dom(abstract, node?)
A shortcut reference to Remixml.abstract2dom()
.
Specified parameters:
template
context
$
. The local scope will always exist
as $._
and that can always be referenced using a direct _
shortcut. I.e. in Javascript $._.foo
and _.foo
will both refer
to the same variable, in Remixml both are referred to as &_.foo;
.flags
is an optional bitmask with:
-
parameter to strip
whitespace per tag).Promise
instead of a direct abstract).Exposed API-list (in NodeJS and the browser):
Remixml.remixml2js(remixmlsrc, flags?)
Remixml.js2obj(jssrc)
context
parameter
returns a DOM-abstract structure (AKA virtual DOM), or a Promise
to return
a DOM-abstract structure when flags
has the async-processing bit set.Remixml.abstract2txt(abstract, html?)
html
to 1
.Remixml.compile(remixmlsrc, flags?)
Remixml.js2obj(Remixml.remixml2js(remixmlsrc, flags))
Remixml.parse2txt(template, context, flags?)
template
can either be direct remixml source, or a precompiled object
from Remixml.compile
. Returns an XHTML/Remixml-string.Remixml.add_filter(name, filterfunction)
Remixml.set_tag(callback, context, name, scope?, args?)
context
just like
<set tag="name"></set>
would have done.
callback
is a javascript function
which will be called as callback(context)
and must return
the replacing DOM-abstract. E.g. when the tag
is referenced as <name foo="bar"></name>
then inside the
callback function context._.foo
will have the value bar
.
Please take note that the provided callback can only return a Promise
when
flags
has the async-processing bit set.Remixml.set_log_callback(callback)
console.error()
. This callback function is used
to log remixml runtime errors.Remixml.set_cache_options(maxttl, maxentries?, intervaltime?, intervalentries?)
intervalentries
allocations it performs
a garbage collection (defaults to 32).Remixml.abstract2dom(abstract, node?)
abstract
into DOM nodes. If the optional node
argument
is specified, it replaces the children of node
with the content
described in DOM abstract
. Returns node
if specified, or the new
nodes. This API-function is only available from this module if
one of the optional remixml-*dom
modules has been loaded.$.sys.lang
Card-carrying member of the zerodeps
movement.
FAQs
XML/HTML-like macro language/template compiler engine
We found that remixml demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Security News
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
Security News
In this segment of the Risky Business podcast, Feross Aboukhadijeh and Patrick Gray discuss the challenges of tracking malware discovered in open source softare.