summaryrefslogtreecommitdiff
path: root/php/luigi-template.php
diff options
context:
space:
mode:
authorPaul Duncan <pabs@pablotron.org>2018-09-04 02:44:57 -0400
committerPaul Duncan <pabs@pablotron.org>2018-09-04 02:44:57 -0400
commit43e03c125dcf0413ee9ab844ced3583c91894253 (patch)
tree5fcfbdd43d8328a58a5e0c4463504d49d5a60a9c /php/luigi-template.php
parent5e573b51b076573d49a56f13f898a1a2e8affcf7 (diff)
downloadluigi-template-43e03c125dcf0413ee9ab844ced3583c91894253.tar.bz2
luigi-template-43e03c125dcf0413ee9ab844ced3583c91894253.zip
php: add composer.json, mv luigi-template.php src/
Diffstat (limited to 'php/luigi-template.php')
-rw-r--r--php/luigi-template.php393
1 files changed, 0 insertions, 393 deletions
diff --git a/php/luigi-template.php b/php/luigi-template.php
deleted file mode 100644
index 69e3fb8..0000000
--- a/php/luigi-template.php
+++ /dev/null
@@ -1,393 +0,0 @@
-<?php
-declare(strict_types = 1);
-
-namespace Luigi;
-
-const VERSION = '0.4.2';
-
-class Error extends \Exception {};
-
-class UnknownTypeError extends Error {
- public $type,
- $name;
-
- public function __construct(string $type, string $name) {
- $this->type = $type;
- $this->name = $name;
- parent::__construct("unknown $type: $name");
- }
-};
-
-final class UnknownTemplateError extends UnknownTypeError {
- public function __construct(string $name) {
- parent::__construct('template', $name);
- }
-};
-
-final class UnknownFilterError extends UnknownTypeError {
- public function __construct(string $name) {
- parent::__construct('filter', $name);
- }
-};
-
-final class UnknownKeyError extends UnknownTypeError {
- public function __construct(string $name) {
- parent::__construct('key', $name);
- }
-};
-
-final class MissingFilterParameterError extends Error {
- public $filter_name;
-
- public function __construct(string $filter_name) {
- $this->filter_name = $filter_name;
- parent::__construct("missing required filter parameter for filter $filter_name");
- }
-};
-
-final class InvalidTemplateError extends Error {
- public $template;
-
- public function __construct(string $template) {
- $this->template = $template;
- parent::__construct("invalid template: $template");
- }
-};
-
-namespace Luigi;
-
-final class RunContext {
- public $args,
- $filters;
-
- public function __construct(array $args, array $filters) {
- $this->args = $args;
- $this->filters = $filters;
- }
-};
-
-final class TemplateFilter {
- private $name,
- $args;
-
- public function __construct(string $name, array $args) {
- $this->name = $name;
- $this->args = $args;
- }
-
- public function run($v, array &$args, array &$filters) {
- if (!isset($filters[$this->name])) {
- throw new UnknownFilterError($this->name);
- }
-
- # get callback
- $cb = $filters[$this->name];
-
- # invoke callback, return result
- return $cb($v, $this->args, $args);
- }
-};
-
-namespace Luigi\Parser;
-
-use Luigi\RunContext;
-use Luigi
-
-abstract class Token {
- public function run(array $args, array $filters) : string;
-};
-
-final class LiteralToken extends Token {
- private $val;
-
- public function __construct(string $val) {
- $this->val = $val;
- }
-
- public function run(array &$args, array &$filters) : string {
- return $this->val;
- }
-};
-
-final class FilterToken extends Token {
- private $key,
- $filters;
-
- public function __construct(string $key, array $filters) {
- $this->key = $key;
- $this->filters = $filters;
- }
-
- public function run(array &$args, array &$filters) : string {
- if (!isset($args[$this->key])) {
- throw new UnknownKeyError($this->key);
- }
-
- # get initial value
- $r = $args[$this->key];
-
- if ($this->filters && count($this->filters) > 0) {
- # pass value through filters
- $r = array_reduce($this->filters, function($r, $f) use (&$args, &$filters) {
- return $f->run($r, $args, $filters);
- }, $r);
- }
-
- # return result
- return $r;
- }
-};
-
-const TOKEN_RE = '/
- # match opening brace
- %\{
-
- # match optional whitespace
- \s*
-
- # match key
- (?<key>[^\s\|\}]+)
-
- # match filter(s)
- (?<filters>(\s*\|(\s*[^\s\|\}]+)+)*)
-
- # match optional whitespace
- \s*
-
- # match closing brace
- \}
-
- # or match up all non-% chars or a single % char
- | (?<text>[^%]* | %)
-/mx';
-
-const FILTER_RE = '/
- # match filter name
- (?<name>\S+)
-
- # match filter arguments (optional)
- (?<args>(\s*\S+)*)
-
- # optional trailing whitespace
- \s*
-/mx';
-
-const DELIM_FILTERS_RE = '/\s*\|\s*/m';
-
-const DELIM_ARGS_RE = '/\s+/m';
-
-function parse_filters(string $filters) : array {
- # split into individual filters
- $r = [];
-
- foreach (preg_split(DELIM_FILTERS_RE, $filters) as $f) {
- # trim whitespace
- $f = trim($f);
-
- # skip empty filters
- if (!$f)
- continue;
-
- # match filter
- $md = [];
- if (!preg_match(FILTER_RE, $f, $md)) {
- throw new UnknownFilterError($f);
- }
-
- # add filter to results
- $r[] = new TemplateFilter($md['name'], (count($md) > 2) ? preg_split(
- DELIM_ARGS_RE,
- trim($md['args'])
- ) : []);
- }
-
- # return results
- return $r;
-}
-
-function parse_template(string $template) : array {
- # build list of matches
- $matches = [];
- $num_matches = preg_match_all(TOKEN_RE, $template, $matches, PREG_SET_ORDER);
-
- # check for error
- if ($num_matches === false) {
- throw new InvalidTemplateError($template);
- }
-
- # map matches to tokens
- return array_map(function($m) {
- if ($m['key'] !== '') {
- # filter token
- return new FilterToken($m['key'], parse_filters($m['filters']));
- } else {
- # literal token
- return new LiteralToken($m['text']);
- }
- }, $matches);
-}
-
-namespace Luigi;
-
-public $FILTERS = [
- 'h' => function($s) {
- return htmlspecialchars($v, ENT_QUOTES);
- },
-
- 'u' => function($s) {
- return urlencode($v);
- },
-
- 'json' => function($v) {
- return json_encode($v);
- },
-
- 'hash' => function($v, $args) {
- if (count($args) !== 1) {
- throw new MissingFilterParameterError('hash');
- }
-
- return hash($args[0], $v);
- },
-
- 'base64' => function($v) {
- return base64_encode($v);
- },
-
- 'nl2br' => function($v) {
- return nl2br($v);
- },
-
- 'uc' => function($v) {
- return strtoupper($v);
- },
-
- 'lc' => function($v) {
- return strtolower($v);
- },
-
- 'trim' => function($v) {
- return trim($v);
- },
-
- 'rtrim' => function($v) {
- return rtrim($v);
- },
-
- 'ltrim' => function($v) {
- return ltrim($v);
- },
-
- 's' => function($v) {
- return ($v == 1) ? '' : 's';
- },
-
- 'strlen' => function($v) {
- return strlen($v);
- },
-
- 'count' => function($v) {
- return count($v);
- },
-
- 'key' => function($v, $args) {
- if (count($args) !== 1) {
- throw new MissingFilterParameterError('key');
- }
-
- # get key
- $key = $args[0];
-
- # make sure key exists
- if (!isset($v[$key])) {
- throw new UnknownKeyError($key);
- }
-
- # return key
- return $v[$key];
- },
-];
-
-final class Template {
- private $template,
- $filters,
- $tokens;
-
- public function __construct(
- string $template,
- array $custom_filters = []
- ) {
- global $FILTERS;
-
- $this->template = $template;
- $this->filters = count($custom_filters) ? $custom_filters : $FILTERS;
-
- # parse template into list of tokens
- $this->tokens = Parser\parse_template($template);
- }
-
- public function run(array $args = []) : string {
- # php sucks
- $me = $this;
-
- return join('', array_map(function($token) use ($me, $args) {
- return $token->run($args, $this->filters);
- }, $this->tokens));
- }
-
- public static function once($str, $args = [], array $filters = []) {
- $t = new Template($str, $filters);
- return $t->run($args);
- }
-};
-
-public function run(
- string $template,
- array $args = [],
- array $filters = []
-) : string {
- $t = new Template($template, $filters);
- return $t->run($args);
-}
-
-final class Cache implements \ArrayAccess {
- private $templates,
- $filters,
- $lut = [];
-
- public function __construct(array $templates, array $filters = []) {
- $this->templates = $templates;
- $this->filters = $filters;
- }
-
- public function offsetExists($key) : bool {
- return isset($this->templates[$key]);
- }
-
- public function offsetGet($key) {
- if (isset($this->lut[$key])) {
- return $this->lut[$key];
- } else if (isset($this->templates[$key]) {
- $this->lut[$key] = new Template($this->templates[$key], $this->filters);
- return $this->lut[$key];
- } else {
- throw new UnknownTemplateError($key);
- }
- }
-
- public function offsetUnset($key) {
- delete($this->lut[$key]);
- delete($this->templates[$key]);
- }
-
- public function offsetSet($key, $val) : bool {
- delete($this->lut[$key]);
- $this->templates[$key] = $val;
- return isset($this->templates[$key]);
- }
-
-
- public function run(string $key, array $args = []) : string {
- return $this->offsetGet($key)->run($args);
- }
-};