Completed
Push — master ( 6589e9...f70bf0 )
by Jitendra
9s
created

HtmlUp   A

Complexity

Total Complexity 32

Size/Duplication

Total Lines 149
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 60
dl 0
loc 149
rs 9.84
c 0
b 0
f 0
wmc 32

10 Methods

Rating   Name   Duplication   Size   Complexity  
A scan() 0 14 4
A parse() 0 15 3
A __toString() 0 3 1
A __construct() 0 3 1
A flush() 0 23 5
A quote() 0 15 4
A paragraph() 0 10 3
A raw() 0 9 5
A init() 0 13 2
A reset() 0 7 4
1
<?php
2
3
/*
4
 * This file is part of the HTMLUP package.
5
 *
6
 * (c) Jitendra Adhikari <[email protected]>
7
 *     <https://github.com/adhocore>
8
 *
9
 * Licensed under MIT license.
10
 */
11
12
namespace Ahc;
13
14
/**
15
 * HtmlUp - A **lightweight** && **fast** `markdown` to HTML Parser.
16
 *
17
 * Supports most of the markdown specs except deep nested elements.
18
 * Check readme.md for the details of its features && limitations.
19
 *
20
 * @author    adhocore | Jitendra Adhikari <[email protected]>
21
 * @copyright (c) 2014 Jitendra Adhikari
22
 */
23
class HtmlUp extends BlockElementParser
24
{
25
    /**
26
     * Constructor.
27
     *
28
     * @param string $markdown
29
     * @param int    $indentWidth
30
     */
31
    public function __construct($markdown = \null, $indentWidth = 4)
32
    {
33
        $this->scan($markdown, $indentWidth);
34
    }
35
36
    protected function scan($markdown, $indentWidth = 4)
37
    {
38
        if ('' === \trim($markdown)) {
39
            return;
40
        }
41
42
        $this->indentLen = $indentWidth == 2 ? 2 : 4;
43
        $this->indentStr = $indentWidth == 2 ? '  ' : '    ';
44
45
        // Normalize whitespaces
46
        $markdown = \str_replace("\t", $this->indentStr, $markdown);
47
        $markdown = \str_replace(["\r\n", "\r"], "\n", $markdown);
48
49
        $this->lines = \array_merge([''], \explode("\n", $markdown), ['']);
50
    }
51
52
    public function __toString()
53
    {
54
        return $this->parse();
55
    }
56
57
    /**
58
     * Parse markdown.
59
     *
60
     * @param string $markdown
61
     * @param int    $indentWidth
62
     *
63
     * @return string
64
     */
65
    public function parse($markdown = \null, $indentWidth = 4)
66
    {
67
        if (\null !== $markdown) {
68
            $this->reset(\true);
69
70
            $this->scan($markdown, $indentWidth);
71
        }
72
73
        if (empty($this->lines)) {
74
            return '';
75
        }
76
77
        $this->parseBlockElements();
78
79
        return (new SpanElementParser)->parse($this->markup);
80
    }
81
82
    protected function init()
83
    {
84
        list($this->prevLine, $this->trimmedPrevLine) = [$this->line, $this->trimmedLine];
85
86
        $this->line        = $this->lines[$this->pointer];
87
        $this->trimmedLine = \trim($this->line);
88
89
        $this->indent   = \strlen($this->line) - \strlen(\ltrim($this->line));
90
        $this->nextLine = isset($this->lines[$this->pointer + 1])
91
            ? $this->lines[$this->pointer + 1]
92
            : '';
93
        $this->trimmedNextLine = \trim($this->nextLine);
94
        $this->nextIndent      = \strlen($this->nextLine) - \strlen(\ltrim($this->nextLine));
95
    }
96
97
    protected function reset($all = \false)
98
    {
99
        $except = $all ? [] : \array_flip(['lines', 'pointer', 'markup', 'indentStr', 'indentLen']);
100
101
        // Reset all current values.
102
        foreach (\get_class_vars(__CLASS__) as $prop => $value) {
103
            isset($except[$prop]) || $this->{$prop} = $value;
104
        }
105
    }
106
107
    protected function flush()
108
    {
109
        if ('' !== $this->trimmedLine) {
110
            return \false;
111
        }
112
113
        while (!empty($this->stackList)) {
114
            $this->markup .= \array_pop($this->stackList);
115
        }
116
117
        while (!empty($this->stackBlock)) {
118
            $this->markup .= \array_pop($this->stackBlock);
119
        }
120
121
        while (!empty($this->stackTable)) {
122
            $this->markup .= \array_pop($this->stackTable);
123
        }
124
125
        $this->markup .= "\n";
126
127
        $this->reset(\false);
128
129
        return \true;
130
    }
131
132
    protected function raw()
133
    {
134
        if ($this->inHtml || \preg_match(static::RE_RAW, $this->trimmedLine)) {
135
            $this->markup .= "\n$this->line";
136
            if (!$this->inHtml && empty($this->lines[$this->pointer - 1])) {
137
                $this->inHtml = \true;
138
            }
139
140
            return \true;
141
        }
142
    }
143
144
    protected function quote()
145
    {
146
        if (\preg_match(static::RE_MD_QUOTE, $this->line, $quoteMatch)) {
147
            $this->line        = \substr($this->line, \strlen($quoteMatch[0]));
148
            $this->trimmedLine = \trim($this->line);
149
150
            if (!$this->inQuote || $this->quoteLevel < \strlen($quoteMatch[1])) {
151
                $this->markup .= "\n<blockquote>";
152
153
                $this->stackBlock[] = "\n</blockquote>";
154
155
                $this->quoteLevel++;
156
            }
157
158
            return $this->inQuote = \true;
159
        }
160
    }
161
162
    protected function paragraph()
163
    {
164
        $this->markup .= $this->inPara ? "\n<br />" : "\n<p>";
165
        $this->markup .= $this->trimmedLine;
166
167
        if (empty($this->trimmedNextLine)) {
168
            $this->markup .= '</p>';
169
            $this->inPara = \false;
170
        } else {
171
            $this->inPara = \true;
172
        }
173
    }
174
}
175