MarkdownFileParser   A
last analyzed

Complexity

Total Complexity 21

Size/Duplication

Total Lines 117
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Test Coverage

Coverage 83.87%

Importance

Changes 0
Metric Value
wmc 21
lcom 1
cbo 5
dl 0
loc 117
ccs 52
cts 62
cp 0.8387
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A parse() 0 14 3
D parseMetadata() 0 37 10
A parseTitle() 0 12 2
B createFlavoredParser() 0 24 6
1
<?php
2
3
namespace Flatdown\Markdown;
4
5
use cebe\markdown\GithubMarkdown;
6
use cebe\markdown\Markdown;
7
use cebe\markdown\MarkdownExtra;
8
use Symfony\Component\Yaml\Yaml;
9
10
class MarkdownFileParser
11
{
12
    /**
13
     * Parses the given Markdown file
14
     *
15
     * @param string $filename
16
     * @param array $options
17
     *
18
     * @return MarkdownFile
19
     */
20 6
    public function parse($filename, array $options)
21
    {
22 6
        $file = new MarkdownFile($filename);
23
24 3
        $content = $file->load()->content;
25
26 3
        $file->metadata = $this->parseMetadata($content, $options);
27 3
        $file->html     = trim($this->createFlavoredParser($options)->parse($content));
28 3
        $parsedTitle    = $this->parseTitle($file->html);
29 3
        $file->title    = (isset($file->metadata['title']) && strlen($file->metadata['title']))
30 3
            ? $file->metadata['title'] : $parsedTitle;
31
32 3
        return $file;
33
    }
34
35
    /**
36
     * @param string $content
37
     * @param array $options
38
     *
39
     * @return array
40
     */
41 3
    private function parseMetadata(&$content, array $options)
42
    {
43 3
        $metadataLines = [];
44 3
        $contentLines  = explode("\n", $content);
45 3
        $delimiter     = isset($options['metadataDelimiter']) ? $options['metadataDelimiter'] : '---';
46 3
        $indentation   = isset($options['metadataIndentation']) ? $options['metadataIndentation'] : 4;
47
48 3
        if (empty($contentLines) || ($contentLines[0] !== $delimiter)) {
49
            return [];
50 2
        }
51
52 3
        array_shift($contentLines);
53
54 3
        $line = 0;
55 3
        while (isset($contentLines[$line]) && ($contentLines[$line] != $delimiter)) {
56 3
            $metadataLines[] = $indentation ?
57 3
                preg_replace('/^(\s{' . $indentation . '})/', '', $contentLines[$line]) :
58
                $contentLines[$line];
59 3
            $line++;
60 2
        }
61
62 3
        if ($contentLines[$line] == $delimiter) {
63 3
            $line++;
64 2
        }
65
66 3
        $content         = [];
67 3
        $contentNumLines = count($contentLines);
68
69 3
        for ($i = $line; $i < $contentNumLines; $i++) {
70 3
            $content[] = $contentLines[$i];
71 2
        }
72
73 3
        $content  = implode("\n", $content);
74 3
        $metadata = implode("\n", $metadataLines);
75
76 3
        return (array)Yaml::parse($metadata);
77 2
    }
78
79
    /**
80
     * @param string $html
81
     *
82
     * @return string
83
     */
84 3
    private function parseTitle(&$html)
85
    {
86 3
        $parts = explode('</h1>', $html, 2);
87
88 3
        if (count($parts) != 2) {
89
            return '';
90
        }
91 3
        $title = preg_replace('/(.*)(\<h1.*\>)(.*)/', '$3', $parts[0]);
92 3
        $html  = preg_replace('/(.*)(\<h1.*)/', '$1', $parts[0]) . $parts[1];
93
94 3
        return $title;
95
    }
96
97
    /**
98
     * @param array $options
99
     *
100
     * @return Markdown
101
     */
102 3
    private function createFlavoredParser(array $options)
103
    {
104 3
        $flavor = isset($options['flavor']) ? $options['flavor'] : 'extra';
105
106
        switch ($flavor) {
107 3
            case 'default':
108
                $parser = new Markdown();
109
                break;
110 3
            case 'extra':
111
                $parser = new MarkdownExtra();
112
                break;
113 3
            case 'github':
114 3
                $parser = new GithubMarkdown();
115 3
                break;
116
            default:
117
                throw new \InvalidArgumentException('Flavor not supported: ' . $flavor);
118
        }
119
120 3
        foreach ($options as $optName => $optValue) {
121 3
            $parser->$optName = $optValue;
122 2
        }
123
124 3
        return $parser;
125
    }
126
}
127