1<?php
2
3namespace dokuwiki\plugin\wordimport\docx;
4
5/**
6 * The styles of a docx file
7 *
8 * Styles have an ID and a name. The XMLs always use the ID, but we want to work with the name.
9 */
10class Styles extends AbstractXMLFile
11{
12    /** @var array The mapping of style IDs to style names */
13    protected $id2name = [];
14    /** @var array The mapping of style names to style IDs */
15    protected $name2id = [];
16
17    /** @inheritdoc */
18    protected function parse()
19    {
20        $xml = $this->docx->loadXMLFile('word/styles.xml');
21        $this->registerNamespaces($xml);
22
23
24        $styles = $xml->xpath('//w:style');
25        foreach ($styles as $style) {
26            $x = $style->asXML();
27
28            $id = strtolower($style->attributes('w', true)->styleId);
29            $name = strtolower($style->xpath('w:name')[0]->attributes('w', true)->val);
30            $this->id2name[$id] = $name;
31        }
32        $this->name2id = array_flip($this->id2name);
33    }
34
35
36    /**
37     * Check if the given element has one of the given style names
38     *
39     * @param \SimpleXMLElement $xml
40     * @param string[] $names
41     * @return bool
42     */
43    public function hasStyle(\SimpleXMLElement $xml, $names)
44    {
45        // get IDs for the given names
46        $ids = array_filter(array_map(function ($name) {
47            $name = strtolower($name);
48            return $this->name2id[$name] ?? $name;
49        }, $names));
50
51        $style = $xml->xpath('w:pPr/w:pStyle');
52        foreach ($style as $s) {
53            $id = strtolower($s->attributes('w', true)->val);
54            if (in_array($id, $ids)) {
55                return true;
56            }
57        }
58        return false;
59    }
60
61    /**
62     * Get the name of a style by its ID
63     *
64     * @param string $id
65     * @return string
66     */
67    public function getStyleName(string $id)
68    {
69        return $this->id2name[$id] ?? $id;
70    }
71}
72