public function writeAttrsMacro($html)
{
// none-2 none-1 tag-1 tag-2 <el attr-1 attr-2> /tag-2 /tag-1 [none-2] [none-1] inner-2 inner-1
// /inner-1 /inner-2 [none-1] [none-2] tag-1 tag-2 </el> /tag-2 /tag-1 /none-1 /none-2
$attrs = $this->htmlNode->macroAttrs;
$left = $right = [];
foreach ($this->macros as $name => $foo) {
$attrName = MacroNode::PREFIX_INNER . "-{$name}";
if (isset($attrs[$attrName])) {
if ($this->htmlNode->closing) {
$left[] = function () use($name) {
$this->closeMacro($name, '', NULL, NULL, MacroNode::PREFIX_INNER);
};
} else {
array_unshift($right, function () use($name, $attrs, $attrName) {
if ($this->openMacro($name, $attrs[$attrName], NULL, NULL, MacroNode::PREFIX_INNER)->empty) {
throw new CompileException("Unable to use empty macro as n:{$attrName}.");
}
});
}
unset($attrs[$attrName]);
}
}
$innerMarker = '';
if ($this->htmlNode->closing) {
$left[] = function () {
$this->output .= $this->htmlNode->innerMarker;
};
} else {
array_unshift($right, function () use(&$innerMarker) {
$this->output .= $innerMarker;
});
}
foreach (array_reverse($this->macros) as $name => $foo) {
$attrName = MacroNode::PREFIX_TAG . "-{$name}";
if (isset($attrs[$attrName])) {
$left[] = function () use($name, $attrs, $attrName) {
if ($this->openMacro($name, $attrs[$attrName], NULL, NULL, MacroNode::PREFIX_TAG)->empty) {
throw new CompileException("Unable to use empty macro as n:{$attrName}.");
}
};
array_unshift($right, function () use($name) {
$this->closeMacro($name, '', NULL, NULL, MacroNode::PREFIX_TAG);
});
unset($attrs[$attrName]);
}
}
foreach ($this->macros as $name => $foo) {
if (isset($attrs[$name])) {
if ($this->htmlNode->closing) {
$right[] = function () use($name) {
$this->closeMacro($name, '', NULL, NULL, MacroNode::PREFIX_NONE);
};
} else {
array_unshift($left, function () use($name, $attrs, &$innerMarker) {
$node = $this->openMacro($name, $attrs[$name], NULL, NULL, MacroNode::PREFIX_NONE);
if ($node->empty) {
unset($this->htmlNode->macroAttrs[$name]);
// don't call closeMacro
} elseif (!$innerMarker) {
$this->htmlNode->innerMarker = $innerMarker = '<n:q' . count($this->placeholders) . 'q>';
$this->placeholders[$innerMarker] = '';
}
});
}
unset($attrs[$name]);
}
}
if ($attrs) {
throw new CompileException('Unknown attribute ' . Parser::N_PREFIX . implode(' and ' . Parser::N_PREFIX, array_keys($attrs)));
}
if (!$this->htmlNode->closing) {
$this->htmlNode->attrCode =& $this->placeholders[$uniq = ' n:q' . count($this->placeholders) . 'q'];
$html = substr_replace($html, $uniq, strrpos($html, '/>') ?: strrpos($html, '>'), 0);
}
foreach ($left as $func) {
$func();
}
$this->output .= $html;
foreach ($right as $func) {
$func();
}
if ($right && substr($this->output, -2) === '?>') {
$this->output .= "\n";
}
}