Overview

Namespaces

  • Alpha
    • Controller
      • Front
    • Exception
    • Model
      • Type
    • Task
    • Util
      • Backup
      • Cache
      • Code
        • Highlight
        • Metric
      • Config
      • Convertor
      • Email
      • Extension
      • Feed
      • File
      • Graph
      • Helper
      • Http
        • Filter
        • Session
      • Image
      • Logging
      • Search
      • Security
    • View
      • Renderer
        • Html
        • Json
      • Widget

Classes

  • Markdown
  • MarkdownFacade
  • TCPDF
  • TCPDFFacade
  • Overview
  • Namespace
  • Class
  • Tree
  1: <?php
  2: 
  3: namespace Alpha\Util\Extension;
  4: 
  5: use Alpha\Util\Config\ConfigProvider;
  6: use Michelf\MarkdownExtra;
  7: use Alpha\Util\Code\Highlight\HighlightProviderFactory;
  8: 
  9: /**
 10:  * A custom version of the Markdown class which uses the geshi library for rendering code.
 11:  *
 12:  * @since 1.0
 13:  *
 14:  * @author John Collins <dev@alphaframework.org>
 15:  * @license http://www.opensource.org/licenses/bsd-license.php The BSD License
 16:  * @copyright Copyright (c) 2015, John Collins (founder of Alpha Framework).
 17:  * All rights reserved.
 18:  *
 19:  * <pre>
 20:  * Redistribution and use in source and binary forms, with or
 21:  * without modification, are permitted provided that the
 22:  * following conditions are met:
 23:  *
 24:  * * Redistributions of source code must retain the above
 25:  *   copyright notice, this list of conditions and the
 26:  *   following disclaimer.
 27:  * * Redistributions in binary form must reproduce the above
 28:  *   copyright notice, this list of conditions and the
 29:  *   following disclaimer in the documentation and/or other
 30:  *   materials provided with the distribution.
 31:  * * Neither the name of the Alpha Framework nor the names
 32:  *   of its contributors may be used to endorse or promote
 33:  *   products derived from this software without specific
 34:  *   prior written permission.
 35:  *
 36:  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 37:  * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 38:  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 39:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 40:  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
 41:  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 42:  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 43:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 44:  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 45:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 46:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 47:  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 48:  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 49:  * </pre>
 50:  */
 51: class Markdown extends MarkdownExtra
 52: {
 53:     /**
 54:      * Custom version of the _doCodeBlocks_callback method which invokes a Gheshi
 55:      * object to render code.
 56:      *
 57:      * @since 1.0
 58:      */
 59:     public function _doCodeBlocks_callback($matches)
 60:     {
 61:         $config = ConfigProvider::getInstance();
 62: 
 63:         $codeblock = $matches[1];
 64: 
 65:         $codeblock = $this->outdent($codeblock);
 66: 
 67:         // trim leading newlines and trailing whitespace
 68:         $codeblock = preg_replace(array('/\A\n+/', '/\n+\z/'), '', $codeblock);
 69: 
 70:         // find the code block and replace it with a blank
 71:         $codeTypeTag = array();
 72:         preg_match('/codeType=\[.*\]/', $codeblock, $codeTypeTag);
 73:         $codeblock = preg_replace('/codeType=\[.*\]\n/', '', $codeblock);
 74: 
 75:         if (isset($codeTypeTag[0])) {
 76:             $start = mb_strpos($codeTypeTag[0], '[');
 77:             $end = mb_strpos($codeTypeTag[0], ']');
 78:             $language = mb_substr($codeTypeTag[0], $start + 1, $end - ($start + 1));
 79:         } else {
 80:             // will use php as a default language type when none is provided
 81:             $language = 'php';
 82:         }
 83: 
 84:         if ($config->get('cms.highlight.provider.name') != '') {
 85:             $highlighter = HighlightProviderFactory::getInstance($config->get('cms.highlight.provider.name'));
 86:             $codeblock = $highlighter->highlight($codeblock, $language);
 87:         } else {
 88:             $codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES);
 89: 
 90:             # trim leading newlines and trailing newlines
 91:             $codeblock = preg_replace('/\A\n+|\n+\z/', '', $codeblock);
 92: 
 93:             $codeblock = "<pre><code>$codeblock\n</code></pre>";
 94:         }
 95: 
 96:         return "\n\n".$this->hashBlock($codeblock)."\n\n";
 97:     }
 98: 
 99:     /**
100:      * Custom _doAnchors_inline_callback that renders links to external sites with a
101:      * target attribute and an icon.
102:      *
103:      * @since 1.0
104:      */
105:     public function _doAnchors_inline_callback($matches)
106:     {
107:         $config = ConfigProvider::getInstance();
108: 
109:         $whole_match    =  $matches[1];
110:         $link_text      =  $this->runSpanGamut($matches[2]);
111:         $url            =  $matches[3] == '' ? $matches[4] : $matches[3];
112:         $title          =& $matches[7];
113:         $attr  = $this->doExtraAttributes("a", $dummy =& $matches[8]);
114: 
115:         $external = false;
116: 
117:         $parts = parse_url($url);
118: 
119:         /*
120:          * Only an external link if:
121:          *
122:          * 1. $url parses to a valid URL
123:          * 2. $url has a host part
124:          * 3. $url does not contain $config->get('app.url'), i.e. points to a local resource.
125:          */
126:         if (is_array($parts) && isset($parts['host']) && mb_strpos($url, $config->get('app.url')) === false) {
127:             $external = true;
128:         }
129: 
130:         $url = $this->encodeAttribute($url);
131: 
132:         $result = "<a href=\"$url\"";
133:         if (isset($title)) {
134:             $title = $this->encodeAttribute($title);
135:             $result .=  " title=\"$title\"";
136:         }
137:         if ($external) {
138:             $result .= " target=\"$url\"";
139:         }
140:         $result .= $attr;
141:         
142:         $link_text = $this->runSpanGamut($link_text);
143:         $result .= ">$link_text</a>";
144: 
145:         return $this->hashPart($result);
146:     }
147: 
148:     /**
149:      * Custom version of the _doTable_callback(...) method which sets the table border and CSS style.
150:      *
151:      * @since 1.0
152:      */
153:     public function _doTable_callback($matches)
154:     {
155:         $head       = $matches[1];
156:         $underline  = $matches[2];
157:         $content    = $matches[3];
158: 
159:         # Remove any tailing pipes for each line.
160:         $head       = preg_replace('/[|] *$/m', '', $head);
161:         $underline  = preg_replace('/[|] *$/m', '', $underline);
162:         $content    = preg_replace('/[|] *$/m', '', $content);
163:         
164:         # Reading alignement from header underline.
165:         $separators = preg_split('/ *[|] */', $underline);
166:         foreach ($separators as $n => $s) {
167:             if (preg_match('/^ *-+: *$/', $s))
168:                 $attr[$n] = $this->_doTable_makeAlignAttr('right');
169:             else if (preg_match('/^ *:-+: *$/', $s))
170:                 $attr[$n] = $this->_doTable_makeAlignAttr('center');
171:             else if (preg_match('/^ *:-+ *$/', $s))
172:                 $attr[$n] = $this->_doTable_makeAlignAttr('left');
173:             else
174:                 $attr[$n] = '';
175:         }
176:         
177:         # Parsing span elements, including code spans, character escapes, 
178:         # and inline HTML tags, so that pipes inside those gets ignored.
179:         $head       = $this->parseSpan($head);
180:         $headers    = preg_split('/ *[|] */', $head);
181:         $col_count  = count($headers);
182:         $attr       = array_pad($attr, $col_count, '');
183:         
184:         # Write column headers.
185:         $text = "<table class=\"table table-bordered\">\n";
186:         $text .= "<thead>\n";
187:         $text .= "<tr>\n";
188:         foreach ($headers as $n => $header)
189:             $text .= "  <th$attr[$n]>".$this->runSpanGamut(trim($header))."</th>\n";
190:         $text .= "</tr>\n";
191:         $text .= "</thead>\n";
192:         
193:         # Split content by row.
194:         $rows = explode("\n", trim($content, "\n"));
195:         
196:         $text .= "<tbody>\n";
197:         foreach ($rows as $row) {
198:             # Parsing span elements, including code spans, character escapes, 
199:             # and inline HTML tags, so that pipes inside those gets ignored.
200:             $row = $this->parseSpan($row);
201:             
202:             # Split row by cell.
203:             $row_cells = preg_split('/ *[|] */', $row, $col_count);
204:             $row_cells = array_pad($row_cells, $col_count, '');
205:             
206:             $text .= "<tr>\n";
207:             foreach ($row_cells as $n => $cell)
208:                 $text .= "  <td$attr[$n]>".$this->runSpanGamut(trim($cell))."</td>\n";
209:             $text .= "</tr>\n";
210:         }
211:         $text .= "</tbody>\n";
212:         $text .= "</table>";
213:         
214:         return $this->hashBlock($text) . "\n";
215:     }
216: }
217: 
Alpha Framework 2.0.4 API Documentation API documentation generated by ApiGen 2.8.0