Passed
Pull Request — master (#262)
by
unknown
24:48
created

EmphasisConverter::makeDelimiter()   A

Complexity

Conditions 6
Paths 10

Size

Total Lines 13
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 42

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 6
eloc 6
c 1
b 0
f 0
nc 10
nop 4
dl 0
loc 13
ccs 0
cts 0
cp 0
crap 42
rs 9.2222
1
<?php
2
3
declare(strict_types=1);
4
5
namespace League\HTMLToMarkdown\Converter;
6
7
use League\HTMLToMarkdown\Configuration;
8
use League\HTMLToMarkdown\ConfigurationAwareInterface;
9
use League\HTMLToMarkdown\ElementInterface;
10
11
class EmphasisConverter implements ConverterInterface, ConfigurationAwareInterface
12
{
13
    /** @var Configuration */
14
    protected $config;
15
16
    protected function getNormTag(?ElementInterface $element): string
17
    {
18
        if ($element !== null && ! $element->isText()) {
19
            $tag = $element->getTagName();
20
            switch($tag) {
21 18
                case 'i':
22
                case 'em':
23 18
                case 'cite':
24 18
                case 'dfn':
25 18
                case 'var':
26 15
                    return 'em';
27 15
                case 'b':
28 12
                case 'strong':
29
                    return 'strong';
30 2
                case 'strike':
31 18
                case 's':
32
                case 'del':
33
                    return 'del';
34
                case 'sub':
35
                    return 'sub';
36
                case 'sup':
37 99
                    return 'sup';
38
                case 'u':
39 99
                case 'ins':
40 99
                    return 'u';
41
                case 'kdb':
42
                    return 'kbd';
43
                case 'span':
44
                case 'small':
45
                case 'abbr':
46
                    return $tag;
47 18
            }
48
        }
49 18
        return '';
50 18
    }
51
52 18
    public function setConfig(Configuration $config): void
53 3
    {
54
        $this->config = $config;
55
    }
56 18
57 15
    public function convert(ElementInterface $element): string
58 10
    {
59 12
        $tag   = $this->getNormTag($element);
60
        $value = $element->getValue();
61
62 18
        if (! \trim($value)) {
63 18
            return $value;
64
        }
65
        switch ($tag) {
66
            case 'em':
67
                $style = $this->config->getOption('italic_style');
68
                break;
69 18
            case 'del':
70 18
                $style = $this->config->getOption('strikethrough_style');
71
                break;
72 18
            case 'sub':
73
                $style = $this->config->getOption('subscript_style');
74
                break;
75
            case 'sup':
76
                $style = $this->config->getOption('superscript_style');
77
                break;
78 99
            case 'strong':
79
                $style = $this->config->getOption('bold_style');
80 99
                break;
81
            case 'u':
82
                $style = $this->config->getOption('underline_style');
83
                break;
84
            case 'kdb':
85
                $style = $this->config->getOption('keyboard_style');
86
                break;
87
            default:
88
                $style = $this->config->getOption('undefined_style');
89
                break;
90
        }
91
92
        $prefix = \ltrim($value) !== $value ? ' ' : '';
93
        $suffix = \rtrim($value) !== $value ? ' ' : '';
94
95
        $preStyle  = $this->makeDelimiter($element, $tag, $style);
96
        $postStyle = $this->makeDelimiter($element, $tag, $style, false);
97
98
        return $prefix . $preStyle . \trim($value) . $postStyle . $suffix;
99
    }
100
101
    /**
102
     * @return string[]
103
     */
104
    public function getSupportedTags(): array
105
    {
106
        return [
107
            'em', 'i', 'cite', 'dfn', 'var',
108
            'strong', 'b',
109
            'del', 'strike', 's',
110
            'sub', 'sup',
111
            'u', 'ins',
112
            'kbd',
113
            'span', 'small', 'abbr'
114
        ];
115
    }
116
    
117
    protected function makeDelimiter($element, string $tag, $style, bool $prev = true): string
118
    {
119
        /* If this node is immediately preceded or followed by one of the same type don't emit
120
         * the start or end $style, respectively. This prevents <em>foo</em><em>bar</em> from
121
         * being converted to *foo**bar* which is incorrect. We want *foobar* instead.
122
         */
123
        if($prev) {
124
            $ignore = $this->getNormTag($element->getPreviousSibling()) === $tag;
125
        } else {
126
            $ignore = $this->getNormTag($element->getNextSibling()) === $tag;
127
        }
128
        if (!is_string($style ?? null) || $ignore) return '';
129
        return empty($style) ? "<" . ($prev ? "" : "/") ."{$tag}>" : $style;
130
    }
131
}
132