Skip to content

Commit 632ec00

Browse files
committed
complete rewrite of our text parser. walk through line by line instead of globbing patterns.
1 parent 180c066 commit 632ec00

File tree

6 files changed

+332
-139
lines changed

6 files changed

+332
-139
lines changed

dist/default.php

+6-4
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ class="table-wrapper md:shadow dark:shadow-none md:rounded-md overflow-hidden bg
112112
class="inline-flex items-center gap-2 group hover:text-black dark:hover:text-slate-200 inline-block active:ring-1 active:ring-slate-500 scroll-mt-14 md:scroll-mt-8"
113113
:class="hash == config.key && 'dark:text-slate-200'"
114114
>
115-
<span x-html="highlighted(config.name)"></span>
115+
<span x-html="formatted(config.name)"></span>
116116

117117
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="hidden group-hover:inline w-3 h-3 opacity-50">
118118
<path stroke-linecap="round" stroke-linejoin="round" d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244" />
@@ -122,12 +122,12 @@ class="inline-flex items-center gap-2 group hover:text-black dark:hover:text-sla
122122
<td class="py-2 lg:py-4 px-6 lg:px-4" style="overflow-wrap: anywhere"
123123
:class="config.localValue == null && 'text-slate-400 italic'">
124124
<span x-show="group.headings.length > 0" class="empty:hidden inline-block w-14 text-center lg:hidden py-1 mr-1 text-xs font-semibold rounded bg-green-100 dark:bg-green-900 text-green-700 dark:text-green-200" x-text="group.shortHeadings[1]"></span>
125-
<span x-html="highlighted(config.localValue)"></span>
125+
<span x-html="formatted(config.localValue)"></span>
126126
</td>
127127
<td x-show="config.hasMasterValue" class="py-2 lg:py-4 px-6 lg:px-4" style="overflow-wrap: anywhere"
128128
:class="config.masterValue == null && 'text-slate-400 italic'">
129129
<span x-show="group.headings.length > 0" class="empty:hidden inline-block w-14 text-center lg:hidden py-1 mr-1 text-xs font-semibold rounded bg-blue-100 dark:bg-blue-900 text-blue-700 dark:text-blue-200" x-text="group.shortHeadings[2]"></span>
130-
<span x-html="highlighted(config.masterValue)"></span>
130+
<span x-html="formatted(config.masterValue)"></span>
131131
</td>
132132
</tr>
133133
</template>
@@ -299,7 +299,9 @@ class="px-4 py-1 rounded block"
299299
document.body.style = "";
300300
this.mobileNav = false;
301301
},
302-
highlighted(text) {
302+
formatted(text) {
303+
if(text) text = text.replaceAll("\n", "<br>");
304+
303305
return this.isUnfiltered() || text == null
304306
? text
305307
: text.replace(new RegExp(this.search,"gi"), "<mark>$&</mark>");

src/Collections/Items.php

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
namespace STS\Phpinfo\Collections;
4+
5+
use Illuminate\Support\Collection;
6+
7+
class Items extends Collection
8+
{
9+
public function localValue()
10+
{
11+
return $this->get(1);
12+
}
13+
14+
public function appendLocalValue($text)
15+
{
16+
$this->put(1, $this->get(1) . $text);
17+
}
18+
}

src/Collections/Lines.php

+160
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
<?php
2+
3+
namespace STS\Phpinfo\Collections;
4+
5+
use Illuminate\Support\Collection;
6+
7+
/**
8+
* Used by our TextParser to help walk through the CLI text version
9+
*/
10+
class Lines extends Collection
11+
{
12+
protected int $index = 0;
13+
14+
/**
15+
* Moves one line forward, regardless of what it is
16+
*/
17+
public function step(): string|null
18+
{
19+
$this->index++;
20+
21+
return $this->current();
22+
}
23+
24+
/**
25+
* Advances to the next usable line and returns the new line
26+
*/
27+
public function advance(): string|null
28+
{
29+
do {
30+
$this->index++;
31+
} while($this->shouldIgnore());
32+
33+
return $this->current();
34+
}
35+
36+
/**
37+
* Similar to the above advance() method, except this returns
38+
* the CURRENT line before advancing
39+
*/
40+
public function consume(): string|null
41+
{
42+
$current = $this->current();
43+
44+
$this->advance();
45+
46+
return $current;
47+
}
48+
49+
public function consumeUntil(callable $callback): Collection
50+
{
51+
$lines = new static;
52+
53+
do {
54+
$current = $this->current();
55+
$lines->push($current);
56+
$this->step();
57+
} while(!$callback($current));
58+
59+
return $lines;
60+
}
61+
62+
public function shouldIgnore(): bool
63+
{
64+
return $this->currentIsBlank()
65+
// || str_contains($this->current(), '_______________________________________________________________________')
66+
|| in_array($this->current(), ['Configuration']);
67+
}
68+
69+
public function currentIsBlank(): bool
70+
{
71+
return $this->current() === '';
72+
}
73+
74+
public function previousIsBlank(): bool
75+
{
76+
return $this->previous() === '';
77+
}
78+
79+
public function nextIsBlank(): bool
80+
{
81+
return $this->next() === '';
82+
}
83+
84+
public function current(): string|null
85+
{
86+
return $this->get($this->index);
87+
}
88+
89+
public function previous(): string|null
90+
{
91+
return $this->get($this->index - 1);
92+
}
93+
94+
public function next(): string|null
95+
{
96+
return $this->get($this->index + 1);
97+
}
98+
99+
public function isDivider(): bool
100+
{
101+
return str_contains($this->current(), '_______________________________________________________________________');
102+
}
103+
104+
public function isModuleName(): bool
105+
{
106+
return !$this->hasItems()
107+
&& $this->nextIsBlank()
108+
&& strlen($this->current()) < 50;
109+
}
110+
111+
public function isGroupTitle(): bool
112+
{
113+
if(str_contains($this->current(), " ")) {
114+
return true;
115+
}
116+
117+
return !$this->hasItems()
118+
&& !$this->nextIsBlank()
119+
&& strlen($this->current()) < 50;
120+
}
121+
122+
public function isTableHeading(): bool
123+
{
124+
return in_array($this->items()->first(), ['Directive', 'Variable', 'Contribution', 'Module']);
125+
}
126+
127+
public function isNote(): bool
128+
{
129+
return !$this->hasItems()
130+
&& !$this->isDivider()
131+
&& !$this->isGroupTitle()
132+
&& strlen($this->current()) > 50;
133+
}
134+
135+
public function items(): Items
136+
{
137+
$items = Items::make(explode(" => ", $this->current()));
138+
139+
// A few weird cases we need to fix
140+
if($items->first() == "Features" && $items->count() == 1) {
141+
$items->put(1, null);
142+
}
143+
144+
return $items;
145+
}
146+
147+
public function hasItems(): bool
148+
{
149+
return $this->items()->count() > 1;
150+
}
151+
152+
public function consumeItems(): Items
153+
{
154+
$items = $this->items();
155+
156+
$this->advance();
157+
158+
return $items;
159+
}
160+
}

src/Models/Group.php

+5
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ public static function simple($name, $configName, $contents)
2727
);
2828
}
2929

30+
public static function noteOnly($note)
31+
{
32+
return (new static(collect()))->addNote($note);
33+
}
34+
3035
public function addNote($note): self
3136
{
3237
$this->note = $note;

src/Parsers/HtmlParser.php

+14-9
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@ public static function canParse(string $contents): bool
2424

2525
protected function parse(): void
2626
{
27-
//dd(new Module('Credits', $this->findGroupedConfigsFor($this->xpath()->query('//body//h1')[2])));
28-
2927
$this->version = str_replace('PHP Version ', '', $this->xpath()->query('//body//h1')[0]->nodeValue);
3028

3129
// For modules, we start by looking at all <h2> tags
@@ -47,17 +45,24 @@ protected function parse(): void
4745
]))
4846
);
4947

48+
// Credits
5049
$this->modules->push(
51-
new Module('Credits', $this->findGroupedConfigsFor($this->xpath()->query('//body//h1')[2]))
50+
new Module(
51+
$this->xpath()->query('//body//h1')[2]->nodeValue,
52+
$this->findGroupedConfigsFor($this->xpath()->query('//body//h1')[2]))
5253
);
5354

55+
// License
5456
$this->modules->push(
55-
new Module('License', collect([
56-
(new Group(collect()))->addNote(
57-
collect(collect($this->xpath()->query('//body//table//td'))->last()->childNodes)
58-
->map->nodeValue->implode("\n")
59-
)
60-
]))
57+
new Module(
58+
collect($this->xpath()->query('//body//h2'))->last()->nodeValue,
59+
collect([
60+
Group::noteOnly(
61+
collect(collect($this->xpath()->query('//body//table//td'))->last()->childNodes)
62+
->map->nodeValue->implode("\n\n")
63+
)
64+
])
65+
)
6166
);
6267
}
6368

0 commit comments

Comments
 (0)