Passed
Push — markdown-responsive ( 66d0bb...dea121 )
by Arnaud
09:36 queued 05:00
created

Parsedown::parseAttributeData()   B

Complexity

Conditions 7
Paths 16

Size

Total Lines 29
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
cc 7
eloc 17
nc 16
nop 1
dl 0
loc 29
rs 8.8333
c 1
b 1
f 0
1
<?php
2
/**
3
 * This file is part of the Cecil/Cecil package.
4
 *
5
 * Copyright (c) Arnaud Ligny <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace Cecil\Converter;
12
13
use Cecil\Assets\Asset;
14
use Cecil\Builder;
15
16
class Parsedown extends \ParsedownToC
17
{
18
    /** @var Builder */
19
    protected $builder;
20
21
    /** {@inheritdoc} */
22
    protected $regexAttribute = '(?:[#.][-\w:\\\]+[ ]*|[-\w:\\\]+(?:=(?:["\'][^\n]*?["\']|[^\s]+)?)?[ ]*)';
23
24
    public function __construct(Builder $builder)
25
    {
26
        $this->builder = $builder;
27
        parent::__construct(['selectors' => $this->builder->getConfig()->get('body.toc')]);
28
    }
29
30
    /**
31
     * {@inheritdoc}
32
     */
33
    protected function inlineImage($excerpt)
34
    {
35
        $image = parent::inlineImage($excerpt);
36
        if (!isset($image)) {
37
            return null;
38
        }
39
        $image['element']['attributes']['src'] = trim($this->removeQuery($image['element']['attributes']['src']));
40
        $asset = new Asset($this->builder, $image['element']['attributes']['src']);
41
        $width = $asset->getWidth();
42
        /**
43
         * Should be lazy loaded?
44
         */
45
        if ($this->builder->getConfig()->get('content.images.lazy.enabled')) {
46
            $image['element']['attributes']['loading'] = 'lazy';
47
        }
48
        /**
49
         * Should be responsive?
50
         */
51
        if ($this->builder->getConfig()->get('content.images.responsive.enabled')) {
52
            $steps = $this->builder->getConfig()->get('content.images.responsive.width.steps');
53
            $wMin = $this->builder->getConfig()->get('content.images.responsive.width.min');
54
            $wMax = $this->builder->getConfig()->get('content.images.responsive.width.max');
55
            if ($width < $wMax) {
56
                $wMax = $width;
57
            }
58
            $srcset = '';
59
            for ($i = 1; $i <= $steps; $i++) {
60
                $w = (int) ceil($wMin + ($wMax - $wMin) / $steps * $i);
61
                $a = new Asset($this->builder, $image['element']['attributes']['src']);
62
                $img = $a->resize($w);
63
                $srcset .= sprintf('%s %sw', $img, $w);
64
                if ($i < $steps) {
65
                    $srcset .= ', ';
66
                }
67
            }
68
            // ie: srcset="/img-480.jpg 480w, /img-800.jpg 800w"
69
            $image['element']['attributes']['srcset'] = $srcset;
70
            $image['element']['attributes']['sizes'] = $this->builder->getConfig()->get('content.images.responsive.sizes.default');
71
        }
72
        /**
73
         * Should be resized?
74
         */
75
        if ($image['element']['attributes']['width'] !== null
76
            && (int) $image['element']['attributes']['width'] < $width
77
            && $this->builder->getConfig()->get('content.images.resize.enabled')
78
        ) {
79
            $width = (int) $image['element']['attributes']['width'];
80
            $imageResized = $asset->resize($width);
81
            $image['element']['attributes']['src'] = $imageResized;
82
        }
83
        if ($image['element']['attributes']['width'] === null) {
84
            $image['element']['attributes']['width'] = $width;
85
        }
86
87
        return $image;
88
    }
89
90
    /**
91
     * {@inheritdoc}
92
     */
93
    protected function parseAttributeData($attributeString)
94
    {
95
        $Data = [];
96
97
        $attributes = preg_split('/[ ]+/', $attributeString, -1, PREG_SPLIT_NO_EMPTY);
98
99
        $HtmlAtt = [];
100
101
        foreach ($attributes as $attribute) {
102
            if ($attribute[0] === '#') {
103
                $Data['id'] = substr($attribute, 1);
104
            } elseif ($attribute[0] === '.') {
105
                $classes[] = substr($attribute, 1);
106
            } else {
107
                parse_str($attribute, $parsed);
108
                $HtmlAtt = array_merge($HtmlAtt, $parsed);
109
            }
110
        }
111
112
        if (isset($classes)) {
113
            $Data['class'] = implode(' ', $classes);
114
        }
115
        if (isset($HtmlAtt)) {
116
            foreach ($HtmlAtt as $a => $v) {
117
                $Data[$a] = trim($v, '"');
118
            }
119
        }
120
121
        return $Data;
122
    }
123
124
    /**
125
     * Removes query string from URL.
126
     */
127
    private function removeQuery(string $path): string
128
    {
129
        return strtok($path, '?');
130
    }
131
}
132