Source of file KSSSection.php
Size: 19,854 Bytes - Last Modified: 2022-01-13T10:01:28+00:00
/var/www/docs.ssmods.com/process/src/code/model/KSSSection.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695 | <?php namespace BenManu\StyleGuide; use SilverStripe\ORM\ArrayList; class KSSSection extends Section { private static $casting = array( 'Title' => 'Varchar', 'Description' => 'HTMLText', 'Template' => 'HTMLText', 'Markup' => 'HTMLText', 'MarkupNormal' => 'HTMLText', 'Deprecated' => 'Varchar', 'Compatibility' => 'Varchar', 'Section' => 'Varchar', 'Reference' => 'Varchar' ); /** * Returns the title of the section * * @return string */ public function getTitle() { $title = ''; $titleComment = $this->getTitleComment(); if (preg_match('/^\s*#+\s*(.+)/', $titleComment, $matches)) { $title = $matches[1]; } elseif (self::isReferenceNumeric($this->getReference())) { return $this->getReference(); } else { $reference = $this->getReferenceParts(); return end($reference); } return $title; } /** * Returns the description for the section * * @return string */ public function getDescription() { $descriptionSections = array(); foreach ($this->getCommentSections() as $commentSection) { // Anything that is not the section comment or modifiers comment // must be the description comment if ($commentSection != $this->getReferenceComment() && $commentSection != $this->getTitleComment() && $commentSection != $this->getMarkupComment() && $commentSection != $this->getDeprecatedComment() && $commentSection != $this->getExperimentalComment() && $commentSection != $this->getCompatibilityComment() && $commentSection != $this->getModifiersComment() && $commentSection != $this->getParametersComment() && $commentSection != $this->getTemplateComment() && $commentSection != $this->getSectionTemplateComment() ) { $descriptionSections[] = $commentSection; } } $description = implode("\n\n", $descriptionSections); return \Parsedown::instance()->text($description); } /** * Returns the markup defined in the section * * @return string */ public function getMarkup() { if($markupComment = $this->getMarkupComment()) { return trim(preg_replace('/^\s*Markup:/i', '', $markupComment)); } } /** * Returns the markup for the normal element (without modifierclass) * * @param string $replacement Replacement for $modifierClass variable * @return void */ public function getMarkupNormal($replacement = '') { return str_replace('$modifierClass', $replacement, $this->getMarkup()); } /** * Returns a boolean value regarding the presence of markup in the kss-block * * @return boolean */ public function hasMarkup() { return $this->getMarkup() !== null; } /** * Returns the deprecation notice defined in the section * * @return string */ public function getDeprecated() { if ($deprecatedComment = $this->getDeprecatedComment()) { return trim(preg_replace('/^\s*Deprecated:/i', '', $deprecatedComment)); } } /** * Returns the experimental notice defined in the section * * @return string */ public function getExperimental() { if($experimentalComment = $this->getExperimentalComment()) { return trim(preg_replace('/^\s*Experimental:/i', '', $experimentalComment)); } } /** * Returns the compatibility notice defined in the section * * @return string */ public function getCompatibility() { if($compatibilityComment = $this->getCompatibilityComment()) { return trim($compatibilityComment); } } /** * Returns the modifiers used in the section * * @return array */ public function getModifiers() { $lastIndent = null; $modifiers = new ArrayList(); if($modiferComment = $this->getModifiersComment()) { $modifierLines = explode("\n", $modiferComment); foreach($modifierLines as $line) { if(empty($line)) { continue; } preg_match('/^\s*/', $line, $matches); $indent = strlen($matches[0]); if($lastIndent && $indent > $lastIndent) { $modifier = end($modifiers); $modifier->setDescription($modifier->getDescription() + trim($line)); } else { $lineParts = explode(' - ', $line); $name = trim(array_shift($lineParts)); $description = ''; if (!empty($lineParts)) { $description = trim(implode(' - ', $lineParts)); } $modifier = new KSSModifier($name, $description, $this); // If the CSS has a markup, pass it to the modifier for the example HTML // or else use the template if one is defined. if($markup = $this->getMarkup()) { $modifier->setMarkup($markup); } elseif($template = $this->getTemplate()) { $modifier->setMarkup($template); } $modifiers->push($modifier); } } } return $modifiers; } /** * Returns the $parameters used in the section * * @return array */ public function getParameters() { $lastIndent = null; $parameters = new ArrayList(); if($parameterComment = $this->getParametersComment()) { $parameterLines = explode("\n", $parameterComment); foreach($parameterLines as $line) { if(empty($line)) { continue; } $lineParts = explode(' - ', $line); $name = trim(array_shift($lineParts)); $description = ''; if(!empty($lineParts)) { $description = trim(implode(' - ', $lineParts)); } $parameter = new KSSParameter($name, $description, $this); $parameters->push($parameter); } } return $parameters; } /** * Returns the template if defined, rendered with the fixture or controller. * * @return HTMLText */ public function getTemplate() { $template = null; if($templateComment = $this->getTemplateComment()) { $template = trim(preg_replace('/^\s*Template:/i', '', $templateComment)); $template = $this->getRenderedTemplate($template); } return $template; } /** * Returns the section template if defined. * * @return HTMLText */ public function getSectionTemplate() { $template = null; if($templateComment = $this->getSectionTemplateComment()) { $template = trim(preg_replace('/^\s*SectionTemplate:/i', '', $templateComment)); } return $template; } /** * Returns the reference number for the section * * @param boolean $trimmed OPTIONAL * * @return string */ public function getReference($trimmed = false) { $reference = null; $referenceComment = $this->getReferenceComment(); $referenceComment = preg_replace('/\.$/', '', $referenceComment); if(preg_match('/^\s*Styleguide\s+(.*)/i', $referenceComment, $matches)) { $reference = trim($matches[1]); } return ($trimmed && $reference !== null) ? self::trimReference($reference) : $reference; } /** * Returns the reference dot delimited * * @return string */ protected function getReferenceDotDelimited() { return self::normalizeReference($this->getReference()); } /** * Checks if the Section has a reference * * @return boolean */ public function hasReference() { return $this->getReference() !== null; } /** * Checks to see if a reference is numeric * * @param string * * @return boolean */ public static function isReferenceNumeric($reference) { return !preg_match('/[^\d\.]/', $reference); } /** * Returns the references as an array of its parts * * @return array */ public function getReferenceParts() { return explode('.', $this->getReferenceDotDelimited()); } /** * Trims off all trailing zeros and periods on a reference * * @param string $reference * * @return string */ public static function trimReference($reference) { if (substr($reference, -1) == '.' || substr($reference, -1) == '-') { $reference = trim(substr($reference, 0, -1)); } while (preg_match('/(\.0+)$/', $reference, $matches)) { $reference = substr($reference, 0, strlen($matches[1]) * -1); } return $reference; } /** * Normalizes references so all delimiters are standardized * * @param string $reference * * @return string */ public static function normalizeReference($reference) { return preg_replace('/\s*-\s*/', '.', $reference); } /** * Checks to see if a section belongs to a specified reference * * @param string $reference * * @return boolean */ public function belongsToReference($reference) { $reference = self::trimReference($reference); $reference = self::normalizeReference($reference); return stripos($this->getReferenceDotDelimited() . '.', $reference . '.') === 0; } /** * Helper method for calculating the depth of the instantiated section * * @return int */ public function getDepth() { return self::calcDepth($this->getReferenceDotDelimited()); } /** * Calculates and returns the depth of a section reference * * @param string $reference * * @return int */ public static function calcDepth($reference) { $reference = self::trimReference($reference); $reference = self::normalizeReference($reference); return substr_count($reference, '.'); } /** * Helper method for calculating the score of the instantiated section * * @return int */ public function getDepthScore() { return self::calcDepthScore($this->getReferenceDotDelimited()); } /** * Calculates and returns the depth score for the section. Useful for sorting * sections correctly by their section reference numbers * * @return int|null */ public static function calcDepthScore($reference) { if (!self::isReferenceNumeric($reference)) { return null; } $reference = self::trimReference($reference); $sectionParts = explode('.', $reference); $score = 0; foreach ($sectionParts as $level => $part) { $score += $part * (1 / pow(10, $level)); } return $score; } /** * Function to help sort sections by depth and then depth score or alphabetically * * @param Section $a * @param Section $b * * @return int */ public static function depthSort(Section $a, Section $b) { if ($a->getDepth() == $b->getDepth()) { return self::alphaDepthScoreSort($a, $b); } return $a->getDepth() > $b->getDepth(); } /** * Function to help sort sections by their depth score * * @param Section $a * @param Section $b * * @return int */ public static function depthScoreSort(Section $a, Section $b) { return $a->getDepthScore() > $b->getDepthScore(); } /** * Function to help sort sections either by their depth score if numeric or * alphabetically if non-numeric. * * @param Section $a * @param Section $b * * @return int */ public static function alphaDepthScoreSort(Section $a, Section $b) { $aNumeric = self::isReferenceNumeric($a->getReference()); $bNumeric = self::isReferenceNumeric($b->getReference()); if($aNumeric && $bNumeric) { return self::depthScoreSort($a, $b); } elseif ($aNumeric) { return -1; } elseif ($bNumeric) { return 1; } else { return strnatcmp( $a->getReferenceDotDelimited(), $b->getReferenceDotDelimited() ); } } /** * Returns the comment block used when creating the section as an array of * paragraphs within the comment block * * @return array */ protected function getCommentSections() { return explode("\n\n", $this->rawComment); } /** * Gets the title part of the KSS Comment Block * * @return string */ protected function getTitleComment() { $titleComment = null; foreach ($this->getCommentSections() as $commentSection) { // Identify the title by the # markdown header syntax if (preg_match('/^\s*#/i', $commentSection)) { $titleComment = $commentSection; break; } } return $titleComment; } /** * Returns the part of the KSS Comment Block that contains the markup * * @return string */ protected function getMarkupComment() { $markupComment = null; foreach ($this->getCommentSections() as $commentSection) { // Identify the markup comment by the Markup: marker if (preg_match('/^\s*Markup:/i', $commentSection)) { $markupComment = $commentSection; break; } } return $markupComment; } /** * Returns the part of the KSS Comment Block that contains the deprecated * notice * * @return string */ protected function getDeprecatedComment() { $deprecatedComment = null; foreach ($this->getCommentSections() as $commentSection) { // Identify the deprecation notice by the Deprecated: marker if (preg_match('/^\s*Deprecated:/i', $commentSection)) { $deprecatedComment = $commentSection; break; } } return $deprecatedComment; } /** * Returns the part of the KSS Comment Block that contains the experimental * notice * * @return string */ protected function getExperimentalComment() { $experimentalComment = null; foreach ($this->getCommentSections() as $commentSection) { // Identify the experimental notice by the Experimental: marker if (preg_match('/^\s*Experimental:/i', $commentSection)) { $experimentalComment = $commentSection; break; } } return $experimentalComment; } /** * Returns the part of the KSS Comment Block that contains the compatibility * notice * * @return string */ protected function getCompatibilityComment() { $compatibilityComment = null; foreach ($this->getCommentSections() as $commentSection) { // Compatible in IE6+, Firefox 2+, Safari 4+. // Compatibility: IE6+, Firefox 2+, Safari 4+. // Compatibility untested. if (preg_match('/^\s*Compatib(le|ility):?\s+/i', $commentSection)) { $compatibilityComment = $commentSection; break; } } return $compatibilityComment; } /** * Gets the part of the KSS Comment Block that contains the section reference * * @return string */ protected function getReferenceComment() { $referenceComment = null; $commentSections = $this->getCommentSections(); $lastLine = end($commentSections); if (preg_match('/^\s*Styleguide \w/i', $lastLine) || preg_match('/^\s*No styleguide reference/i', $lastLine) ) { $referenceComment = $lastLine; } return $referenceComment; } /** * Returns the part of the KSS Comment Block that contains the modifiers * * @return string */ protected function getModifiersComment() { $modifiersComment = null; foreach ($this->getCommentSections() as $commentSection) { // Assume that the modifiers section starts with either a class or a // pseudo class if (preg_match('/^\s*(?:\.|:)/', $commentSection)) { $modifiersComment = $commentSection; break; } } return $modifiersComment; } /** * Returns the part of the KSS Comment Block that contains the $parameters * * @return string */ protected function getParametersComment() { $parametersComment = null; foreach ($this->getCommentSections() as $commentSection) { // Assume that the parameters section starts with $,%,@ if (preg_match('/^\s*(\$|@|%)/', $commentSection)) { $parametersComment = $commentSection; break; } } return $parametersComment; } /** * Returns the part of the KSS Comment Block that contains the template * * @return String */ protected function getTemplateComment() { $templateComment = null; foreach ($this->getCommentSections() as $commentSection) { // Assume that the parameters section starts with $,%,@ if (preg_match('/^\s*Template:/i', $commentSection)) { $templateComment = $commentSection; break; } } return $templateComment; } /** * Returns the part of the KSS Comment Block that contains the section template * * @return String */ protected function getSectionTemplateComment() { $templateComment = null; foreach ($this->getCommentSections() as $commentSection) { // Assume that the parameters section starts with $,%,@ if (preg_match('/^\s*SectionTemplate:/i', $commentSection)) { $templateComment = $commentSection; break; } } return $templateComment; } /** * Checks if the current section is the active route. * @return Boolean */ public function getActive() { return $this->request->param('Action') == $this->getReferenceID(); } /** * Get the section reference formatted for url use. * @return String */ public function getReferenceID() { return "section-" . str_replace(".", "-", $this->getReference()); } /** * Returns the link to this section formatted on the StyleGuideController. * @return String */ public function getLink() { return $this->getReferenceID(); } public function forTemplate() { $template = $this->getSectionTemplate(); if(!$template) { $template = __NAMESPACE__ . '\SGSection'; } return $this->renderWith($template); } } |