19 declare(strict_types=1);
55 if (!is_string($from)) {
59 return $this->calculate($from);
62 private function calculate(
string $text):
int 64 $text = mb_encode_numericentity(
65 '<!DOCTYPE html><html><head><meta charset="utf-8"/></head><body>' . $text .
'</body></html>',
66 [0x80, 0x10FFFF, 0, ~0],
73 set_error_handler(
static function (
int $severity,
string $message,
string $file,
int $line):
void {
74 throw new ErrorException($message, $severity, $severity, $file, $line);
79 if (!$document->loadHTML($text)) {
83 throw new InvalidArgumentException(__METHOD__ .
' the argument is not a parsable XHTML string: ' . $e->getMessage());
85 restore_error_handler();
93 $textNodes = $xpath->query(
'//text()');
94 if ($textNodes->length > 0) {
95 foreach ($textNodes as $textNode) {
101 $wordsInContent = array_filter(preg_split(
'/\s+/', $textNode->textContent));
103 $wordsInContent = array_filter($wordsInContent,
static function (
string $word):
bool {
104 return preg_replace(
'/^\pP$/u',
'', $word) !==
'';
107 $numberOfWords += count($wordsInContent);
111 if ($this->withImages) {
112 $imageNodes = $document->getElementsByTagName(
'img');
116 $readingTime = ceil($numberOfWords / $this->wordsPerMinute);
118 return (
int) $readingTime;
130 for ($i = 1; $i <= $numberOfImages; $i++) {
132 $time += 3 * ($this->wordsPerMinute / 60);
134 $time += (12 - ($i - 1)) * ($this->wordsPerMinute / 60);
143 $this->xmlErrorState = libxml_use_internal_errors(
true);
144 libxml_clear_errors();
149 $currentErrors = libxml_get_errors();
150 libxml_clear_errors();
152 $this->xmlErrors = $currentErrors;
157 libxml_use_internal_errors($this->xmlErrorState);
162 return $this->xmlErrors !== [];
168 foreach ($this->xmlErrors as
$error) {
169 $text .= implode(
',', [
170 'level=' . $error->level,
171 'code=' . $error->code,
172 'line=' . $error->line,
173 'col=' . $error->column,
174 'msg=' . trim($error->message)
trait DeriveInvokeFromTransform
trait DeriveApplyToFromTransform
__construct(bool $withImages)
calculateWordsForImages(int $numberOfImages)