Code

< 40 %
40-60 %
> 60 %
1
<?php
2
/**
3
 * @copyright Copyright (c) 2014 Carsten Brandt
4
 * @license https://github.com/cebe/markdown/blob/master/LICENSE
5
 * @link https://github.com/cebe/markdown#readme
6
 */
7
8
namespace cebe\markdown\latex;
9
10
use cebe\markdown\block\FencedCodeTrait;
11
use cebe\markdown\block\TableTrait;
12
use cebe\markdown\inline\StrikeoutTrait;
13
use cebe\markdown\inline\UrlLinkTrait;
14
15
/**
16
 * Markdown parser for github flavored markdown.
17
 *
18
 * - uses the [tabularx](http://www.ctan.org/pkg/tabularx) environment for tables.
19
 *
20
 * @author Carsten Brandt <[email protected]>
21
 */
22
class GithubMarkdown extends Markdown
23
{
24
	// include block element parsing using traits
25
	use TableTrait;
26
	use FencedCodeTrait;
27
28
	// include inline element parsing using traits
29
	use StrikeoutTrait;
30
	use UrlLinkTrait;
31
32
	/**
33
	 * @var boolean whether to interpret newlines as `<br />`-tags.
34
	 * This feature is useful for comments where newlines are often meant to be real new lines.
35
	 */
36
	public $enableNewlines = false;
37
38
	/**
39
	 * @inheritDoc
40
	 */
41
	protected $escapeCharacters = [
42
		// from Markdown
43
		'\\', // backslash
44
		'`', // backtick
45
		'*', // asterisk
46
		'_', // underscore
47
		'{', '}', // curly braces
48
		'[', ']', // square brackets
49
		'(', ')', // parentheses
50
		'#', // hash mark
51
		'+', // plus sign
52
		'-', // minus sign (hyphen)
53
		'.', // dot
54
		'!', // exclamation mark
55
		'<', '>',
56
		// added by GithubMarkdown
57
		':', // colon
58
		'|', // pipe
59
	];
60
61
62
	/**
63
	 * Consume lines for a paragraph
64
	 *
65
	 * Allow headlines, lists and code to break paragraphs
66
	 */
67 13
	protected function consumeParagraph($lines, $current)
68
	{
69
		// consume until newline
70 13
		$content = [];
71 13
		for ($i = $current, $count = count($lines); $i < $count; $i++) {
72 13
			$line = $lines[$i];
73 13
			if (!empty($line) && ltrim($line) !== '' &&
74 13
				!($line[0] === "\t" || $line[0] === " " && strncmp($line, '    ', 4) === 0) &&
75 13
				!$this->identifyHeadline($line, $lines, $i) &&
76 13
				!$this->identifyUl($line, $lines, $i) &&
77 13
				!$this->identifyOl($line, $lines, $i))
78 13
			{
79 13
				$content[] = $line;
80 13
			} else {
81 11
				break;
82
			}
83 13
		}
84
		$block = [
85 13
			'paragraph',
86 13
			'content' => $this->parseInline(implode("\n", $content)),
87 13
		];
88 13
		return [$block, --$i];
89
	}
90
91
	/**
92
	 * @inheritdoc
93
	 */
94 2
	protected function renderCode($block)
95
	{
96
		// make sure this is not replaced by the trait
97 2
		return parent::renderCode($block);
98
	}
99
100
	/**
101
	 * @inheritdoc
102
	 */
103 2
	protected function renderAutoUrl($block)
104
	{
105 2
		return '\url{' . $this->escapeUrl($block[1]) . '}';
106
	}
107
108
	/**
109
	 * @inheritdoc
110
	 */
111 1
	protected function renderStrike($block)
112
	{
113 1
		return '\sout{' . $this->renderAbsy($block[1]) . '}';
114
	}
115
116
	/**
117
	 * @inheritdocs
118
	 *
119
	 * Parses a newline indicated by two spaces on the end of a markdown line.
120
	 */
121 13
	protected function renderText($text)
122
	{
123 13
		if ($this->enableNewlines) {
124 1
			return preg_replace("/(  \n|\n)/", "\\\\\\\\\n", $this->escapeLatex($text[1]));
125
		} else {
126 13
			return parent::renderText($text);
127
		}
128
	}
129
130
	private $_tableCellHead = false;
131
	private $_tds = 0;
132
133 1
	protected function renderTable($block)
134
	{
135 1
		$align = [];
136 1
		foreach($block['cols'] as $col) {
137 1
			if (empty($col)) {
138 1
				$align[] = 'X';
139 1
			} else {
140 1
				$align[] = $col[0];
141
			}
142 1
		}
143 1
		$align = implode('|', $align);
144
145 1
		$content = '';
146 1
		$first = true;
147 1
		$numThs = 0;
148 1
		foreach($block['rows'] as $row) {
149 1
			$this->_tableCellHead = $first;
150 1
			$this->_tds = 0;
151 1
			$content .= $this->renderAbsy($this->parseInline($row)); // TODO move this to the consume step
152 1
			if ($first) {
153 1
				$numThs = $this->_tds;
154 1
			} else {
155 1
				while ($this->_tds < $numThs) {
156
					$content .= ' & ';
157
					$this->_tds++;
158
				}
159
			}
160 1
			$content .= "\\\\ \\hline\n";
161 1
			$first = false;
162 1
		}
163 1
		return "\n\\noindent\\begin{tabularx}{\\textwidth}{|$align|}\\hline\n$content\\end{tabularx}\n\n";
164
	}
165
166
	/**
167
	 * @marker |
168
	 */
169 1
	protected function parseTd($markdown)
170
	{
171 1
		if (isset($this->context[1]) && $this->context[1] === 'table') {
172 1
			$this->_tds++;
173 1
			return [['tableSep'], 1];
174
		}
175 1
		return [['text', $markdown[0]], 1];
176
	}
177
178 1
	protected function renderTableSep($block)
179
	{
180 1
		return '&';
181
	}
182
}
183