Completed
Pull Request — master (#5)
by
unknown
03:01
created

LaTeXFormatter::getStyle()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 4
ccs 0
cts 2
cp 0
crap 2
rs 10
c 1
b 0
f 0
1
<?php
2
/**
3
 * Highlighter
4
 *
5
 * Copyright (C) 2016, Some right reserved.
6
 *
7
 * @author Kacper "Kadet" Donat <[email protected]>
8
 *
9
 * Contact with author:
10
 * Xmpp:   [email protected]
11
 * E-mail: [email protected]
12
 *
13
 * From Kadet with love.
14
 */
15
16
namespace Kadet\Highlighter\Formatter;
17
18
use Kadet\Highlighter\Parser\Token\Token;
19
use Kadet\Highlighter\Parser\Tokens;
20
use Kadet\Highlighter\Utils\ArrayHelper;
21
22
/**
23
 * Class LateXFormatter
24
 *
25
 * @package Kadet\Highlighter\Formatter
26
 */
27
class LaTeXFormatter implements FormatterInterface
28
{
29
    private $_styles;
30
31 1
    public function __construct($styles = false)
32
    {
33 1
        $this->_styles = $styles ?: include __DIR__.'/../Styles/LaTeX/Default.php';
34 1
    }
35
36 View Code Duplication
    public function format(Tokens $tokens)
37
    {
38
        $source = $tokens->getSource();
39
40
        $result = '';
41
        $last   = 0;
42
43
        /** @var Token $token */
44
        foreach ($tokens as $token) {
45
            $result .= sprintf(
46
                '%s%s',
47
                $this->escape(substr($source, $last, $token->pos - $last)),
48
                $token->isStart() ? $this->getOpenTag($token) : $this->getCloseTag($token));
49
50
            $last = $token->pos;
51
        }
52
        $result .= substr($source, $last);
53
54
        return $result;
55
    }
56
57
    protected function escape($token)
58
    {
59
        $replace = [
60
            '\\' => '\\textbackslash{}',
61
            '{' => '\\{',
62
            '}' => '\\}',
63
            // When there is a \ in the source, it gets translated to
64
            // \textasciibackslash{}, but then the { and } are escaped to \{
65
            // and \}. This substitution reverts this.
66
            '\\textbackslash\\{\\}' => '\\textbackslash{}',
67
            '%' => '\\%',
68
            '_' => '\\_',
69
            '^' => '\\textasciicircum{}',
70
            '~' => '\\textasciitilde{}',
71
            '$' => '\\$',
72
            '&' => '\\&',
73
            '<' => '\\textless{}',
74
            '>' => '\\textgreater{}',
75
            '>' => '\\textgreater{}',
76
            // '"' => '\\textquotedbl{}',
77
            // '\'' => '\\char13{}',
78
        ];
79
80
        // We can do just with a simple str_replace() because PHP promises to
81
        // process them sequentially:
82
        // https://secure.php.net/manual/en/function.str-replace.php#refsect1-function.str-replace-parameters
83
        return str_replace(
84
            array_keys($replace),
85
            array_values($replace),
86
            $token
87
        );
88
    }
89
90
    protected function getOpenTag($token)
91
    {
92
        $result = '';
93
        $style = $this->getStyle($token);
94
95
        if (($color = ArrayHelper::resolve($style, 'color', 'default')) !== 'default') {
96
            $result = sprintf('\\textcolor{%s}{%s', $style['color'], $result);
97
        }
98
        if (ArrayHelper::resolve($style, 'bold', false)) {
99
            $result = sprintf('\\textbf{%s', $result);
100
        }
101
        if (ArrayHelper::resolve($style, 'italic', false)) {
102
            $result = sprintf('\\textit{%s', $result);
103
        }
104
105
        return $result;
106
    }
107
108
    protected function getCloseTag($token)
109
    {
110
        return str_repeat('}', count($this->getStyle($token)));
111
    }
112
113
    protected function getStyle($token)
114
    {
115
        return ArrayHelper::resolve($this->_styles, $token->name, []);
116
    }
117
}
118