Skip to content

Commit a919e54

Browse files
committed
new: TableTracer::inferTableHeadFrom() method.
1 parent 4e8d4bc commit a919e54

File tree

4 files changed

+67
-71
lines changed

4 files changed

+67
-71
lines changed

Src/Interfaces/TableTracer.php

+9
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,15 @@ public function addEventListener( Table $for, callable $callback, EventAt $event
4848
*/
4949
public function inferTableFrom( string $source, bool $normalize ): void;
5050

51+
/**
52+
* Infers table head content from given element list.
53+
*
54+
* @param iterable<array-key,TElement> $elementList
55+
* @throws InvalidSource When TElement is not a valid type.
56+
* @template TElement
57+
*/
58+
public function inferTableHeadFrom( iterable $elementList ): void;
59+
5160
/**
5261
* Infers table column data from given element list.
5362
*

Src/Traits/Table/HtmlTableFromNode.php

+25-36
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,29 @@ public function inferTableFrom( string $source, bool $normalize = true ): void {
2828
);
2929
}
3030

31+
/** @param DOMNodeList<DOMNode> $elementList */
32+
public function inferTableHeadFrom( iterable $elementList ): void {
33+
[$names, $skippedNodes, $transformer] = $this->useCurrentTableHeadDetails();
34+
35+
foreach ( $elementList as $currentIndex => $node ) {
36+
if ( ! AssertDOMElement::isValid( $node, Table::Head ) ) {
37+
$this->tickCurrentHeadIterationSkippedHeadNode( $node );
38+
39+
++$skippedNodes;
40+
41+
continue;
42+
}
43+
44+
$position = $currentIndex - $skippedNodes;
45+
46+
$this->registerCurrentIterationTableHead( $position );
47+
48+
$names[] = $transformer?->transform( $node, $this ) ?? trim( $node->textContent );
49+
}
50+
51+
$this->registerCurrentTableHead( $names );
52+
}
53+
3154
/** @param iterable<array-key,string|DOMNode> $elementList */
3255
public function inferTableDataFrom( iterable $elementList ): array {
3356
$data = [];
@@ -97,36 +120,6 @@ protected function inferTableFromDOMNodeList( DOMNodeList $elementList ): void {
97120
}//end foreach
98121
}
99122

100-
/**
101-
* @return ?list<string>
102-
* @throws InvalidSource When element list is not DOMNodeList.
103-
*/
104-
protected function inferTableHeadFrom( DOMNode $element ): ?array {
105-
if ( ! AssertDOMElement::isValid( $element, Table::Row ) || ! $element->childNodes->length ) {
106-
return null;
107-
}
108-
109-
[$names, $skippedNodes, $transformer] = $this->useCurrentTableHeadDetails();
110-
111-
foreach ( $element->childNodes as $currentIndex => $node ) {
112-
if ( ! AssertDOMElement::isValid( $node, Table::Head ) ) {
113-
$this->tickCurrentHeadIterationSkippedHeadNode( $node );
114-
115-
++$skippedNodes;
116-
117-
continue;
118-
}
119-
120-
$position = $currentIndex - $skippedNodes;
121-
122-
$this->registerCurrentIterationTableHead( $position );
123-
124-
$names[] = $transformer?->transform( $node, $this ) ?? trim( $node->textContent );
125-
}
126-
127-
return $names ?: null;
128-
}
129-
130123
final protected function findTableStructureIn( DOMNode $node, int $minChildNodesCount = 0 ): void {
131124
( ! $this->getTableId() || $this->shouldPerform__allTableDiscovery )
132125
&& ( ( $nodes = $node->childNodes )->length > $minChildNodesCount )
@@ -211,9 +204,7 @@ private function headStructureContentFrom( DOMElement $node ): void {
211204
$iterator->next();
212205
}
213206

214-
if ( $row && ( $headContent = $this->inferTableHeadFrom( $row ) ) ) {
215-
$this->registerCurrentTableHead( $headContent );
216-
}
207+
$row && $row->childNodes->length && $this->inferTableHeadFrom( $row->childNodes );
217208

218209
$this->dispatchEvent( new TableTraced( Table::THead, EventAt::End, $node, $this ) );
219210
}
@@ -302,9 +293,7 @@ private function bodyStructureIteratorFrom( DOMElement $body ): Iterator {
302293
}
303294

304295
private function inspectFirstRowForHeadStructure( DOMNode $row ): bool {
305-
( $firstRowContent = $this->inferTableHeadFrom( $row ) )
306-
&& $this->currentIteration__allTableHeads
307-
&& $this->registerCurrentTableHead( $firstRowContent );
296+
$this->inferTableHeadFrom( $row->childNodes );
308297

309298
return $this->currentIteration__allTableHeads;
310299
}

Src/Traits/Table/HtmlTableFromString.php

+27-33
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,31 @@ public function inferTableFrom( string $source, bool $normalize = true ): void {
5252
$this->dispatchEvent( new TableTraced( Table::TBody, EventAt::End, $table, $this ) );
5353
}
5454

55+
/** @param iterable<array-key,array{0:string,1:string,2:string,3:string,4:string}> $elementList */
56+
public function inferTableHeadFrom( iterable $elementList ): void {
57+
[$names, $skippedNodes, $transformer] = $this->useCurrentTableHeadDetails();
58+
59+
foreach ( $elementList as $currentIndex => $head ) {
60+
[$node, $nodeName, $attribute, $content] = $head;
61+
62+
if ( Table::Head->value !== $nodeName ) {
63+
$this->tickCurrentHeadIterationSkippedHeadNode();
64+
65+
++$skippedNodes;
66+
67+
continue;
68+
}
69+
70+
$position = $currentIndex - $skippedNodes;
71+
72+
$this->registerCurrentIterationTableHead( $position );
73+
74+
$names[] = $transformer?->transform( $head, $this ) ?? trim( $content );
75+
}
76+
77+
$this->registerCurrentTableHead( $names );
78+
}
79+
5580
/** @param iterable<array-key,DOMNode|array{0:string,1:string,2:string,3:string,4:string}> $elementList */
5681
public function inferTableDataFrom( iterable $elementList ): array {
5782
$data = [];
@@ -87,34 +112,6 @@ public function inferTableDataFrom( iterable $elementList ): array {
87112
return $data;
88113
}
89114

90-
/**
91-
* @param iterable<array-key,array{0:string,1:string,2:string,3:string,4:string}> $elementList
92-
* @return ?list<string>
93-
*/
94-
protected function inferTableHeadFrom( iterable $elementList ): ?array {
95-
[$names, $skippedNodes, $transformer] = $this->useCurrentTableHeadDetails();
96-
97-
foreach ( $elementList as $currentIndex => $head ) {
98-
[$node, $nodeName, $attribute, $content] = $head;
99-
100-
if ( Table::Head->value !== $nodeName ) {
101-
$this->tickCurrentHeadIterationSkippedHeadNode();
102-
103-
++$skippedNodes;
104-
105-
continue;
106-
}
107-
108-
$position = $currentIndex - $skippedNodes;
109-
110-
$this->registerCurrentIterationTableHead( $position );
111-
112-
$names[] = $transformer?->transform( $head, $this ) ?? trim( $content );
113-
}
114-
115-
return $names ?: null;
116-
}
117-
118115
protected function captionStructureContentFrom( string $table ): void {
119116
[$matched, $caption] = Normalize::nodeToMatchedArray( $table, Table::Caption );
120117

@@ -151,9 +148,8 @@ protected function headStructureContentFrom( string $string ): void {
151148

152149
if ( $rowsFound ) {
153150
[$headsFound, $rowColumns] = Normalize::tableColumnsFrom( $headRow[2] );
154-
$content = ! $headsFound ? null : $this->inferTableHeadFrom( $rowColumns );
155151

156-
$content && $this->registerCurrentTableHead( $content );
152+
$headsFound && $this->inferTableHeadFrom( $rowColumns );
157153
}
158154

159155
$this->dispatchEvent( new TableTraced( Table::THead, EventAt::End, $thead[0], $this ) );
@@ -284,9 +280,7 @@ private function bodyStructureIteratorFrom( array $body ): Iterator {
284280

285281
/** @param array{0:string,1:string,2:string,3:string,4:string}[] $row */
286282
private function inspectFirstRowForHeadStructure( array $row ): bool {
287-
( $firstRowContent = $this->inferTableHeadFrom( $row ) )
288-
&& $this->currentIteration__allTableHeads
289-
&& $this->registerCurrentTableHead( $firstRowContent );
283+
$this->inferTableHeadFrom( $row );
290284

291285
return $this->currentIteration__allTableHeads;
292286
}

Src/Traits/Table/TableExtractor.php

+6-2
Original file line numberDiff line numberDiff line change
@@ -306,10 +306,14 @@ private function tickCurrentHeadIterationSkippedHeadNode( mixed $node = null ):
306306

307307
/** @param list<string> $names */
308308
private function registerCurrentTableHead( array $names ): void {
309+
$this->registerCurrentIterationTableHead( false );
310+
311+
if ( ! $this->currentIteration__allTableHeads || ! $names ) {
312+
return;
313+
}
314+
309315
$tableId = $this->getTableId( current: true );
310316
$this->discoveredTable__headNames[ $tableId ] = SplFixedArray::fromArray( $names );
311-
312-
$this->registerCurrentIterationTableHead( false );
313317
}
314318

315319
private function registerCurrentIterationTableHead( int|false $position ): void {

0 commit comments

Comments
 (0)