From e961af6be7ddc607e64a739db7544358875d07a5 Mon Sep 17 00:00:00 2001 From: Josef Friedrich Date: Sun, 21 Jan 2024 09:05:30 +0100 Subject: [PATCH] Extend the create_sub_element method --- mscxyz/lyrics.py | 3 +-- mscxyz/score.py | 5 ++--- mscxyz/style.py | 26 ++++++++++++++++---------- mscxyz/xml.py | 4 ++-- 4 files changed, 21 insertions(+), 17 deletions(-) diff --git a/mscxyz/lyrics.py b/mscxyz/lyrics.py index 7d3d364..e6445a4 100644 --- a/mscxyz/lyrics.py +++ b/mscxyz/lyrics.py @@ -5,7 +5,6 @@ import typing -import lxml.etree as etree from lxml.etree import _Element if typing.TYPE_CHECKING: @@ -179,7 +178,7 @@ def fix_lyrics_verse(self, verse_number: int) -> None: tag, ) text = self.score.xml.get_text_safe(element_text) - element_syllabic: _Element = etree.Element("syllabic") + element_syllabic: _Element = self.score.xml.create_element("syllabic") append_syllabic: bool = True if text.endswith("-"): element_text.text = text[:-1] diff --git a/mscxyz/score.py b/mscxyz/score.py index 42c1678..9191b2a 100644 --- a/mscxyz/score.py +++ b/mscxyz/score.py @@ -9,8 +9,6 @@ from pathlib import Path from typing import Any, Optional -import lxml -import lxml.etree from lxml.etree import _Element from mscxyz import utils @@ -248,9 +246,10 @@ def save(self, new_dest: str = "", mscore: bool = False) -> None: # Since MuseScore 4 the style is stored in a separate file. if self.style_file: - element: _Element = lxml.etree.Element( + element = self.xml.create_element( "museScore", {"version": str(self.version)} ) + element.append(self.style.parent_element) self.xml.write(self.style_file, element) diff --git a/mscxyz/style.py b/mscxyz/style.py index 5dc2cd5..43fb26f 100644 --- a/mscxyz/style.py +++ b/mscxyz/style.py @@ -12,6 +12,7 @@ from mscxyz import utils from mscxyz.utils import INCH +from mscxyz.xml import Xml if typing.TYPE_CHECKING: from mscxyz.score import Score @@ -124,16 +125,20 @@ class Style: """The parent ``/museScore/Score/Style`` element that contains all style tags. """ + @property + def xml(self) -> Xml: + return self.score.xml + def __init__(self, score: "Score") -> None: self.score = score if self.score.style_file: - self.parent_element = self.score.xml.find_safe( + self.parent_element = self.xml.find_safe( "Style", - self.score.xml.parse_file(self.score.style_file), + self.xml.parse_file(self.score.style_file), ) else: - element: _Element | None = self.score.xml_root.find("Score/Style") + element: _Element | None = self.xml.find("Score/Style") if element is not None: self.parent_element = element else: @@ -145,10 +150,11 @@ def __create_parent_style(self) -> _Element: :return: The created parent style element. """ - score: _Element | None = self.score.xml_root.find("Score") + score: _Element | None = self.xml.find("Score") if score is None: raise ValueError("The score file has no tag.") - return lxml.etree.SubElement(score, "Style") + _, sub_element = self.xml.create_sub_element(score, "Style") + return sub_element def __create_nested_element(self, tag: str) -> _Element: """ @@ -243,7 +249,7 @@ def __get_attributes(self, style_name: str) -> _Attrib: def clean(self) -> None: """Remove the style, the layout breaks, the stem directions and the ``font``, ``b``, ``i``, ``pos``, ``offset`` tags""" - self.score.xml.remove_tags( + self.xml.remove_tags( "./Score/Style", ".//LayoutBreak", ".//StemDirection", @@ -320,7 +326,7 @@ def __get_text_style_element(self, name: str) -> _Element: "This operation is only allowed for MuseScore 2 score files" ) - child: _Element | None = self.score.xml.xpath( + child: _Element | None = self.xml.xpath( f'//TextStyle/name[contains(., "{name}")]' ) @@ -399,7 +405,7 @@ def get_all_fonts(self) -> list[tuple[str, str]]: output: list[tuple[str, str]] = [] for element in self.parent_element: if "FontFace" in element.tag: - output.append((element.tag, self.score.xml.get_text_safe(element))) + output.append((element.tag, self.xml.get_text_safe(element))) return output def print_all_font_faces(self) -> None: @@ -526,7 +532,7 @@ def set_musical_text_font(self, font_face: str) -> StyleChanges: return self.set("musicalTextFont", font_face) def __set_parent_style_element(self, parent_style: _Element) -> None: - score_element: _Element = self.score.xml.find_safe("Score") + score_element: _Element = self.xml.find_safe("Score") score_element.insert(0, parent_style) self.parent_element = parent_style @@ -560,7 +566,7 @@ def load_styles_as_string(self, styles: str) -> None: self.__set_parent_style_element(style[0]) def load_style_file(self, file: str | Path | TextIOWrapper) -> None: - style: _Element = self.score.xml.parse_file(file) + style: _Element = self.xml.parse_file(file) self.__set_parent_style_element(style[0]) def reload(self, save: bool = False) -> Style: diff --git a/mscxyz/xml.py b/mscxyz/xml.py index 1ce3077..188cd6e 100644 --- a/mscxyz/xml.py +++ b/mscxyz/xml.py @@ -275,8 +275,8 @@ def replace(old: _Element, new: _Element) -> None: parent.replace(old, new) @staticmethod - def create_element(tag_name: str) -> _Element: - return Element(tag_name) + def create_element(tag_name: str, attrib: Optional[_DictAnyStr] = None) -> _Element: + return Element(tag_name, attrib=attrib) @staticmethod def create_sub_element(