"""This module declares the basic classes for all renderers."""from__future__importannotationsfromabcimportABC,abstractmethodfrommaelzel.scorestructimportScoreStructfrommaelzel.scoring.renderoptionsimportRenderOptionsfrommaelzel.scoringimportquantfrommaelzel.scoring.configimportconfigfrommaelzelimport_utilfrommaelzelimport_imgtoolsimportemlib.imgimportemlib.miscimportemlib.envir
[docs]classRenderer(ABC):""" Renders a quantizedscore to a given format This is an abstract base class for different backend renderers (lilypond, musicxml, etc) """def__init__(self,score:quant.QuantizedScore,options:RenderOptions):ifnotscore:raiseValueError("The quantized score is empty")ifscore[0].structisNone:raiseValueError("The score has no associated ScoreStruct, cannot render")self.quantizedScore:quant.QuantizedScore=score"""The quantized score used for rendering"""self.struct:ScoreStruct=score[0].struct"""The ScoreStruct used for rendering"""self.options:RenderOptions=options"""The render options used"""def__hash__(self)->int:returnhash((hash(self.quantizedScore),hash(self.struct),hash(self.options)))
[docs]@abstractmethoddefrender(self,options:RenderOptions|None=None)->str:""" Render the quantized score .. note:: The result is internally cached so calling this method multiple times only performs the rendering once as long as the options used do not change Args: options: if given, these options override the own options Returns: the rendered score, as text. This will be lilypond text if the renderer is a LilypondRenderer, or musicxml text in the case of a MusicxmlRenderer """raiseNotImplementedError("Please Implement this method")
[docs]@abstractmethoddefwriteFormats(self)->list[str]:""" List of formats supported by this Renderer Returns: a list of possible write formats (pdf, xml, musicxml, etc) """raiseNotImplementedError("Please Implement this method")
[docs]@abstractmethoddefwrite(self,outfile:str,fmt='',removeTemporaryFiles=False)->None:""" Write the rendered score to a file Args: outfile: the path to the written file fmt: if given, this will be used as format for the output, independent of the extension used in outfile. The possible values depend on the formats supported by this Renderer (see :meth:`Renderer.writeFormats`) removeTemporaryFiles: if True, removes any temporary files generated during the rendering/writing process """raiseNotImplementedError("Please Implement this method")
[docs]defmusicxml(self)->str|None:""" Returns the rendered score as musicxml if supported Returns: either the musicxml as str, or None if not supported by this renderer """returnNone
[docs]defshow(self,fmt='png',external=False,scalefactor=1.0)->None:""" Display the rendered score Args: fmt: one of 'png', 'pdf' external: if True, for the use of an external app to open the rendered result. Otherwise, if running inside jupyter this command will try to display the result inline scalefactor: a factor to scale the generated image when shown inline """iffmt=='pdf':external=Trueiffmt=='png':png=_util.mktemp(suffix='.png')self.write(png)_util.pngShow(png,forceExternal=external,inlineScale=scalefactor)eliffmt=='pdf':outfile=_util.mktemp(suffix=f'.{fmt}')self.write(outfile)emlib.misc.open_with_app(outfile)else:raiseValueError(f"fmt should be 'png' or 'pdf', got '{fmt}'")