Manipulate the XML based .mscz
and .mscx
files of the notation software
MuseScore.
- Batch processing of
.msc[zx]
files in nested folder structures - Rename
.msc[zx]
files based on meta tags - Set, read and synchronized meta tags
- Set style properties
- Can handle MuseScore 2, 3 and 4 files
- Command line interface
- Python API
pipx install mscxyz
To find out which files are selected by the script, the -L, --list-files
option can be used. The --list-files
option lists as the name suggests
only the file paths and doesn’t touch the specified MuseScore files:
musescore-manager --list-files
Without an option the script lists all MuseScore files in the current directory
in a recursive way (musescore-manager
= musescore-manager .
).
You can pass multiple file paths to the script:
musescore-manager -L score1.mscz score2.mscz score3.mscz
or multiple directories:
musescore-manager -L folder1 folder2 folder3
or use the path expansion of your shell:
musescore-manager -L *.mscz
To apply glob patterns on the file paths, the --glob
option can be used.
musescore-manager -L --glob "*/folder/*.mscz"
To selection only mscz oder mscx files use the options --mscz
or --mscx
.
Don’t mix the options --mscz
and --mscx
with the option --glob
.
The python package mscxyz
exports a function named list_path
which can
be used to list the paths of MuseScore files. This allows you to list score
paths in a nested folder structure in a similar way to the command line.
This folder structure is used for the following example:
cd /home/xyz/scores find . | sort . ./level1 ./level1/level2 ./level1/level2/score2.mscz ./level1/level2/level3 ./level1/level2/level3/score3.mscz ./level1/score1.mscz ./score0.mscz
from mscxyz import list_path, Score
score_paths = []
for score_path in list_path(path="/home/xyz/scores", extension="mscz"):
score = Score(score_path)
assert score.path.exists()
assert score.extension == "mscz"
score_paths.append(str(score_path))
assert len(score_paths) == 4
assert "level1/level2/level3/score3.mscz" in score_paths[3]
assert "level1/level2/score2.mscz" in score_paths[2]
assert "level1/score1.mscz" in score_paths[1]
assert "score0.mscz" in score_paths[0]
On the command line use the option --export
to export the scores to
different file types. The exported file has the same path, only the file
extension is different. Further information about the supported file formats
can be found at the MuseScore website:
Version 2,
Version 3 and
Version 4
The MuseScore binay must be installed and the script must know the location of t
his binary.
musescore-manager --export pdf musescore-manager --export png
score = Score('score.mscz')
score.export.to_extension("musicxml")
Set a single style by its style name --style
:
musescore-manager --style staffDistance 7.5 score.mscz
To set mulitple styles at once specify the option --style
multiple times:
musescore-manager --style staffUpperBorder 5.5 --style staffLowerBorder 5.5 score.mscz
Some options change mutliple font related xml elements at once:
musescore-manager --text-font Alegreya score.mscz musescore-manager --title-font "Alegreya Sans" score.mscz musescore-manager --musical-symbol-font Leland score.mscz musescore-manager --musical-text-font "Leland Text" score.mscz
Set all font faces (using a for loop, not available in MuseScore 2):
score = Score('score.mscz')
assert score.style.get("defaultFontFace") == "FreeSerif"
for element in score.style.styles:
if "FontFace" in element.tag:
element.text = "Alegreya"
score.save()
new_score: Score = score.reload()
assert new_score.style.get("defaultFontFace") == "Alegreya"
Set all text font faces (using the method score.style.set_text_font_faces(font_face)
,
not available in MuseScore 2):
score = Score('score.mscz')
assert score.style.get("defaultFontFace") == "FreeSerif"
response = score.style.set_text_font_faces("Alegreya")
assert response == [
...
("harpPedalTextDiagramFontFace", "Edwin", "Alegreya"),
("longInstrumentFontFace", "FreeSerif", "Alegreya"),
...
]
score.save()
new_score: Score = score.reload()
assert new_score.style.get("defaultFontFace") == "Alegreya"
Use one of the following autocomplete files ...
musescore-manager --print-completion bash > autocomplete.bash musescore-manager --print-completion zsh > autocomplete.zsh musescore-manager --print-completion tcsh > autocomplete.tcsh
The following example assumes that the folder /home/xyz/messy-leadsheets
contains the following three MuseScore files: folsom prison blues.mscz
,
Johnny Cash - I Walk the Line.mscz
, Jackson (Cash).mscz
The files are named arbitrarily without any recognizable pattern, but they have a
title in the first vertical frame (VBox).
The files should be moved to a target directory (--target /home/xyz/tidy-leadsheets
) and
the file names should not contain any spaces (--no-whitespace
).
The title should be used as the file name (--rename '$vbox_title'
).
The individual files should be stored in subdirectories named after the first
letter of the title (--rename '%lower{%shorten{$vbox_title,1}}/...'
)
musescore-manager --rename '%lower{%shorten{$vbox_title,1}}/$vbox_title' \ --target /home/xyz/tidy-leadsheets \ --no-whitespace \ /home/xyz/messy-leadsheets
After executing the above command on the command line, find /home/xyz/tidy-leadsheets
should show the following output:
i/I-Walk-the-Line.mscz j/Jackson.mscz f/Folsom-Prison-Blues.mscz
Please visit the API documentation on readthedocs.
Instantiate a Score
object:
from mscxyz import Score
score = Score('score.mscz')
assert score.path.exists()
assert score.filename == "score.mscz"
assert score.basename == "score"
assert score.extension == "mscz"
assert score.version == 4.20
assert score.version_major == 4
Examine the most important attribute of a Score
object: xml_root
.
It is the root element of the XML document in which MuseScore stores all information
about a score.
It’s best to take a look at the lxml API documentation
to see what you can do with this element. So much can be revealed:
lots of interesting things.
score = Score('score.mscz')
def print_elements(element: _Element, level: int) -> None:
for sub_element in element:
print(f"{' ' * level}<{sub_element.tag}>")
print_elements(sub_element, level + 1)
print_elements(score.xml_root, 0)
The output of the code example is very long, so here is a shortened version:
<programVersion> <programRevision> <LastEID> <Score> <Division> <showInvisible> <showUnprintable> <showFrames> <showMargins> <open> <metaTag> ...
XML structure of a meta tag:
<metaTag name="tag"></metaTag>
All meta tags:
arranger
audioComUrl
(new in v4)composer
copyright
creationDate
lyricist
movementNumber
movementTitle
mscVersion
platform
poet
(not in v4)source
sourceRevisionId
subtitle
translator
workNumber
workTitle
XML structure of a vbox tag:
<VBox>
<Text>
<style>title</style>
<text>Some title text</text>
</Text>
All vbox tags:
title
(v2,3:Title
)subtitle
(v2,3:Subtitle
)composer
(v2,3:Composer
)lyricist
(v2,3:Lyricist
)
This command line tool bundles some meta data informations:
title
(1.vbox_title
2.metatag_work_title
)subtitle
(1.vbox_subtitle
2.metatag_subtitle
3.metatag_movement_title
)composer
(1.vbox_composer
2.metatag_composer
)lyricist
(1.vbox_lyricist
2.metatag_lyricist
)
Set the meta tag composer
:
<museScore version="4.20">
<Score>
<metaTag name="composer">Composer</metaTag>
score = Score('score.mscz')
assert score.meta.meta_tag.composer == "Composer"
score.meta.meta_tag.composer = "Mozart"
score.save()
new_score: Score = score.reload()
assert new_score.meta.meta_tag.composer == "Mozart"
<museScore version="4.20">
<Score>
<metaTag name="composer">Mozart</metaTag>
usage: musescore-manager [-h] [--print-completion {bash,zsh,tcsh}] [-C <file-path>] [-b] [-d] [--catch-errors] [-m] [-e FILE_PATH] [-E <extension>] [--compress] [-V] [-v] [-k | --color | --no-color] [--diff] [--print-xml] [-c <fields>] [-D] [-i <source-fields> <format-string>] [-j] [-l <log-file> <format-string>] [-y] [-S <field> <format-string>] [--metatag <field> <value>] [--vbox <field> <value>] [--title <string>] [--subtitle <string>] [--composer <string>] [--lyricist <string>] [-x <number-or-all>] [-r <remap-pairs>] [-F] [--rename <path-template>] [-t <directory> | --only-filename] [-A] [-a] [-n] [-K <fields>] [-L] [-g <glob-pattern> | --mscz | --mscx] [-s <style-name> <value>] [--clean] [-Y <file>] [--s3] [--s4] [--list-fonts] [--text-font <font-face>] [--title-font <font-face>] [--musical-symbol-font <font-face>] [--musical-text-font <font-face>] [--staff-space <dimension>] [--page-size <width> <height>] [--a4] [--letter] [--margin <dimension>] [--show-header | --no-show-header] [--header-first-page | --no-header-first-page] [--different-odd-even-header | --no-different-odd-even-header] [--header <left> <center> <right>] [--header-odd-even <odd-left> <even-left> <odd-center> <even-center> <odd-right> <even-right>] [--show-footer | --no-show-footer] [--footer-first-page | --no-footer-first-page] [--different-odd-even-footer | --no-different-odd-even-footer] [--footer <left> <center> <right>] [--footer-odd-even <odd-left> <even-left> <odd-center> <even-center> <odd-right> <even-right>] [--reset-small-staffs] [<path> ...] The next generation command line tool to manipulate the XML based "*.mscX" and "*.mscZ" files of the notation software MuseScore. positional arguments: <path> Path to a "*.msc[zx]" file or a folder containing "*.msc[zx]" files. can be specified several times. options: -h, --help show this help message and exit --print-completion {bash,zsh,tcsh} print shell completion script -C <file-path>, --config-file <file-path> Specify a configuration file in the INI format. -b, --backup Create a backup file. -d, --dry-run Simulate the actions. --catch-errors Print error messages instead stop execution in a batch run. -m, --mscore, --save-in-mscore Open and save the XML file in MuseScore after manipulating the XML with lxml to avoid differences in the XML structure. -e FILE_PATH, --executable FILE_PATH Path of the musescore executable. export: Export the scores in different formats. -E <extension>, --export <extension> Export the scores in a format defined by the extension. The exported file has the same path, only the file extension is different. Further information can be found at the MuseScore website: https://musescore.org/en/handbook/2/file-formats, https://musescore.org/en/handbook/3/file-export, https://musescore.org/en/handbook/4/file-export. MuseScore must be installed and the script must know the location of the binary file. --compress Save an uncompressed MuseScore file (*.mscx) as a compressed file (*.mscz). info: Print informations about the score and the CLI interface itself. -V, --version show program's version number and exit -v, --verbose Make commands more verbose. You can specifiy multiple arguments (. g.: -vvv) to make the command more verbose. -k, --color, --no-color Colorize the command line print statements. (default: True) --diff Show a diff of the XML file before and after the manipulation. --print-xml Print the XML markup of the score. meta: Deal with meta data informations stored in the MuseScore file. -c <fields>, --clean-meta <fields> Clean the meta data fields. Possible values: „all“ or a comma separated list of fields, for example: „field_one,field_two“. -D, --delete-duplicates Deletes lyricist if this field is equal to composer. Deletes subtitle if this field is equal totitle. Move subtitle to combimed_title if title is empty. -i <source-fields> <format-string>, --distribute-fields <source-fields> <format-string> Distribute source fields to target fields by applying a format string on the source fields. It is possible to apply multiple --distribute-fields options. <source-fields> can be a single field or a comma separated list of fields: field_one,field_two. The program tries first to match the <format-string> on the first source field. If thisfails, it tries the second source field ... and so on. -j, --json Write the meta data to a json file. The resulting file has the same path as the input file, only the extension is changed to “json”. -l <log-file> <format-string>, --log <log-file> <format-string> Write one line per file to a text file. e. g. --log /tmp/musescore-manager.log '$title $composer' -y, --synchronize Synchronize the values of the first vertical frame (vbox) (title, subtitle, composer, lyricist) with the corresponding metadata fields -S <field> <format-string>, --set-field <field> <format-string> Set value to meta data fields. --metatag <field> <value>, --metatag-meta <field> <value> Define the metadata in MetaTag elements. Available fields: arranger, audio_com_url, composer, copyright, creation_date, lyricist, movement_number, movement_title, msc_version, platform, poet, source, source_revision_id, subtitle, translator, work_number, work_title. --vbox <field> <value>, --vbox-meta <field> <value> Define the metadata in VBox elements. Available fields: composer, lyricist, subtitle, title. --title <string> Create a vertical frame (vbox) containing a title text field and set the corresponding document properties work title field (metatag). --subtitle <string> Create a vertical frame (vbox) containing a subtitle text field and set the corresponding document properties subtitle and movement title filed (metatag). --composer <string> Create a vertical frame (vbox) containing a composer text field and set the corresponding document properties composer field (metatag). --lyricist <string> Create a vertical frame (vbox) containing a lyricist text field and set the corresponding document properties lyricist field (metatag). lyrics: -x <number-or-all>, --extract <number-or-all>, --extract-lyrics <number-or-all> Extract each lyrics verse into a separate MuseScore file. Specify ”all” to extract all lyrics verses. The old verse number is appended to the file name, e. g.: score_1.mscx. -r <remap-pairs>, --remap <remap-pairs>, --remap-lyrics <remap-pairs> Remap lyrics. Example: "--remap 3:2,5:3". This example remaps lyrics verse 3 to verse 2 and verse 5 to 3. Use commas to specify multiple remap pairs. One remap pair is separated by a colon in this form: "old:new": "old" stands for the old verse number. "new" stands for the new verse number. -F, --fix, --fix-lyrics Fix lyrics: Convert trailing hyphens ("la- la- la") to a correct hyphenation ("la - la - la") rename: Rename the “*.msc[zx]” files. --rename <path-template> A path template string to set the destination location. -t <directory>, --target <directory> Target directory --only-filename Rename only the filename and don’t move the score to a different directory. -A, --alphanum Use only alphanumeric characters. -a, --ascii Use only ASCII characters. -n, --no-whitespace Replace all whitespaces with dashes or sometimes underlines. -K <fields>, --skip-if-empty <fields> Skip the rename action if the fields specified in <fields> are empty. Multiple fields can be separated by commas, e. g.: composer,title selection: The following options affect how the manager selects the MuseScore files. -L, --list-files Only list files and do nothing else. -g <glob-pattern>, --glob <glob-pattern> Handle only files which matches against Unix style glob patterns (e. g. "*.mscx", "* - *"). If you omit this option, the standard glob pattern "*.msc[xz]" is used. --mscz Take only "*.mscz" files into account. --mscx Take only "*.mscx" files into account. style: Change the styles. -s <style-name> <value>, --style <style-name> <value> Set a single style value. For example: --style pageWidth 8.5 --clean Clean and reset the formating of the "*.mscx" file -Y <file>, --style-file <file> Load a "*.mss" style file and include the contents of this file. --s3, --styles-v3 List all possible version 3 styles. --s4, --styles-v4 List all possible version 4 styles. --reset-small-staffs Reset all small staffs to normal size. font (style): Change the font faces of a score. --list-fonts List all font related styles. --text-font <font-face> Set nearly all fonts except “romanNumeralFontFace”, “figuredBassFontFace”, “dynamicsFontFace“, “musicalSymbolFont” and “musicalTextFont”. --title-font <font-face> Set “titleFontFace” and “subTitleFontFace”. --musical-symbol-font <font-face> Set “musicalSymbolFont”, “dynamicsFont” and “dynamicsFontFace”. --musical-text-font <font-face> Set “musicalTextFont”. page (style): Page settings. --staff-space <dimension> Set the staff space or spatium. This is the vertical distance between two lines of a music staff. --page-size <width> <height> Set the page size. --a4, --din-a4 Set the paper size to DIN A4 (210 by 297 mm). --letter Set the paper size to Letter (8.5 by 11 in). --margin <dimension> Set the top, right, bottom and left margins to the same value. header (style): Change the header. --show-header, --no-show-header Show or hide the header. --header-first-page, --no-header-first-page Show the header on the first page. --different-odd-even-header, --no-different-odd-even-header Use different header for odd and even pages. --header <left> <center> <right> Set the header for all pages. --header-odd-even <odd-left> <even-left> <odd-center> <even-center> <odd-right> <even-right> Set different headers for odd and even pages. footer (style): Change the footer. --show-footer, --no-show-footer Show or hide the footer. --footer-first-page, --no-footer-first-page Show the footer on the first page. --different-odd-even-footer, --no-different-odd-even-footer Use different footers for odd and even pages. --footer <left> <center> <right> Set the footer for all pages. --footer-odd-even <odd-left> <even-left> <odd-center> <even-center> <odd-right> <even-right> Set different footers for odd and even pages.
/etc/mscxyz.ini
[general]
executable = /usr/bin/mscore3
colorize = True
[rename]
format = '$title ($composer)'
make test
git tag 1.1.1 git push --tags make publish
The package documentation is hosted on readthedocs.
Generate the package documentation:
make docs