class HamlParser in Sassy 7
HamlParser class. Parses {@link http://haml-lang.com/ Haml} view files. @package PHamlP @subpackage Haml
Hierarchy
- class \HamlParser
Expanded class hierarchy of HamlParser
1 string reference to 'HamlParser'
- HamlView::_init in phamlp/
Cake/ views/ haml.php - * Do a sanity check on the options and setup alias to filters
File
- phamlp/
haml/ HamlParser.php, line 65
View source
class HamlParser {
/**#@+
* Debug modes
*/
const DEBUG_NONE = 0;
const DEBUG_SHOW_SOURCE = 1;
const DEBUG_SHOW_OUTPUT = 2;
const DEBUG_SHOW_ALL = 3;
/**#@-*/
/**#@+
* Regexes used to parse the document
*/
const REGEX_HAML = '/(?m)^([ \\x09]*)((?::(\\w*))?(?:%([\\w:-]*))?(?:\\.((?:(?:[-_:a-zA-Z]|#\\{.+?\\})+(?:[-:\\w]|#\\{.+?\\})*(?:\\.?))*))?(?:#((?:[_:a-zA-Z]|#\\{.+?\\})+(?:[-:\\w]|#\\{.+?\\})*))?(?:\\[(.+)\\])?(?:(\\()((?:(?:\\w+\\(.*?\\)|data[\\t ]*=[\\t ]*\\{.+?\\}|(?:[_:a-zA-Z]+[-:\\w]*)[\\t ]*=[\\t ]*.+)[\\t ]*)+\\)))?(?:(\\{)((?:(?:\\w+\\(.*?\\)|:data[\\t ]*=>[\\t ]*\\{.+?\\}|:(?:[_:a-zA-Z]+[-:\\w]*)[\\t ]*=>?[\\t ]*.+)(?:,?[\\t ]*)?)+\\}))?(\\|?>?\\|?<?) *((?:\\?#)|!!!|\\/\\/|\\/|-#|!=|&=|!|&|=|-|~|\\\\\\\\)? *(.*?)(?:\\s(\\|)?)?)$/';
// Haml line
const REGEX_ATTRIBUTES = '/:?(?:(data)\\s*=>?\\s*([({].*?[})]))|(\\w+(?:[-:]\\w*)*)\\s*=>?\\s*(?(?=\\[)(?:\\[(.+?)\\])|(?(?=([\'"]))(?:[\'"](.*?)\\5)|([^\\s,]+)))/';
const REGEX_ATTRIBUTE_FUNCTION = '/^\\$?[_a-zA-Z]\\w*(?(?=->)(->[_a-zA-Z]\\w*)+|(::[_a-zA-Z]\\w*)?)\\(.+\\)$/';
// Matches functions and instantiated and static object methods
const REGEX_WHITESPACE_REMOVAL = '/(.*?)\\s+$/s';
const REGEX_WHITESPACE_REMOVAL_DEBUG = '%(.*?)(?:<br />\\s)$%s';
// whitespace control when showing output
//const REGEX_CODE_INTERPOLATION = '/(?:(?<!\\\\)#{(.+?(?:\(.*?\).*?)*)})/';
/**#@-*/
const MATCH_INTERPOLATION = '/(?<!\\\\)#\\{(.*?)\\}/';
const INTERPOLATE = '<?php echo \\1; ?>';
const HTML_ATTRS = '/html_attrs\\(\\s*((?(?=\')(?:.*?)\'|(?:.*?)"))(?:\\s*,\\s*(.*?))?\\)/';
/**#@+
* Haml regex match positions
*/
const HAML_HAML = 0;
const HAML_INDENT = 1;
const HAML_SOURCE = 2;
const HAML_FILTER = 3;
const HAML_TAG = 4;
const HAML_CLASS = 5;
const HAML_ID = 6;
const HAML_OBJECT_REFERENCE = 7;
const HAML_OPEN_XML_ATTRIBUTES = 8;
const HAML_XML_ATTRIBUTES = 9;
const HAML_OPEN_RUBY_ATTRIBUTES = 10;
const HAML_RUBY_ATTRIBUTES = 11;
const HAML_WHITESPACE_REMOVAL = 12;
const HAML_TOKEN = 13;
const HAML_CONTENT = 14;
const HAML_MULTILINE = 15;
/**#@-*/
/**#@+
* Haml tokens
*/
const DOCTYPE = '!!!';
const HAML_COMMENT = '!(-#|//)!';
const XML_COMMENT = '/';
const SELF_CLOSE_TAG = '/';
const ESCAPE_XML = '&=';
const UNESCAPE_XML = '!=';
const INSERT_CODE = '=';
const INSERT_CODE_PRESERVE_WHITESPACE = '~';
const RUN_CODE = '-';
const INNER_WHITESPACE_REMOVAL = '<';
const OUTER_WHITESPACE_REMOVAL = '>';
const BLOCK_LEFT_OUTER_WHITESPACE_REMOVAL = '|>';
const BLOCK_RIGHT_OUTER_WHITESPACE_REMOVAL = '>|';
/**#@-*/
const MULTILINE = ' |';
/**#@+
* Attribute tokens
*/
const OPEN_XML_ATTRIBUTES = '(';
const CLOSE_XML_ATTRIBUTES = ')';
const OPEN_RUBY_ATTRIBUTES = '{';
const CLOSE_RUBY_ATTRIBUTES = '}';
/**#@-*/
/**#@+
* Directives
*/
const DIRECTIVE = '?#';
const SOURCE_DEBUG = 's';
const OUTPUT_DEBUG = 'o';
/**#@-*/
const IS_XML_PROLOG = 'XML';
const XML_PROLOG = "<?php echo \"<?xml version='1.0' encoding='{encoding}' ?>\n\"; ?>";
const DEFAULT_XML_ENCODING = 'utf-8';
const XML_ENCODING = '{encoding}';
/**
* @var string Doctype format. Determines how the Haml Doctype declaration is
* rendered.
* @see doctypes
*/
private $format = 'xhtml';
/**
* @var string Custom Doctype. If not null and the Doctype declaration in the
* Haml Document is not a built in Doctype this will be used as the Doctype.
* This allows Haml to be used for non-(X)HTML documents that are XML compliant.
* @see doctypes
* @see emptyTags
* @see inlineTags
* @see minimizedAttributes
*/
private $doctype;
/**
* @var boolean whether or not to escape X(HT)ML-sensitive characters in script.
* If this is true, = behaves like &=; otherwise, it behaves like !=.
* Note that if this is set, != should be used for yielding to subtemplates
* and rendering partials. Defaults to false.
*/
private $escapeHtml = false;
/**
* @var boolean Whether or not attribute hashes and scripts designated by
* = or ~ should be evaluated. If true, the scripts are rendered as empty strings.
* Defaults to false.
*/
private $suppressEval = false;
/**
* @var string The character that should wrap element attributes. Characters
* of this type within attributes will be escaped (e.g. by replacing them with
* ') if the character is an apostrophe or a quotation mark.
* Defaults to " (an quotation mark).
*/
private $attrWrapper = '"';
/**
* @var array available output styles:
* nested: output is nested according to the indent level in the source
* expanded: block tags have their own lines as does content which is indented
* compact: block tags and their content go on one line
* compressed: all unneccessary whitepaces is removed. If ugly is true this style is used.
*/
private $styles = array(
'nested',
'expanded',
'compact',
'compressed',
);
/**
* @var string output style. Note: ugly must be false to allow style.
*/
private $style = 'nested';
/**
* @var boolean if true no attempt is made to properly indent or format
* the output. Reduces size of output file but is not very readable;
* equivalent of style == compressed. Note: ugly must be false to allow style.
* Defaults to true.
* @see style
*/
private $ugly = true;
/**
* @var boolean if true comments are preserved in ugly mode. If not in
* ugly mode comments are always output. Defaults to false.
*/
private $preserveComments = false;
/**
* @var integer Initial debug setting:
* no debug, show source, show output, or show all.
* Debug settings can be controlled in the template
* Defaults to DEBUG_NONE.
*/
private $debug = self::DEBUG_NONE;
/**
* @var string Path to the directory containing user defined filters. If
* specified this dirctory will be searched before PHamlP looks for the filter
* in it's collection. This allows the default filters to be overridden and
* new filters to be installed. Note: No trailing directory separator.
*/
private $filterDir;
/**
* @var string Path to the file containing user defined Haml helpers.
*/
private $helperFile;
/**
* @var string Haml helper class. This must be an instance of HamlHelpers.
*/
private $helperClass = 'HamlHelpers';
/**
* @var array built in Doctypes
* @see format
* @see doctype
*/
private $doctypes = array(
'html4' => array(
'<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">',
//HTML 4.01 Transitional
'Strict' => '<!DOCTYPE html PUBLIC "-//W3C//DTD 4.01 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">',
//HTML 4.01 Strict
'Frameset' => '<!DOCTYPE html PUBLIC "-//W3C//DTD 4.01 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">',
),
'html5' => array(
'<!DOCTYPE html>',
),
'xhtml' => array(
'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">',
//XHTML 1.0 Transitional
'Strict' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">',
//XHTML 1.0 Strict
'Frameset' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">',
//XHTML 1.0 Frameset
'5' => '<!DOCTYPE html>',
// XHTML 5
'1.1' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">',
// XHTML 1.1
'Basic' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">',
//XHTML Basic 1.1
'Mobile' => '<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.2//EN" "http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd">',
//XHTML Mobile 1.2
'RDFa' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN" "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd">',
),
);
/**
* @var array A list of tag names that should be automatically self-closed
* if they have no content.
*/
private $emptyTags = array(
'meta',
'img',
'link',
'br',
'hr',
'input',
'area',
'param',
'col',
'base',
);
/**
* @var array A list of inline tags.
*/
private $inlineTags = array(
'a',
'abbr',
'accronym',
'b',
'big',
'cite',
'code',
'dfn',
'em',
'i',
'kbd',
'q',
'samp',
'small',
'span',
'strike',
'strong',
'tt',
'u',
'var',
);
/**
* @var array attributes that are minimised
*/
private $minimizedAttributes = array(
'compact',
'checked',
'declare',
'readonly',
'disabled',
'selected',
'defer',
'ismap',
'nohref',
'noshade',
'nowrap',
'multiple',
'noresize',
);
/**
* @var array A list of tag names that should automatically have their newlines preserved.
*/
private $preserve = array(
'pre',
'textarea',
);
/**#@-*/
/**
* @var string the character used for indenting. Space or tab.
* @see indentSpaces
*/
private $indentChar;
/**
* @var array allowable characters for indenting
*/
private $indentChars = array(
' ',
"\t",
);
/**
* @var integer number of spaces for indentation.
* Used on source if {@link indentChar} is space.
* Used on output if {@link ugly} is false.
*/
private $indentSpaces;
/**
* @var array loaded filters
*/
private $filters = array();
/**
* @var boolean whether line is in a filter
*/
private $inFilter = false;
/**
* @var boolean whether to show the output in the browser for debug
*/
private $showOutput;
/**
* @var boolean whether to show the source in the browser for debug
*/
private $showSource;
/**
* @var integer line number of source being parsed
*/
private $line;
/**
* @var string name of file being parsed
*/
private $filename;
/**
* @var mixed source
*/
private $source;
/**
* HamlParser constructor.
* @param array options
* @return HamlParser
*/
public function __construct($options = array()) {
if (isset($options['language'])) {
Phamlp::$language = $options['language'];
unset($options['language']);
}
foreach ($options as $name => $value) {
$this->{$name} = $value;
}
// foreach
if ($this->ugly) {
$this->style = 'compressed';
}
$this->format = strtolower($this->format);
if (is_null($this->doctype) && !array_key_exists($this->format, $this->doctypes)) {
throw new HamlException('Invalid {what} ({value}). Must be one of "{options}"', array(
'{what}' => 'format',
'{value}' => $this->format,
'{options}' => join(', ', array_keys($this->doctypes)),
), $this);
}
$this->showSource = $this->debug & HamlParser::DEBUG_SHOW_SOURCE;
$this->showOutput = $this->debug & HamlParser::DEBUG_SHOW_OUTPUT;
require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'HamlHelpers.php';
if (isset($this->helperFile)) {
require_once $this->helperFile;
$this->helperClass = basename($this->helperFile, ".php");
if (!is_subclass_of($this->helperClass, 'HamlHelpers')) {
throw new HamlException('{what} must extend {base} class', array(
'{what}' => $this->helperClass,
'{base}' => 'HamlHelpers',
), $this);
}
}
}
/**
* Getter.
* @param string name of property to get
* @return mixed return value of getter function
*/
public function __get($name) {
$getter = 'get' . ucfirst($name);
if (method_exists($this, $getter)) {
return $this
->{$getter}();
}
throw new HamlException('No getter function for {what}', array(
'{what}' => $name,
));
}
public function getFilename() {
return $this->filename;
}
public function getLine() {
return $this->line;
}
public function getSource() {
return $this->source;
}
/**
* Parses a Haml file.
* If an output directory is given the resulting PHP is cached.
* @param string path to file to parse
* @param mixed boolean: true to use the default cache directory, false to use
* the source file directory. string: path to the cache directory.
* null: disable caching
* @param string output file extension
* @param integer permission for the output directory and file
* @return mixed string: the resulting PHP if no output directory is specified
* or the output filename if the output directory is specified.
* boolean: false if the output file could not be written.
*/
public function parse($sourceFile, $cacheDir = null, $permission = 0755, $sourceExtension = '.haml', $outputExtension = '.php') {
if (is_string($cacheDir) || is_bool($cacheDir)) {
if (is_bool($cacheDir)) {
$cacheDir = $cacheDir ? dirname(__FILE__) . DIRECTORY_SEPARATOR . 'haml-cache' : dirname($sourceFile);
}
$outputFile = $cacheDir . DIRECTORY_SEPARATOR . basename($sourceFile, $sourceExtension) . $outputExtension;
if (!is_file($outputFile) || @filemtime($sourceFile) > @filemtime($outputFile)) {
if (!is_dir($cacheDir)) {
@mkdir($cacheDir, $permission);
}
$return = file_put_contents($outputFile, $this
->haml2PHP($sourceFile)) === false ? false : $outputFile;
if ($return !== false) {
@chmod($outputFile, $permission);
}
}
else {
$return = $outputFile;
}
}
else {
$return = $this
->haml2PHP($sourceFile);
}
return $return;
}
/**
* Parses a Haml file into PHP.
* @param string path to file to parse
* @return string the resulting PHP
*/
public function haml2PHP($sourceFile) {
$this->line = 0;
$this->filename = $sourceFile;
$helpers = "<?php\nrequire_once '" . dirname(__FILE__) . DIRECTORY_SEPARATOR . "HamlHelpers.php';\n";
if (isset($this->helperFile)) {
$helpers .= "require_once '{$this->helperFile}';\n";
}
$helpers .= "?>";
return $helpers . $this
->toTree(file_get_contents($sourceFile))
->render();
}
/**
* Parse Haml source into a document tree.
* @param string Haml source
* @return HamlRootNode the root of this document tree
*/
private function toTree($source) {
$source = str_replace(array(
"\r\n",
"\n\r",
"\r",
), "\n", $source);
$this->source = explode("\n", $source);
$this
->setIndentChar();
preg_match_all(self::REGEX_HAML, $source, $this->source, PREG_SET_ORDER);
unset($source);
$root = new HamlRootNode(array(
'format' => $this->format,
'style' => $this->style,
'attrWrapper' => $this->attrWrapper,
'minimizedAttributes' => $this->minimizedAttributes,
));
$this
->buildTree($root);
return $root;
}
/**
* Builds a parse tree under the parent node.
* @param HamlNode the parent node
*/
private function buildTree($parent) {
while (!empty($this->source) && $this
->isChildOf($parent, $this->source[0])) {
$line = $this
->getNextLine();
if (!empty($line)) {
$node = $this->inFilter ? new HamlNode($line[self::HAML_SOURCE], $parent) : $this
->parseLine($line, $parent);
if (!empty($node)) {
$node->token = $line;
$node->showOutput = $this->showOutput;
$node->showSource = $this->showSource;
$this
->addChildren($node, $line);
}
}
}
}
/**
* Adds children to a node if the current line has children.
* @param HamlNode the node to add children to
* @param array line to test
*/
private function addChildren($node, $line) {
if ($node instanceof HamlFilterNode) {
$this->inFilter = true;
}
if ($this
->hasChild($line, $this->inFilter)) {
$this
->buildTree($node);
if ($node instanceof HamlFilterNode) {
$this->inFilter = false;
}
}
}
/**
* Returns a value indicating if the next line is a child of the parent line
* @param array parent line
* @param boolean whether to all greater than the current indent
* Used if the source line is a comment or a filter.
* If true all indented lines are regarded as children; if not the child line
* must only be indented by 1 or blank. Defaults to false.
* @return boolean true if the next line is a child of the parent line
* @throws Exception if the indent is invalid
*/
private function hasChild($line, $allowGreater = false) {
if (!empty($this->source)) {
$i = 0;
$c = count($this->source);
while (empty($nextLine[self::HAML_SOURCE]) && $i <= $c) {
$nextLine = $this->source[$i++];
}
$level = $this
->getLevel($nextLine, $line['line'] + $i);
if ($level == $line['level'] + 1 || $allowGreater && $level > $line['level']) {
return true;
}
elseif ($level <= $line['level']) {
return false;
}
else {
throw new HamlException('Illegal indentation level ({level}); indentation level can only increase by one', array(
'{level}' => $level,
), $this);
}
}
else {
return false;
}
}
/**
* Returns a value indicating if $line is a child of a node.
* A blank line is a child of a node.
* @param HamlNode the node
* @param array the line to check
* @return boolean true if the line is a child of the node, false if not
*/
private function isChildOf($node, $line) {
$haml = trim($line[self::HAML_HAML]);
return empty($haml) || $this
->getLevel($line, $this->line) > $node->level;
}
/**
* Determine the indent character and indent spaces.
* The first character of the first indented line determines the character.
* If this is a space the number of spaces determines the indentSpaces; this
* is always 1 if the indent character is a tab.
* @throws HamlException if the indent is mixed
*/
private function setIndentChar() {
foreach ($this->source as $l => $source) {
if (!empty($source) && in_array($source[0], $this->indentChars)) {
$this->indentChar = $source[0];
for ($i = 0, $len = strlen($source); $i < $len && $source[$i] == $this->indentChar; $i++) {
}
if ($i < $len && in_array($source[$i], $this->indentChars)) {
$this->line = ++$l;
$this->source = $source;
throw new HamlException('Mixed indentation not allowed', array(), $this);
}
$this->indentSpaces = $this->indentChar == ' ' ? $i : 1;
return;
}
}
// foreach
$this->indentChar = ' ';
$this->indentSpaces = 2;
}
/**
* Gets the next line.
* @param array remaining source lines
* @return array the next line
*/
private function getNextLine() {
$line = array_shift($this->source);
// Blank lines ore OK
$haml = trim($line[self::HAML_HAML]);
if (empty($haml)) {
$this->line++;
return null;
}
// The regex will strip off a '<' at the start of a line
if ($line[self::HAML_WHITESPACE_REMOVAL] === self::INNER_WHITESPACE_REMOVAL && empty($line[self::HAML_TAG])) {
$line[self::HAML_CONTENT] = $line[self::HAML_WHITESPACE_REMOVAL] . $line[self::HAML_TOKEN] . $line[self::HAML_CONTENT];
}
// The regex treats lines starting with [.+] as an object reference; they are just content
if (!empty($line[self::HAML_OBJECT_REFERENCE]) && empty($line[self::HAML_TAG])) {
unset($line[self::HAML_OBJECT_REFERENCE]);
$line[self::HAML_CONTENT] = $line[self::HAML_SOURCE];
}
$line['line'] = $this->line++;
$line['level'] = $this
->getLevel($line, $this->line);
$line['filename'] = $this->filename;
if ($this
->isMultiline($line)) {
$line = $this
->getMultiline($line);
}
return $line;
}
/**
* Returns the indent level of the line.
* @param array the line
* @param integer line number
* @return integer the indent level of the line
* @throws Exception if the indent level is invalid
*/
private function getLevel($line, $n) {
if ($line[self::HAML_INDENT] && $this->indentChar === ' ') {
$indent = strlen($line[self::HAML_INDENT]) / $this->indentSpaces;
}
else {
$indent = strlen($line[self::HAML_INDENT]);
}
if (!is_integer($indent) || preg_match("/[^{$this->indentChar}]/", $line[self::HAML_INDENT])) {
throw new HamlException('Invalid indentation', array(), $this);
}
return $indent;
}
/**
* Parse a line of Haml into a HamlNode for the document tree
* @param array line to parse
* @param HamlNode parent node
* @return HamlNode
*/
private function parseLine($line, $parent) {
if ($this
->isHamlComment($line)) {
return $this
->parseHamlComment($line);
}
elseif ($this
->isXmlComment($line)) {
return $this
->parseXmlComment($line, $parent);
}
elseif ($this
->isElement($line)) {
return $this
->parseElement($line, $parent);
}
elseif ($this
->isHelper($line)) {
return $this
->parseHelper($line, $parent);
}
elseif ($this
->isCode($line)) {
return $this
->parseCode($line, $parent);
}
elseif ($this
->isDirective($line)) {
return $this
->parseDirective($line, $parent);
}
elseif ($this
->isFilter($line)) {
return $this
->parseFilter($line, $parent);
}
elseif ($this
->isDoctype($line)) {
return $this
->parseDoctype($line, $parent);
}
else {
return $this
->parseContent($line, $parent);
}
}
/**
* Return a value indicating if the line has content.
* @param array line
* @return boolean true if the line has a content, false if not
*/
private function hasContent($line) {
return !empty($line[self::HAML_CONTENT]);
}
/**
* Return a value indicating if the line is code to be run.
* @param array line
* @return boolean true if the line is code to be run, false if not
*/
private function isCode($line) {
return $line[self::HAML_TOKEN] === self::RUN_CODE;
}
/**
* Return a value indicating if the line is a directive.
* @param array line
* @return boolean true if the line is a directive, false if not
*/
private function isDirective($line) {
return $line[self::HAML_TOKEN] === self::DIRECTIVE;
}
/**
* Return a value indicating if the line is a doctype.
* @param array line
* @return boolean true if the line is a doctype, false if not
*/
private function isDoctype($line) {
return $line[self::HAML_TOKEN] === self::DOCTYPE;
}
/**
* Return a value indicating if the line is an element.
* Will set the tag to div if it is an implied div.
* @param array line
* @return boolean true if the line is an element, false if not
*/
private function isElement(&$line) {
if (empty($line[self::HAML_TAG]) && (!empty($line[self::HAML_CLASS]) || !empty($line[self::HAML_ID]) || !empty($line[self::HAML_XML_ATTRIBUTES]) || !empty($line[self::HAML_RUBY_ATTRIBUTES]) || !empty($line[self::HAML_OBJECT_REFERENCE]))) {
$line[self::HAML_TAG] = 'div';
}
return !empty($line[self::HAML_TAG]);
}
/**
* Return a value indicating if the line starts a filter.
* @param array line to test
* @return boolean true if the line starts a filter, false if not
*/
private function isFilter($line) {
return !empty($line[self::HAML_FILTER]);
}
/**
* Return a value indicating if the line is a Haml comment.
* @param array line to test
* @return boolean true if the line is a Haml comment, false if not
*/
private function isHamlComment($line) {
return preg_match(self::HAML_COMMENT, $line[self::HAML_TOKEN]) > 0;
}
/**
* Return a value indicating if the line is a HamlHelper.
* @param array line to test
* @return boolean true if the line is a HamlHelper, false if not
*/
private function isHelper($line) {
return preg_match(HamlHelperNode::MATCH, $line[self::HAML_CONTENT], $matches) ? method_exists($this->helperClass, $matches[HamlHelperNode::NAME]) : false;
}
/**
* Return a value indicating if the line is an XML comment.
* @param array line to test
* @return boolean true if theline is an XML comment, false if not
*/
private function isXmlComment($line) {
return $line[self::HAML_SOURCE][0] === self::XML_COMMENT;
}
/**
* Returns a value indicating whether the line is part of a multilne group
* @param array the line to test
* @return boolean true if the line os part of a multiline group, false if not
*/
private function isMultiline($line) {
return substr($line[self::HAML_SOURCE], -2) === self::MULTILINE;
}
/**
* Return a value indicating if the line's tag is a block level tag.
* @param array line
* @return boolean true if the line's tag is is a block level tag, false if not
*/
private function isBlock($line) {
return !in_array($line[self::HAML_TAG], $this->inlineTags);
}
/**
* Return a value indicating if the line's tag is self-closing.
* @param array line
* @return boolean true if the line's tag is self-closing, false if not
*/
private function isSelfClosing($line) {
return in_array($line[self::HAML_TAG], $this->emptyTags) || $line[self::HAML_TOKEN] == self::SELF_CLOSE_TAG;
}
/**
* Gets a filter.
* Filters are loaded on first use.
* @param string filter name
* @throws HamlException if the filter does not exist or does not extend HamlBaseFilter
*/
private function getFilter($filter) {
static $firstRun = true;
$imported = false;
if (empty($this->filters[$filter])) {
if ($firstRun) {
require_once 'filters/HamlBaseFilter.php';
$firstRun = false;
}
$filterclass = 'Haml' . ucfirst($filter) . 'Filter';
if (isset($this->filterDir)) {
$this->filterDir = substr($this->filterDir, -1) == DIRECTORY_SEPARATOR ? substr($this->filterDir, 0, -1) : $this->filterDir;
if (file_exists($this->filterDir . DIRECTORY_SEPARATOR . "{$filterclass}.php")) {
require_once $this->filterDir . DIRECTORY_SEPARATOR . "{$filterclass}.php";
$imported = true;
}
}
if (!$imported && file_exists(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'filters' . DIRECTORY_SEPARATOR . "{$filterclass}.php")) {
require_once "filters/{$filterclass}.php";
$imported = true;
}
if (!$imported) {
throw new HamlException('Unable to find {what}: {filename}', array(
'{what}' => $filter . ' filter',
'{filename}' => $filterclass . '.php',
), $this);
}
$this->filters[$filter] = new $filterclass();
if (!$this->filters[$filter] instanceof HamlBaseFilter) {
throw new HamlException('{what} must extend {base} class', array(
'{what}' => $filter,
'{base}' => 'HamlBaseFilter',
), $this);
}
$this->filters[$filter]
->init();
}
return $this->filters[$filter];
}
/**
* Gets the next line.
* @param array first line
* @return array the next line
*/
private function getMultiline($line) {
do {
$multiLine = array_shift($this->source);
$line[self::HAML_CONTENT] .= substr($multiLine[self::HAML_SOURCE], 0, -2);
} while (!empty($this->source) && $this
->isMultiline($this->source[0]));
return $line;
}
/**
* Parse attributes.
* @param array line to parse
* @return array attributes in name=>value pairs
*/
private function parseAttributes($line) {
$attributes = array();
if (!empty($line[self::HAML_OPEN_XML_ATTRIBUTES])) {
if (empty($line[self::HAML_XML_ATTRIBUTES])) {
$line[self::HAML_XML_ATTRIBUTES] = $line[self::HAML_CONTENT];
unset($line[self::HAML_CONTENT]);
do {
$multiLine = array_shift($this->source);
$line[self::HAML_XML_ATTRIBUTES] .= $multiLine[self::HAML_CONTENT];
} while (substr($line[self::HAML_XML_ATTRIBUTES], -1) !== self::CLOSE_XML_ATTRIBUTES);
}
if (preg_match(self::HTML_ATTRS, $line[self::HAML_XML_ATTRIBUTES], $htmlAttrs)) {
$line[self::HAML_XML_ATTRIBUTES] = preg_replace(self::HTML_ATTRS, '', $line[self::HAML_XML_ATTRIBUTES]);
$attributes = array_merge($attributes, $this
->htmlAttrs($htmlAttrs));
}
$attributes = array_merge($attributes, $this
->parseAttributeHash($line[self::HAML_XML_ATTRIBUTES]));
}
if (!empty($line[self::HAML_OPEN_RUBY_ATTRIBUTES])) {
if (empty($line[self::HAML_RUBY_ATTRIBUTES])) {
$line[self::HAML_RUBY_ATTRIBUTES] = $line[self::HAML_CONTENT];
unset($line[self::HAML_CONTENT]);
do {
$multiLine = array_shift($this->source);
$line[self::HAML_RUBY_ATTRIBUTES] .= $multiLine[self::HAML_CONTENT];
} while (substr($line[self::HAML_RUBY_ATTRIBUTES], -1) !== self::CLOSE_RUBY_ATTRIBUTES);
}
if (preg_match(self::HTML_ATTRS, $line[self::HAML_RUBY_ATTRIBUTES], $htmlAttrs)) {
$line[self::HAML_RUBY_ATTRIBUTES] = preg_replace(self::HTML_ATTRS, '', $line[self::HAML_RUBY_ATTRIBUTES]);
$attributes = array_merge($attributes, $this
->htmlAttrs($htmlAttrs));
}
$attributes = array_merge($attributes, $this
->parseAttributeHash($line[self::HAML_RUBY_ATTRIBUTES]));
}
if (!empty($line[self::HAML_OBJECT_REFERENCE])) {
$objectRef = explode(',', preg_replace('/,\\s*/', ',', $line[self::HAML_OBJECT_REFERENCE]));
$prefix = isset($objectRef[1]) ? $objectRef[1] . '_' : '';
$class = "strtolower(str_replace(' ',\t'_', preg_replace('/(?<=\\w)([ A-Z])/', '_\1', get_class(" . $objectRef[0] . '))))';
$attributes['class'] = "<?php echo '{$prefix}' . {$class}; ?>";
$attributes['id'] = "<?php echo '{$prefix}' . {$class} . '_' . {$objectRef[0]}->id; ?>";
}
else {
if (!empty($line[self::HAML_CLASS])) {
$classes = explode('.', $line[self::HAML_CLASS]);
foreach ($classes as &$class) {
if (preg_match(self::MATCH_INTERPOLATION, $class)) {
$class = $this
->interpolate($class);
}
}
// foreach
$attributes['class'] = join(' ', $classes) . (isset($attributes['class']) ? " {$attributes['class']}" : '');
}
if (!empty($line[self::HAML_ID])) {
$attributes['id'] = (preg_match(self::MATCH_INTERPOLATION, $line[self::HAML_ID]) ? $this
->interpolate($line[self::HAML_ID]) : $line[self::HAML_ID]) . (isset($attributes['id']) ? "_{$attributes['id']}" : '');
}
}
ksort($attributes, SORT_STRING);
return $attributes;
}
/**
* Parse attributes.
* @param string the attributes
* @return array attributes in name=>value pairs
*/
private function parseAttributeHash($subject) {
$subject = substr($subject, 0, -1);
$attributes = array();
if (preg_match(self::REGEX_ATTRIBUTE_FUNCTION, $subject)) {
$attributes[0] = "<?php echo {$subject}; ?>";
return $attributes;
}
preg_match_all(self::REGEX_ATTRIBUTES, $subject, $attrs, PREG_SET_ORDER);
// print_r($attrs);
foreach ($attrs as $attr) {
if (!empty($attr[1])) {
// HTML5 Custom Data Attributes
$dataAttributes = $this
->parseAttributeHash(substr($attr[2], 1));
foreach ($dataAttributes as $key => $value) {
$attributes["data-{$key}"] = $value;
}
// foreach
}
elseif (!empty($attr[4])) {
$values = array_map('trim', explode(',', $attr[4]));
if ($attr[3] !== 'class' && $attr[3] !== 'id') {
throw new HamlException('Attribute must be "class" or "id" with array value', array(), $this);
}
$attributes[$attr[3]] = '<?php echo ' . join($attr[3] === 'id' ? ".'_'." : ".' '.", $values) . '; ?>';
}
elseif (!empty($attr[6])) {
$attributes[$attr[3]] = $this
->interpolate($attr[6], $attr[3]);
}
else {
switch ($attr[7]) {
case 'true':
$attributes[$attr[3]] = $attr[3];
break;
case 'false':
break;
case '':
$attributes[$attr[3]] = "";
break;
default:
$attributes[$attr[3]] = "<?php echo {$attr[7]}; ?>";
break;
}
}
}
// foreach
return $attributes;
}
/**
* Returns an array of attributes for the html element.
* @param array arguments for HamlHelpers::html_attrs
* @return array attributes for the html element
*/
private function htmlAttrs($htmlAttrs) {
if (empty($htmlAttrs[1]) && empty($htmlAttrs[2])) {
return HamlHelpers::html_attrs();
}
else {
$htmlAttrs[1] = substr($htmlAttrs[1], 1, -1);
if (substr($htmlAttrs[1], -1) == ';') {
$htmlAttrs[1] = eval("return {$htmlAttrs[1]}");
}
if (isset($htmlAttrs[2])) {
return HamlHelpers::html_attrs($htmlAttrs[1], eval($htmlAttrs[2] . ';'));
}
else {
return HamlHelpers::html_attrs($htmlAttrs[1]);
}
}
}
/**
* Parse code
* @param array line to parse
* @param HamlNode parent node
* @return HamlCodeBlockNode
*/
private function parseCode($line, $parent) {
if (preg_match('/^(if|foreach|for|switch|do|while)\\b(.*)$/', $line[self::HAML_CONTENT], $block)) {
if ($block[1] === 'do') {
$node = new HamlCodeBlockNode('<?php do { ?>', $parent);
$node->doWhile = 'while' . $block[2] . ';';
}
elseif ($block[1] === 'switch') {
$node = new HamlCodeBlockNode("<?php {$line[self::HAML_CONTENT]} {", $parent);
}
else {
$node = new HamlCodeBlockNode("<?php {$line[self::HAML_CONTENT]} { ?>", $parent);
}
}
elseif (strpos($line[self::HAML_CONTENT], 'else') === 0) {
$node = new HamlCodeBlockNode("<?php } {$line[self::HAML_CONTENT]} { ?>", null);
$node->token = $line;
$node->showOutput = $this->showOutput;
$node->showSource = $this->showSource;
$parent
->getLastChild()
->addElse($node);
$this
->addChildren($node, $line);
$node = null;
}
elseif (strpos($line[self::HAML_CONTENT], 'case') === 0) {
$node = new HamlNode(($parent
->hasChildren() ? '<?php ' : '') . "{$line[self::HAML_CONTENT]}: ?>", $parent);
}
else {
$node = new HamlNode("<?php {$line[self::HAML_CONTENT]}; ?>", $parent);
}
return $node;
}
/**
* Parse content
* @param array line to parse
* @param HamlNode parent node
* @return HamlNode
*/
private function parseContent($line, $parent) {
switch ($line[self::HAML_TOKEN]) {
case self::INSERT_CODE:
$content = $this->suppressEval ? '' : '<?php echo ' . ($this->escapeHtml ? 'htmlentities(' . $line[self::HAML_CONTENT] . ')' : $line[self::HAML_CONTENT]) . "; ?>" . ($this->style == HamlRenderer::STYLE_EXPANDED || $this->style == HamlRenderer::STYLE_NESTED ? "\n" : '');
break;
case self::INSERT_CODE_PRESERVE_WHITESPACE:
$content = $this->suppressEval ? '' : '<?php echo str_replace("\\n", \'
\', ' . ($this->escapeHtml ? 'htmlentities(' . $line[self::HAML_CONTENT] . ')' : $line[self::HAML_CONTENT]) . "; ?>" . ($this->style == HamlRenderer::STYLE_EXPANDED || $this->style == HamlRenderer::STYLE_NESTED ? "\n" : '');
break;
case self::UNESCAPE_XML:
$content = $this->suppressEval ? '' : '<?php echo ' . $line[self::HAML_CONTENT] . "; ?>" . ($this->style == HamlRenderer::STYLE_EXPANDED || $this->style == HamlRenderer::STYLE_NESTED ? "\n" : '');
break;
case self::ESCAPE_XML:
$content = $this->suppressEval ? '' : '<?php echo ' . ('htmlentities(' . $line[self::HAML_CONTENT] . ')') . "; ?>" . ($this->style == HamlRenderer::STYLE_EXPANDED || $this->style == HamlRenderer::STYLE_NESTED ? "\n" : '');
break;
default:
$content = $line[self::HAML_CONTENT];
break;
}
// switch
return new HamlNode($this
->interpolate($content), $parent);
}
/**
* Parse a directive.
* Various options are set according to the directive
* @param array line to parse
* @return null
*/
private function parseDirective($line) {
preg_match('/(\\w+)(\\+|-)?/', $line[self::HAML_CONTENT], $matches);
switch ($matches[1]) {
case 's':
$this->showSource = $matches[2] == '+' ? true : ($matches[2] == '-' ? false : $this->showSource);
break;
case 'o':
$this->showOutput = $matches[2] == '+' ? true : ($matches[2] == '-' ? false : $this->showOutput);
break;
case 'os':
case 'so':
$this->showSource = $matches[2] == '+' ? true : ($matches[2] == '-' ? false : $this->showSource);
$this->showOutput = $matches[2] == '+' ? true : ($matches[2] == '-' ? false : $this->showOutput);
break;
default:
if (!in_array($matches[1], $this->styles)) {
throw new HamlException('Invalid {what} ({value})', array(
'{what}' => 'directive',
'{value}' => self::DIRECTIVE . $matches[0],
), $this);
}
$this->style = $matches[1];
break;
}
// switch
}
/**
* Parse a doctype declaration
* @param array line to parse
* @param HamlNode parent node
* @return HamlDoctypeNode
*/
private function parseDoctype($line, $parent) {
$content = explode(' ', $line[self::HAML_CONTENT]);
if (!empty($content)) {
if ($content[0] === self::IS_XML_PROLOG) {
$encoding = isset($content[1]) ? $content[1] : self::DEFAULT_XML_ENCODING;
$output = str_replace(self::XML_ENCODING, $encoding, self::XML_PROLOG);
}
elseif (empty($content[0])) {
$output = $this->doctypes[$this->format][0];
}
elseif (array_key_exists($content[0], $this->doctypes[$this->format])) {
$output = $this->doctypes[$this->format][$content[0]];
}
elseif (!empty($this->doctype)) {
$output = $this->doctype;
}
else {
$_doctypes = array_keys($this->doctypes[$this->format]);
array_shift($_doctypes);
throw new HamlException('Invalid {what} ({value}); must be one of "{options}"', array(
'{what}' => 'doctype',
'{value}' => $content[0],
'{options}' => join(', ', $_doctypes) . ' or empty',
), $this);
}
}
return new HamlDoctypeNode($output, $parent);
}
/**
* Parse a Haml comment.
* If the comment is an empty comment eat all child lines.
* @param array line to parse
*/
private function parseHamlComment($line) {
if (!$this
->hasContent($line)) {
while ($this
->hasChild($line, true)) {
array_shift($this->source);
$this->line++;
}
}
}
/**
* Parse a HamlHelper.
* @param array line to parse
* @param HamlNode parent node
* @return HamlHelperNode
*/
private function parseHelper($line, $parent) {
preg_match(HamlHelperNode::MATCH, $line[self::HAML_CONTENT], $matches);
$node = new HamlHelperNode($this->helperClass, $matches[HamlHelperNode::PRE], $matches[HamlHelperNode::NAME], $matches[HamlHelperNode::ARGS], $parent);
if (isset($matches[HamlHelperNode::BLOCK])) {
new HamlNode($matches[HamlHelperNode::BLOCK], $node);
}
return $node;
}
/**
* Parse an element.
* @param array line to parse
* @param HamlNode parent node
* @return HamlElementNode tag node and children
*/
private function parseElement($line, $parent) {
$node = new HamlElementNode($line[self::HAML_TAG], $parent);
$node->isSelfClosing = $this
->isSelfClosing($line);
$node->isBlock = $this
->isBlock($line);
$node->attributes = $this
->parseAttributes($line);
if ($this
->hasContent($line)) {
$child = $this
->parseContent($line, $node);
$child->showOutput = $this->showOutput;
$child->showSource = $this->showSource;
$child->token = array(
self::HAML_SOURCE => $line[self::HAML_SOURCE],
'filename' => $line['filename'],
'line' => $line['line'],
'level' => $line['level'] + 1,
);
}
$node->whitespaceControl = $this
->parseWhitespaceControl($line);
return $node;
}
/**
* Parse a filter.
* @param array line to parse
* @param HamlNode parent node
* @return HamlNode filter node
*/
private function parseFilter($line, $parent) {
$node = new HamlFilterNode($this
->getFilter($line[self::HAML_FILTER]), $parent);
if ($this
->hasContent($line)) {
$child = $this
->parseContent($line);
$child->showOutput = $this->showOutput;
$child->showSource = $this->showSource;
$child->token = array(
'level' => $line['level'] + 1,
'line' => $line['line'],
);
}
return $node;
}
/**
* Parse an Xml comment.
* @param array line to parse
* @param HamlNode parent node
* @return HamlCommentNode
*/
private function parseXmlComment($line, $parent) {
return new HamlCommentNode($line[self::HAML_CONTENT], $parent);
}
private function parseWhitespaceControl($line) {
$whitespaceControl = array(
'inner' => false,
'outer' => array(
'left' => false,
'right' => false,
),
);
if (!empty($line[self::HAML_WHITESPACE_REMOVAL])) {
$whitespaceControl['inner'] = strpos($line[self::HAML_WHITESPACE_REMOVAL], self::INNER_WHITESPACE_REMOVAL) !== false;
if (strpos($line[self::HAML_WHITESPACE_REMOVAL], self::OUTER_WHITESPACE_REMOVAL) !== false) {
$whitespaceControl['outer']['left'] = strpos($line[self::HAML_WHITESPACE_REMOVAL], self::BLOCK_LEFT_OUTER_WHITESPACE_REMOVAL) === false;
$whitespaceControl['outer']['right'] = strpos($line[self::HAML_WHITESPACE_REMOVAL], self::BLOCK_RIGHT_OUTER_WHITESPACE_REMOVAL) === false;
}
}
return $whitespaceControl;
}
/**
* Replace interpolated PHP contained in '#{}'.
* @param string the text to interpolate
* @return string the interpolated text
*/
protected function interpolate($string, $type = '') {
return preg_replace(self::MATCH_INTERPOLATION, in_array($type, $this->minimizedAttributes) ? '\\1' : self::INTERPOLATE, $string);
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
HamlParser:: |
private | property | * * of this type within attributes will be escaped (e.g. by replacing them with * ') if the character is an apostrophe or a quotation mark. * Defaults to " (an quotation mark). | |
HamlParser:: |
private | property | * * no debug, show source, show output, or show all. * Debug settings can be controlled in the template * Defaults to DEBUG_NONE. | |
HamlParser:: |
private | property | * * Haml Document is not a built in Doctype this will be used as the Doctype. * This allows Haml to be used for non-(X)HTML documents that are XML compliant. * * * * | |
HamlParser:: |
private | property | * * * | |
HamlParser:: |
private | property | * * if they have no content. | |
HamlParser:: |
private | property | * * If this is true, = behaves like &=; otherwise, it behaves like !=. * Note that if this is set, != should be used for yielding to subtemplates * and rendering partials. Defaults to false. | |
HamlParser:: |
private | property | * | |
HamlParser:: |
private | property | * * specified this dirctory will be searched before PHamlP looks for the filter * in it's collection. This allows the default filters to be overridden and * new filters to be installed. Note: No trailing directory separator. | |
HamlParser:: |
private | property | * | |
HamlParser:: |
private | property | * * rendered. * | |
HamlParser:: |
private | property | * | |
HamlParser:: |
private | property | * | |
HamlParser:: |
private | property | * * | |
HamlParser:: |
private | property | * | |
HamlParser:: |
private | property | * * Used on source if {@link indentChar} is space. * Used on output if {@link ugly} is false. | |
HamlParser:: |
private | property | * | |
HamlParser:: |
private | property | * | |
HamlParser:: |
private | property | * | |
HamlParser:: |
private | property | * | |
HamlParser:: |
private | property | * | |
HamlParser:: |
private | property | * * ugly mode comments are always output. Defaults to false. | |
HamlParser:: |
private | property | * | |
HamlParser:: |
private | property | * | |
HamlParser:: |
private | property | * | |
HamlParser:: |
private | property | * | |
HamlParser:: |
private | property | * * nested: output is nested according to the indent level in the source * expanded: block tags have their own lines as does content which is indented * compact: block tags and their content go on one line * compressed: all unneccessary… | |
HamlParser:: |
private | property | = or ~ should be evaluated. If true, the scripts are rendered as empty strings. Defaults to false. | |
HamlParser:: |
private | property | * * the output. Reduces size of output file but is not very readable; * equivalent of style == compressed. Note: ugly must be false to allow style. * Defaults to true. * | |
HamlParser:: |
private | function | * Adds children to a node if the current line has children. * | |
HamlParser:: |
constant | |||
HamlParser:: |
constant | |||
HamlParser:: |
private | function | * Builds a parse tree under the parent node. * | |
HamlParser:: |
constant | |||
HamlParser:: |
constant | |||
HamlParser:: |
constant | |||
HamlParser:: |
constant | |||
HamlParser:: |
constant | |||
HamlParser:: |
constant | |||
HamlParser:: |
constant | |||
HamlParser:: |
constant | |||
HamlParser:: |
constant | |||
HamlParser:: |
constant | |||
HamlParser:: |
public | function | ||
HamlParser:: |
private | function | * Gets a filter. * Filters are loaded on first use. * | |
HamlParser:: |
private | function | * Returns the indent level of the line. * | |
HamlParser:: |
public | function | ||
HamlParser:: |
private | function | * Gets the next line. * | |
HamlParser:: |
private | function | * Gets the next line. * | |
HamlParser:: |
public | function | ||
HamlParser:: |
public | function | * Parses a Haml file into PHP. * | |
HamlParser:: |
constant | |||
HamlParser:: |
constant | |||
HamlParser:: |
constant | |||
HamlParser:: |
constant | |||
HamlParser:: |
constant | |||
HamlParser:: |
constant | |||
HamlParser:: |
constant | |||
HamlParser:: |
constant | |||
HamlParser:: |
constant | |||
HamlParser:: |
constant | |||
HamlParser:: |
constant | |||
HamlParser:: |
constant | |||
HamlParser:: |
constant | |||
HamlParser:: |
constant | |||
HamlParser:: |
constant | |||
HamlParser:: |
constant | |||
HamlParser:: |
constant | |||
HamlParser:: |
private | function | * Returns a value indicating if the next line is a child of the parent line * | |
HamlParser:: |
private | function | * Return a value indicating if the line has content. * | |
HamlParser:: |
private | function | * Returns an array of attributes for the html element. * | |
HamlParser:: |
constant | |||
HamlParser:: |
constant | |||
HamlParser:: |
constant | |||
HamlParser:: |
constant | |||
HamlParser:: |
protected | function | * Replace interpolated PHP contained in '#{}'. * | |
HamlParser:: |
constant | |||
HamlParser:: |
private | function | * Return a value indicating if the line's tag is a block level tag. * | |
HamlParser:: |
private | function | * Returns a value indicating if $line is a child of a node. * A blank line is a child of a node. * | |
HamlParser:: |
private | function | * Return a value indicating if the line is code to be run. * | |
HamlParser:: |
private | function | * Return a value indicating if the line is a directive. * | |
HamlParser:: |
private | function | * Return a value indicating if the line is a doctype. * | |
HamlParser:: |
private | function | * Return a value indicating if the line is an element. * Will set the tag to div if it is an implied div. * | |
HamlParser:: |
private | function | * Return a value indicating if the line starts a filter. * | |
HamlParser:: |
private | function | * Return a value indicating if the line is a Haml comment. * | |
HamlParser:: |
private | function | * Return a value indicating if the line is a HamlHelper. * | |
HamlParser:: |
private | function | * Returns a value indicating whether the line is part of a multilne group * | |
HamlParser:: |
private | function | * Return a value indicating if the line's tag is self-closing. * | |
HamlParser:: |
private | function | * Return a value indicating if the line is an XML comment. * | |
HamlParser:: |
constant | |||
HamlParser:: |
constant | |||
HamlParser:: |
constant | |||
HamlParser:: |
constant | |||
HamlParser:: |
constant | |||
HamlParser:: |
constant | |||
HamlParser:: |
constant | |||
HamlParser:: |
public | function | * Parses a Haml file. * If an output directory is given the resulting PHP is cached. * | |
HamlParser:: |
private | function | * Parse attributes. * | |
HamlParser:: |
private | function | * Parse attributes. * | |
HamlParser:: |
private | function | * Parse code * | |
HamlParser:: |
private | function | * Parse content * | |
HamlParser:: |
private | function | * Parse a directive. * Various options are set according to the directive * | |
HamlParser:: |
private | function | * Parse a doctype declaration * | |
HamlParser:: |
private | function | * Parse an element. * | |
HamlParser:: |
private | function | * Parse a filter. * | |
HamlParser:: |
private | function | * Parse a Haml comment. * If the comment is an empty comment eat all child lines. * | |
HamlParser:: |
private | function | * Parse a HamlHelper. * | |
HamlParser:: |
private | function | * Parse a line of Haml into a HamlNode for the document tree * | |
HamlParser:: |
private | function | ||
HamlParser:: |
private | function | * Parse an Xml comment. * | |
HamlParser:: |
constant | |||
HamlParser:: |
constant | |||
HamlParser:: |
constant | |||
HamlParser:: |
constant | |||
HamlParser:: |
constant | |||
HamlParser:: |
constant | |||
HamlParser:: |
constant | |||
HamlParser:: |
private | function | * Determine the indent character and indent spaces. * The first character of the first indented line determines the character. * If this is a space the number of spaces determines the indentSpaces; this * is always 1 if the indent character is a… | |
HamlParser:: |
constant | |||
HamlParser:: |
private | function | * Parse Haml source into a document tree. * | |
HamlParser:: |
constant | |||
HamlParser:: |
constant | |||
HamlParser:: |
constant | |||
HamlParser:: |
constant | |||
HamlParser:: |
public | function | * HamlParser constructor. * | |
HamlParser:: |
public | function | * Getter. * |