Warning, file /webapps/ocs-fileserver/library/Flooer/Utility/Element.php was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 <?php
0002 
0003 /**
0004  * Flooer Framework
0005  *
0006  * LICENSE: BSD License (2 Clause)
0007  *
0008  * @category    Flooer
0009  * @package     Flooer_Utility
0010  * @author      Akira Ohgaki <akiraohgaki@gmail.com>
0011  * @copyright   Akira Ohgaki
0012  * @license     https://opensource.org/licenses/BSD-2-Clause  BSD License (2 Clause)
0013  * @link        https://github.com/akiraohgaki/flooer
0014  */
0015 
0016 /**
0017  * Usage
0018  *
0019  * $xhtmlSource = Flooer_Utility_Element::convert($textSource);
0020  */
0021 
0022 /**
0023  * Element converter class that convert a plain text to a XHTML source
0024  *
0025  * @category    Flooer
0026  * @package     Flooer_Utility
0027  * @author      Akira Ohgaki <akiraohgaki@gmail.com>
0028  */
0029 class Flooer_Utility_Element
0030 {
0031 
0032     /**
0033      * Batch converting
0034      *
0035      * @param   string $source
0036      * @return  string
0037      */
0038     public static function convert($source)
0039     {
0040         $source = self::convertNewline($source);
0041         $source = self::convertSpecialchar($source);
0042         $source = self::convertInlineElement($source);
0043         $source = self::convertBlockElement($source);
0044         return $source;
0045     }
0046 
0047     /**
0048      * Convert a newline
0049      *
0050      * @param   string $source
0051      * @return  string
0052      */
0053     public static function convertNewline($source)
0054     {
0055         // Make a newline into LF
0056         return str_replace(array("\r\n", "\r"), "\n", $source);
0057     }
0058 
0059     /**
0060      * Convert a special character
0061      *
0062      * @param   string $source
0063      * @return  string
0064      */
0065     public static function convertSpecialchar($source)
0066     {
0067         // Encode a conflicted characters
0068         $encodeConflictChars = function ($matches) {
0069             return rawurlencode(stripslashes($matches[0]));
0070         };
0071         $source = preg_replace_callback(
0072             "/\"[^\"\n]+\"\<[^\>\n]+\>/",
0073             $encodeConflictChars,
0074             $source
0075         );
0076         $source = preg_replace_callback(
0077             "/\"[^\"\n]+\"\{[^\}\n]+\}\<[^\>\n]+\>/",
0078             $encodeConflictChars,
0079             $source
0080         );
0081         $source = preg_replace_callback(
0082             "/\"[^\"\n]+\"\{[^\}\n]+\}/",
0083             $encodeConflictChars,
0084             $source
0085         );
0086         $source = preg_replace_callback(
0087             "/\"[^\"\n]+\"\([^\)\n]+\)/",
0088             $encodeConflictChars,
0089             $source
0090         );
0091         $source = str_replace("\n>", "\n" . rawurlencode('>'), $source);
0092         // Make a characters into a character-entity
0093         $source = str_replace("\t", '    ', $source); // tab to 4 spaces
0094         $source = str_replace('&', '&amp;', $source);
0095         $source = str_replace('"', '&quot;', $source);
0096         $source = str_replace("'", '&#039;', $source);
0097         $source = str_replace('<', '&lt;', $source);
0098         $source = str_replace('>', '&gt;', $source);
0099         $source = str_ireplace('(C)', '&copy;', $source);
0100         $source = str_ireplace('(R)', '&reg;', $source);
0101         $source = str_ireplace('(TM)', '&trade;', $source);
0102         // Decode a conflicted characters
0103         $source = rawurldecode($source);
0104         return $source;
0105     }
0106 
0107     /**
0108      * Convert an inline element
0109      *
0110      * @param   string $source
0111      * @return  string
0112      */
0113     public static function convertInlineElement($source)
0114     {
0115         // Anchor
0116         // "title"<uri>
0117         $source = preg_replace(
0118             "/\"([^\"\n]+)\"\<([^\>\n]+)\>/",
0119             "<a href=\"$2\" title=\"$1\">$1</a>",
0120             $source
0121         );
0122         // Image Anchor
0123         // "title"{image-uri}<uri>
0124         $source = preg_replace(
0125             "/\"([^\"\n]+)\"\{([^\}\n]+)\}\<([^\>\n]+)\>/",
0126             "<a href=\"$3\" title=\"$1\"><img src=\"$2\" alt=\"$1\" /></a>",
0127             $source
0128         );
0129         // Image
0130         // "title"{image-uri}
0131         $source = preg_replace(
0132             "/\"([^\"\n]+)\"\{([^\}\n]+)\}/",
0133             "<img src=\"$2\" alt=\"$1\" />",
0134             $source
0135         );
0136         // Abbreviation
0137         // "abbr"(Abbreviation)
0138         $source = preg_replace(
0139             "/\"([^\"\n]+)\"\(([^\)\n]+)\)/",
0140             "<abbr title=\"$2\">$1</abbr>",
0141             $source
0142         );
0143         // Strong Emphasis
0144         // ***strong***
0145         $source = preg_replace(
0146             "/\*\*\*([^\*\n]+)\*\*\*/",
0147             "<strong>$1</strong>",
0148             $source
0149         );
0150         // Emphasis
0151         // **em**
0152         $source = preg_replace(
0153             "/\*\*([^\*\n]+)\*\*/",
0154             "<em>$1</em>",
0155             $source
0156         );
0157         // Subscript
0158         // ~~sub~~
0159         $source = preg_replace(
0160             "/\~\~([^\~\n]+)\~\~/",
0161             "<sub>$1</sub>",
0162             $source
0163         );
0164         // Superscript
0165         // ^^sup^^
0166         $source = preg_replace(
0167             "/\^\^([^\^\n]+)\^\^/",
0168             "<sup>$1</sup>",
0169             $source
0170         );
0171         // Insert
0172         // ++ins++
0173         $source = preg_replace(
0174             "/\+\+([^\+\n]+)\+\+/",
0175             "<ins>$1</ins>",
0176             $source
0177         );
0178         // Delete
0179         // --del--
0180         $source = preg_replace(
0181             "/\-\-([^\-\n]+)\-\-/",
0182             "<del>$1</del>",
0183             $source
0184         );
0185         return $source;
0186     }
0187 
0188     /**
0189      * Convert a block element
0190      *
0191      * @param   string $source
0192      * @return  string
0193      */
0194     public static function convertBlockElement($source)
0195     {
0196         $sourceLines = explode("\n", $source);
0197         $totalSourceLines = count($sourceLines);
0198         $isBlockContinueable = false;
0199         $isLineBreakable = false;
0200         for ($i = 0; $i < $totalSourceLines; $i++) {
0201             $sourceLines[$i] = rtrim($sourceLines[$i]);
0202             $n = $i + 1;
0203             if (!isset($sourceLines[$n])) {
0204                 $sourceLines[$n] = '';
0205             }
0206             // Blank line
0207             // Blank line is removes.
0208             if ($sourceLines[$i] == '') {
0209                 unset($sourceLines[$i]);
0210                 continue;
0211             }
0212             // Commentation
0213             // // Comment line 1
0214             // // Comment line 2
0215             // // Comment line 3
0216             // Comment line is removes.
0217             else if (preg_match("/^\/\//", $sourceLines[$i])) {
0218                 unset($sourceLines[$i]);
0219                 continue;
0220             }
0221             // Division
0222             // ******
0223             // ++++++
0224             // ------
0225             // "*/+/-" is 4 characters or more required.
0226             else if (preg_match("/^(\*|\+|\-){4,}$/", $sourceLines[$i])) {
0227                 $sourceLines[$i] = "</div>\n<div>";
0228                 $isBlockContinueable = false;
0229                 $isLineBreakable = false;
0230             }
0231             // Heading
0232             // = Heading 1 =
0233             // ====== Heading 6 ======
0234             // # Heading 1 #
0235             // ###### Heading 6 ######
0236             // Closing "=/#" is an option and not counted.
0237             else if (preg_match("/(^[\=\#]{1,6})[ \t]*(.*)/", $sourceLines[$i], $matches)) {
0238                 $matches[1] = strlen($matches[1]);
0239                 $matches[2] = preg_replace("/[ \t\=\#]*$/", '', $matches[2]);
0240                 $sourceLines[$i] = "<h{$matches[1]}>{$matches[2]}</h{$matches[1]}>";
0241                 $isBlockContinueable = false;
0242                 $isLineBreakable = false;
0243             }
0244             // Address
0245             // @ Address line 1
0246             // @ Address line 2
0247             // @ Address line 3
0248             else if (preg_match("/^\@[ \t]*(.*)/", $sourceLines[$i], $matches)) {
0249                 $sourceLines[$i] = $matches[1];
0250                 if (!$isBlockContinueable) {
0251                     $sourceLines[$i] = "<address>\n{$sourceLines[$i]}";
0252                     $isBlockContinueable = true;
0253                     $isLineBreakable = true;
0254                 }
0255                 if (!preg_match("/^\@/", $sourceLines[$n])) {
0256                     $sourceLines[$i] .= "\n</address>";
0257                     $isBlockContinueable = false;
0258                     $isLineBreakable = false;
0259                 }
0260             }
0261             // Preformatted Text
0262             // \sPreformatted Text line 1
0263             // \tPreformatted Text line 2
0264             // \s\tPreformatted Text line 3
0265             // "\s" is a space and "\t" is a tab.
0266             else if (preg_match("/^[ \t].*/", $sourceLines[$i])) {
0267                 if (!$isBlockContinueable) {
0268                     $sourceLines[$i] = "<pre>\n{$sourceLines[$i]}";
0269                     $isBlockContinueable = true;
0270                     $isLineBreakable = false;
0271                 }
0272                 if (!preg_match("/^[ \t]/", $sourceLines[$n])) {
0273                     $sourceLines[$i] .= "\n</pre>";
0274                     $isBlockContinueable = false;
0275                     $isLineBreakable = false;
0276                 }
0277             }
0278             // Block Quote
0279             // > Block Quote line 1
0280             // > Block Quote line 2
0281             // > Block Quote line 3
0282             else if (preg_match("/^\>[ \t]*(.*)/", $sourceLines[$i], $matches)) {
0283                 $sourceLines[$i] = $matches[1];
0284                 if (!$isBlockContinueable) {
0285                     $sourceLines[$i] = "<blockquote>\n{$sourceLines[$i]}";
0286                     $isBlockContinueable = true;
0287                     $isLineBreakable = true;
0288                 }
0289                 if (!preg_match("/^\>/", $sourceLines[$n])) {
0290                     $sourceLines[$i] .= "\n</blockquote>";
0291                     $isBlockContinueable = false;
0292                     $isLineBreakable = false;
0293                 }
0294             }
0295             // Ordered List
0296             // 1. Ordered List 1
0297             // 2. Ordered List 2
0298             // 3. Ordered List 3
0299             else if (preg_match("/(^[1-9][0-9]*)\.[ \t]*(.*)/", $sourceLines[$i], $matches)) {
0300                 $sourceLines[$i] = "<li>{$matches[2]}</li>";
0301                 if (!$isBlockContinueable) {
0302                     $sourceLines[$i] = "<ol start=\"{$matches[1]}\">\n{$sourceLines[$i]}";
0303                     $isBlockContinueable = true;
0304                     $isLineBreakable = false;
0305                 }
0306                 if (!preg_match("/^[1-9][0-9]*\./", $sourceLines[$n])) {
0307                     $sourceLines[$i] .= "\n</ol>";
0308                     $isBlockContinueable = false;
0309                     $isLineBreakable = false;
0310                 }
0311             }
0312             // Unordered List
0313             // * Unordered List 1
0314             // + Unordered List 2
0315             // - Unordered List 3
0316             else if (preg_match("/^[\*\+\-][ \t]*(.*)/", $sourceLines[$i], $matches)) {
0317                 $sourceLines[$i] = "<li>{$matches[1]}</li>";
0318                 if (!$isBlockContinueable) {
0319                     $sourceLines[$i] = "<ul>\n{$sourceLines[$i]}";
0320                     $isBlockContinueable = true;
0321                     $isLineBreakable = false;
0322                 }
0323                 if (!preg_match("/^[\*\+\-]+[^\*\+\-]+/", $sourceLines[$n])) {
0324                     $sourceLines[$i] .= "\n</ul>";
0325                     $isBlockContinueable = false;
0326                     $isLineBreakable = false;
0327                 }
0328             }
0329             // Definition List
0330             // | dl1 | Definition List 1
0331             // | dl2 | Definition List 2
0332             // | dl3 | Definition List 3
0333             else if (preg_match("/^\|[ \t]*(.*)\|[ \t]*(.*)/", $sourceLines[$i], $matches)) {
0334                 $matches[1] = rtrim($matches[1]);
0335                 $sourceLines[$i] = "<dt>{$matches[1]}</dt>\n<dd>{$matches[2]}</dd>";
0336                 if (!$isBlockContinueable) {
0337                     $sourceLines[$i] = "<dl>\n{$sourceLines[$i]}";
0338                     $isBlockContinueable = true;
0339                     $isLineBreakable = false;
0340                 }
0341                 if (!preg_match("/^\|.*\|/", $sourceLines[$n])) {
0342                     $sourceLines[$i] .= "\n</dl>";
0343                     $isBlockContinueable = false;
0344                     $isLineBreakable = false;
0345                 }
0346             }
0347             // Paragraph
0348             // A line without markup is a paragraph and separate as a blank line.
0349             else {
0350                 if (!$isBlockContinueable) {
0351                     $sourceLines[$i] = "<p>\n{$sourceLines[$i]}";
0352                     $isBlockContinueable = true;
0353                     $isLineBreakable = true;
0354                 }
0355                 if ($sourceLines[$n] == ''
0356                     || preg_match("/^([ \t\=\#\>\@\*\+\-]|[1-9][0-9]*\.|\|.*\|)/", $sourceLines[$n])
0357                 ) {
0358                     $sourceLines[$i] .= "\n</p>";
0359                     $isBlockContinueable = false;
0360                     $isLineBreakable = false;
0361                 }
0362             }
0363             // Line break
0364             if ($isLineBreakable) {
0365                 $sourceLines[$i] .= '<br />';
0366             }
0367         }
0368         // Enclosed with a div tag
0369         $source = "<div>\n" . implode("\n", $sourceLines) . "\n</div>";
0370         return $source;
0371     }
0372 
0373 }