diff --git a/src/output/IPrintable.php b/src/output/IPrintable.php deleted file mode 100644 index a5b67bb..0000000 --- a/src/output/IPrintable.php +++ /dev/null @@ -1,11 +0,0 @@ -getContent(); - } elseif ($values instanceof IPrintable) { - ob_start(null, 0, PHP_OUTPUT_HANDLER_STDFLAGS ^ PHP_OUTPUT_HANDLER_FLUSHABLE); - $values->print(); - $dest[] = ob_get_clean(); - return $dest; - } elseif (!is_iterable($values)) { - $dest[] = strval($values); - return $dest; - } - } - foreach ($values as $value) { - self::flatten($value, $dest); - } - return $dest; - } - function getIndent(int $indentLevel): string { return str_repeat($this->indent, $indentLevel); } function getLines(bool $withNl, ...$values): array { - $values = self::flatten($values); + $values = content::flatten($values); if (!$values) return []; $text = implode("", $values); if ($text === "") return [""]; diff --git a/src/output/IContent.php b/src/sys/IContent.php similarity index 87% rename from src/output/IContent.php rename to src/sys/IContent.php index fbddc2a..d5e2412 100644 --- a/src/output/IContent.php +++ b/src/sys/IContent.php @@ -1,5 +1,5 @@ getContent(); + } elseif ($contents instanceof IPrintable) { + ob_start(null, 0, PHP_OUTPUT_HANDLER_STDFLAGS ^ PHP_OUTPUT_HANDLER_FLUSHABLE); + $contents->print(); + $dest[] = ob_get_clean(); + return $dest; + } elseif (!is_iterable($contents)) { + $dest[] = $contents; + return $dest; + } + foreach ($contents as $value) { + self::flatten($value, $dest); + } + return $dest; + } + + /** + * résoudre tout le contenu statique: il ne restera plus qu'une liste de + * chaines ou d'instances de IContent, IPrintable ou des objets quelconques + */ + static function resolve_static($contents, $dest_class=null, bool $quote=true, ?array &$dest=null): array { + if ($dest === null) $dest = []; + if ($contents === null) return $dest; + if (is_string($contents)) { + if ($quote) $contents = htmlspecialchars($contents); + $dest[] = $contents; + return $dest; + } elseif ($contents instanceof IContent) { + $dest[] = $contents; + return $dest; + } elseif ($contents instanceof IPrintable) { + $dest[] = $contents; + return $dest; + } elseif (!is_iterable($contents)) { + $dest[] = $contents; + return $dest; + } + foreach ($contents as $content) { + if ($content === null) continue; + elseif (is_string($content)) $dest[] = $content; + elseif ($contents instanceof IContent) $dest[] = $content; + elseif ($contents instanceof IPrintable) $dest[] = $content; + elseif (!is_array($content)) $dest[] = $content; + else { + # ici, $content est soit: + # - un appel de fonction ou méthode statique d'une des formes suivantes: + # - [class, method, ...args] + # - [null, method, ...args] + # - [[class, method], ...args] + # - [[null, method], ...args] + # - ou une définition d'objet d'une des formes suivantes + # - [class, ...args] + # - [[class], ...args] + $class = false; + if (array_key_exists(0, $content) && is_array($content[0])) { + # $content est de la forme [func_or_class, ...args] + $func = $content[0]; + $args = array_slice($content, 1); + if (func::is_class($func)) { + $class = true; + func::fix_class_args($func, $args); + } else { + func::ensure_func($func, $dest_class, $args); + } + } else { + # $content est de la forme $func + $func = $content; + if (func::is_class($func)) { + $class = true; + func::fix_class_args($func, $args); + } else { + func::ensure_func($func, $dest_class, $args); + } + } + # chaque argument est un contenu statique + foreach ($args as &$arg) { + $arg = self::resolve_static($arg, $dest_class, false); + $arg = self::flatten($arg); + switch (count($arg)) { + case 0: $arg = null; break; + case 1: $arg = $arg[0]; break; + default: $arg = implode("", $arg); + } + }; unset($arg); + # puis appeler la fonction + if ($class) $content = func::cons($func, ...$args); + else $content = func::call($func, ...$args); + $dest[] = $content; + } + } + } +}