1
0
mirror of https://github.com/php/phd.git synced 2026-03-23 22:52:05 +01:00

Allow for (nested) annotations elements

This allows us to set 'interactive' annotations on books, sets, and chapters to
signal to the WASM code runner that examples in these areas can be run.

The WASM code runner also checks for the 'non-interactive' annotation and
selectively disables running code for that example.
This commit is contained in:
Derick Rethans
2025-03-06 14:56:06 +00:00
parent b1e5ac3975
commit b7d8f52b05
3 changed files with 65 additions and 2 deletions

View File

@@ -6,6 +6,9 @@ abstract class Format_Abstract_XHTML extends Format {
/** @var array<?string> Last In First Out stack of roles */
private array $role = [];
/** @var array<?string> Last In First Out stack of annotations */
private array $annotations = [];
/* XHTMLPhDFormat */
protected $openPara = 0;
protected $escapedPara = array();
@@ -44,13 +47,19 @@ abstract class Format_Abstract_XHTML extends Format {
}
public function CDATA($value) {
$annotations = $this->getAnnotations();
$annotationsStr = '';
if (count($annotations) > 0) {
$annotationsStr = 'annotation-' . join(' annotation-', $annotations) . ' ';
}
switch($this->getRole()) {
case '':
return '<div class="cdata"><pre>'
return '<div class="' . $annotationsStr . 'cdata"><pre>'
. htmlspecialchars($value, ENT_QUOTES, "UTF-8")
. '</pre></div>';
default:
return '<div class="' . $this->getRole() . 'code">'
return '<div class="' . $annotationsStr . $this->getRole() . 'code' . '">'
. $this->highlight(trim($value), $this->getRole(), 'xhtml')
. '</div>';
}
@@ -139,4 +148,20 @@ abstract class Format_Abstract_XHTML extends Format {
protected function popRole(): ?string {
return array_pop($this->role);
}
protected function pushAnnotations(?string $annotations): void {
$this->annotations[] = ($annotations != null ? explode(' ', $annotations) : []);
}
protected function getAnnotations() : ?array {
$top = end($this->annotations);
if ($top === false) {
$top = [];
}
return $top;
}
protected function popAnnotations() : ?array {
return array_pop($this->annotations);
}
}

View File

@@ -820,6 +820,8 @@ abstract class Package_Generic_XHTML extends Format_Abstract_XHTML {
}
public function format_container_chunk_top($open, $name, $attrs, $props) {
$hasAnnotations = array_key_exists('annotations', $attrs[Reader::XMLNS_DOCBOOK]);
$this->cchunk = $this->dchunk;
$this->cchunk["name"] = $name;
if(isset($attrs[Reader::XMLNS_XML]["id"])) {
@@ -829,12 +831,20 @@ abstract class Package_Generic_XHTML extends Format_Abstract_XHTML {
}
if ($open) {
if ($hasAnnotations) {
$this->pushAnnotations($attrs[Reader::XMLNS_DOCBOOK]["annotations"]);
}
$this->CURRENT_CHUNK = $id;
$this->notify(Render::CHUNK, Render::OPEN);
return '<div id="' .$id. '" class="' .$name. '">';
}
if ($hasAnnotations) {
$this->popAnnotations();
}
$this->CURRENT_CHUNK = $id;
$this->notify(Render::CHUNK, Render::CLOSE);
$toc = "";
@@ -1714,10 +1724,17 @@ abstract class Package_Generic_XHTML extends Format_Abstract_XHTML {
return "</p></div>";
}
public function format_programlisting($open, $name, $attrs) {
$hasAnnotations = array_key_exists('annotations', $attrs[Reader::XMLNS_DOCBOOK]);
if ($open) {
$this->pushRole($attrs[Reader::XMLNS_DOCBOOK]["role"] ?? null);
if ($hasAnnotations) {
$this->pushAnnotations($attrs[Reader::XMLNS_DOCBOOK]["annotations"]);
}
return '<div class="example-contents">';
}
if ($hasAnnotations) {
$this->popAnnotations();
}
$this->popRole();
return "</div>\n";
}

View File

@@ -914,6 +914,8 @@ abstract class Package_PHP_XHTML extends Package_Generic_XHTML {
}
public function format_container_chunk($open, $name, $attrs, $props) {
$hasAnnotations = array_key_exists('annotations', $attrs[Reader::XMLNS_DOCBOOK]);
$this->CURRENT_CHUNK = $this->CURRENT_ID = $id = $attrs[Reader::XMLNS_XML]["id"] ?? '';
if ($this->isChunkedByAttributes($attrs)) {
@@ -921,6 +923,10 @@ abstract class Package_PHP_XHTML extends Package_Generic_XHTML {
}
if ($open) {
if ($hasAnnotations) {
$this->pushAnnotations($attrs[Reader::XMLNS_DOCBOOK]["annotations"]);
}
$this->notify(Render::CHUNK, Render::OPEN);
if ($name != "reference") {
$chunks = Format::getChildren($id);
@@ -937,6 +943,10 @@ abstract class Package_PHP_XHTML extends Package_Generic_XHTML {
}
return '<div id="'.$id.'" class="'.$name.'">';
}
if ($hasAnnotations) {
$this->popAnnotations();
}
$this->notify(Render::CHUNK, Render::CLOSE);
$content = "";
@@ -957,11 +967,22 @@ abstract class Package_PHP_XHTML extends Package_Generic_XHTML {
}
public function format_root_chunk($open, $name, $attrs) {
$hasAnnotations = array_key_exists('annotations', $attrs[Reader::XMLNS_DOCBOOK]);
$this->CURRENT_CHUNK = $this->CURRENT_ID = $id = $attrs[Reader::XMLNS_XML]["id"] ?? '';
if ($open) {
if ($hasAnnotations) {
$this->pushAnnotations($attrs[Reader::XMLNS_DOCBOOK]["annotations"]);
}
$this->notify(Render::CHUNK, Render::OPEN);
return '<div id="'.$id.'" class="'.$name.'">';
}
if ($hasAnnotations) {
$this->popAnnotations();
}
$this->notify(Render::CHUNK, Render::CLOSE);
$chunks = Format::getChildren($id);
$content = '<ul class="chunklist chunklist_'.$name.'">';