diff --git a/phpdotnet/phd/Package/Generic/XHTML.php b/phpdotnet/phd/Package/Generic/XHTML.php index 40a26e75..20581b43 100644 --- a/phpdotnet/phd/Package/Generic/XHTML.php +++ b/phpdotnet/phd/Package/Generic/XHTML.php @@ -143,7 +143,7 @@ abstract class Package_Generic_XHTML extends Format_Abstract_XHTML { 'methodparam' => 'format_methodparam', 'methodsynopsis' => 'format_methodsynopsis', 'methodname' => 'format_methodname', - 'member' => 'li', + 'member' => 'format_member', 'modifier' => 'span', 'note' => 'format_note', 'orgname' => 'span', @@ -269,7 +269,7 @@ abstract class Package_Generic_XHTML extends Format_Abstract_XHTML { 'setindex' => 'format_chunk', 'shortaffil' => 'format_suppressed_tags', 'sidebar' => 'format_note', - 'simplelist' => 'format_itemizedlist', /* FIXME: simplelists has few attributes that need to be implemented */ + 'simplelist' => 'format_simplelist', 'simplesect' => 'div', 'simpara' => array( /* DEFAULT */ 'p', @@ -446,6 +446,7 @@ abstract class Package_Generic_XHTML extends Format_Abstract_XHTML { 'literal' => 'format_literal_text', 'email' => 'format_email_text', 'titleabbrev' => 'format_suppressed_text', + 'member' => 'format_member_text', ); /** @var array */ @@ -501,6 +502,11 @@ abstract class Package_Generic_XHTML extends Format_Abstract_XHTML { "varlistentry" => array( "listitems" => array(), ), + "simplelist" => array( + "members" => array(), + "type" => null, + "columns" => null, + ), ); protected $pihandlers = array( @@ -2040,6 +2046,126 @@ public function format_itemizedlist($open, $name, $attrs, $props) { return ''; } + public function format_simplelist($open, $name, $attrs, $props) { + if ($open) { + $this->cchunk["simplelist"]["type"] = $attrs[Reader::XMLNS_DOCBOOK]["type"] ?? ""; + $this->cchunk["simplelist"]["columns"] = $attrs[Reader::XMLNS_DOCBOOK]["columns"] ?? 1; + + if ($this->cchunk["simplelist"]["columns"] < 1) { + $this->cchunk["simplelist"]["columns"] = 1; + } + + if ($this->cchunk["simplelist"]["type"] === "inline") { + return ''; + } + + if ($this->cchunk["simplelist"]["type"] === "vert" + || $this->cchunk["simplelist"]["type"] === "horiz") { + return '' . "\n" . $this->indent($props["depth"] + 1) . "\n"; + } + + return '\n" + . $this->indent($props["depth"]) . "
", + "vert" => $this->simplelist_format_vertical($props["depth"]) + . $this->indent($props["depth"] + 1) . "\n" + . $this->indent($props["depth"]) . "", + default => "", + }; + + $this->cchunk["simplelist"] = $this->dchunk["simplelist"]; + + return $list; + } + + private function indent($depth): string { + return $depth > 0 ? str_repeat(' ', $depth) : ''; + } + + private function simplelist_format_inline() { + return implode(", ", $this->cchunk["simplelist"]["members"]) . '
'; + } + + private function simplelist_format_horizontal($depth) { + return $this->chunkReduceTable( + $this->processTabular( + $this->cchunk["simplelist"]["members"], + $this->cchunk["simplelist"]["columns"], + $depth), + $this->cchunk["simplelist"]["columns"], + $depth + ); + } + + /** Return formatted rows */ + private function chunkReduceTable(array $members, int $cols, int $depth): string + { + $trPadding = $this->indent($depth + 2); + return array_reduce( + array_chunk( + $members, + $cols, + ), + fn (string $carry, array $entry) => $carry . $trPadding . "\n" . implode('', $entry) . $trPadding . "\n", + '' + ); + } + + /** Pads $members so that number of members = columns x rows */ + private function processTabular(array $members, int $cols, int $depth): array + { + $tdPadding = $this->indent($depth + 3); + return array_map( + fn (string $member) => $tdPadding . "$member\n", + /** The padding is done by getting the additive modular inverse which is + * ``-\count($members) % $cols`` but because PHP gives us the mod in negative we need to + * add $cols back to get the positive + */ + [...$members, ...array_fill(0, (-\count($members) % $cols) + $cols, '')] + ); + } + + private function simplelist_format_vertical($depth) { + $members = $this->processTabular( + $this->cchunk["simplelist"]["members"], + $this->cchunk["simplelist"]["columns"], + $depth + ); + // Sort elements so that we get each correct element for the rows to display vertically + uksort( + $members, + fn (int $l, int $r) => $l % $this->cchunk["simplelist"]["columns"] <=> $r % $this->cchunk["simplelist"]["columns"] + ); + return $this->chunkReduceTable($members, $this->cchunk["simplelist"]["columns"], $depth); + } + + public function format_member($open, $name, $attrs, $props) { + if ($this->cchunk["simplelist"]["type"] === "inline" + || $this->cchunk["simplelist"]["type"] === "vert" + || $this->cchunk["simplelist"]["type"] === "horiz") { + return ''; + } + if ($open) { + return '
  • '; + } + return '
  • '; + } + + public function format_member_text($value, $tag) { + if ($this->cchunk["simplelist"]["type"] === "inline" + || $this->cchunk["simplelist"]["type"] === "vert" + || $this->cchunk["simplelist"]["type"] === "horiz") { + $this->cchunk["simplelist"]["members"][] = $value; + return ''; + } + return $value; + } + public function format_orderedlist($open, $name, $attrs, $props) { if ($open) { $numeration = "1"; @@ -2115,6 +2241,15 @@ public function format_whitespace($whitespace, $elementStack, $currentDepth) { return false; } + if ( + $elementStack[$currentDepth - 1] === "simplelist" + && ($this->cchunk["simplelist"]["type"] === "inline" + || $this->cchunk["simplelist"]["type"] === "vert" + || $this->cchunk["simplelist"]["type"] === "horiz") + ) { + return false; + } + /* The following if is to skip unnecessary whitespaces in the implements list */ if ( ($elementStack[$currentDepth - 1] === 'classsynopsisinfo' && $elementStack[$currentDepth] === 'oointerface') || @@ -2127,5 +2262,3 @@ public function format_whitespace($whitespace, $elementStack, $currentDepth) { } } - - diff --git a/phpdotnet/phd/Render.php b/phpdotnet/phd/Render.php index 144c56fd..e3a17cc3 100644 --- a/phpdotnet/phd/Render.php +++ b/phpdotnet/phd/Render.php @@ -216,6 +216,3 @@ public function execute(Reader $r) { /* {{{ */ } /* }}} */ } - - - diff --git a/tests/php/type_rendering_001.phpt b/tests/php/type_rendering_001.phpt index 3e0d2545..e9edc78d 100644 --- a/tests/php/type_rendering_001.phpt +++ b/tests/php/type_rendering_001.phpt @@ -38,8 +38,7 @@ Content:

    1. Function/method with no return type

    -
    - function_name()
    +
    function_name()
    diff --git a/tests/php/type_rendering_002.phpt b/tests/php/type_rendering_002.phpt index e44a1c80..6309b11f 100644 --- a/tests/php/type_rendering_002.phpt +++ b/tests/php/type_rendering_002.phpt @@ -38,8 +38,7 @@ Content:

    1. Function/method with no parameters

    -
    - function_name()
    +
    function_name()
    diff --git a/tests/php/type_rendering_003.phpt b/tests/php/type_rendering_003.phpt index 03a30c7d..f37b33ed 100644 --- a/tests/php/type_rendering_003.phpt +++ b/tests/php/type_rendering_003.phpt @@ -38,8 +38,7 @@ Content:

    1. Constructor with no parameters, no return type

    -
    - final public ClassName::__construct()
    +
    final public ClassName::__construct()
    diff --git a/tests/xhtml/data/simplelist.xml b/tests/xhtml/data/simplelist.xml new file mode 100644 index 00000000..ce3e5d5b --- /dev/null +++ b/tests/xhtml/data/simplelist.xml @@ -0,0 +1,56 @@ + + + +
    + 1. Simplelist with no type + + First + Second + Third + Fourth + Fifth + Sixth + Seventh + +
    + +
    + 2. Simplelist with "inline" type + + First + Second + Third + Fourth + Fifth + Sixth + Seventh + +
    + +
    + 3. Simplelist with "vert" type, 3 columns + + First + Second + Third + Fourth + Fifth + Sixth + Seventh + +
    + +
    + 4. Simplelist with "horiz" type, 4 columns + + First + Second + Third + Fourth + Fifth + Sixth + Seventh + +
    + +
    diff --git a/tests/xhtml/simplelist_001.phpt b/tests/xhtml/simplelist_001.phpt new file mode 100644 index 00000000..ad461a05 --- /dev/null +++ b/tests/xhtml/simplelist_001.phpt @@ -0,0 +1,100 @@ +--TEST-- +Simplelist rendering 001 - Types and columns +--FILE-- + true, + "xml_root" => dirname($xml_file), + "xml_file" => $xml_file, + "output_dir" => __DIR__ . "/output/", +); + +$extra = array( + "lang_dir" => __PHDDIR__ . "phpdotnet/phd/data/langs/", + "phpweb_version_filename" => dirname($xml_file) . '/version.xml', + "phpweb_acronym_filename" => dirname($xml_file) . '/acronyms.xml', +); + +$render = new TestRender($formatclass, $opts, $extra); + +if (Index::requireIndexing() && !file_exists($opts["output_dir"])) { + mkdir($opts["output_dir"], 0755); +} + +$render->run(); +?> +--EXPECTF-- +Filename: simpelist.html +Content: +
    + +
    +

    1. Simplelist with no type

    + +
    + +
    +

    2. Simplelist with "inline" type

    + First, Second, Third, Fourth, Fifth, Sixth, Seventh +
    + +
    +

    3. Simplelist with "vert" type, 3 columns

    + + + + + + + + + + + + + + + + + + +
    FirstFourthSeventh
    SecondFifth
    ThirdSixth
    +
    + +
    +

    4. Simplelist with "horiz" type, 4 columns

    + + + + + + + + + + + + + + + +
    FirstSecondThirdFourth
    FifthSixthSeventh
    +
    + +
    diff --git a/tests/xhtml/whitespace_formatting_001.phpt b/tests/xhtml/whitespace_formatting_001.phpt index 81339724..5c1aa1d6 100644 --- a/tests/xhtml/whitespace_formatting_001.phpt +++ b/tests/xhtml/whitespace_formatting_001.phpt @@ -44,13 +44,13 @@ Content:

    2. Constructor with whitespace between name, parameters and return types

    -
    final public ClassName::__construct(iterableresourcecallablenull $optionvoid)
    +
    final public ClassName::__construct(iterableresourcecallablenull $optionvoid)

    3. Destructor with whitespace between name, parameters and return types

    -
    final public ClassName::__construct(iterableresourcecallablenull $optionvoid)
    +
    final public ClassName::__construct(iterableresourcecallablenull $optionvoid)