def music(self, layout): layout.setSpanBarContexts(['PianoStaff']) if not self.clefs.isChecked(): layout.add('Staff', "\\override Clef #'transparent = ##t") if lilyPondVersion() < (2, 13, 4): spacing = "#'minimum-Y-extent = #'(-6 . 3)" elif lilyPondVersion() < (2, 14, 0): spacing = "#'next-staff-spacing = #'((space . 10))" else: spacing = "#'next-staff-spacing = #'((basic-distance . 10))" return ['\\new PianoStaff <<', '\\new Staff \\with {', '\\override VerticalAxisGroup ' + spacing, '} { \\clef treble \\music }', '\\new Staff { \\clef bass \\music }', '>>']
def music(self, layout): clef = self.clef.clef() staff = 'TabStaff' if clef == 'tab' else 'Staff' layout.addStaffContext(staff) music = ['\\new {0} \\with {{'.format(staff)] if lilyPondVersion() < (2, 13, 4): music.append( "\\override VerticalAxisGroup #'minimum-Y-extent = #'(-{0} . 5)".format( self.spaceBelow.value())) elif lilyPondVersion() < (2, 14, 0): music.append( "\\override VerticalAxisGroup #'next-staff-spacing = #'((space . {0}))".format( self.spaceBelow.value() + 5)) else: music.append( "\\override VerticalAxisGroup #'next-staff-spacing = #'((basic-distance . {0}))".format( self.spaceBelow.value() + 5)) if not clef: music.append("\\override Clef #'transparent = ##t") if not clef or clef == 'tab': music.append('} { \\music }') else: music.append('}} {{ \\clef "{0}" \\music }}'.format(clef)) return music
def changeLanguage(self, lang): """ Change the LilyPond pitch name language in our document to lang. This is a bit hairy because LilyPond has a new syntax for this since 2.14, \language "name", while the old \include "name.ly" still is supported as well. """ newSyntax = (self.doc.lilyPondVersion() or lilyPondVersion()) >= (2, 13, 38) text, start = self.doc.selectionOrDocument() try: changes, includeCommandChanged = ly.tools.translate(text, lang, start) except ly.QuarterToneAlterationNotAvailable: KMessageBox.sorry( self.doc.app.mainwin, i18n( "Can't perform the requested translation.\n\n" "The music contains quarter-tone alterations, but " 'those are not available in the pitch language "%1".', lang, ), ) return # Apply the changes. with self.doc.editContext(): changes.applyToCursor(EditCursor(self.doc.doc)) if not start and not includeCommandChanged: if newSyntax: self.addLineToTop('\\language "{0}"'.format(lang)) else: self.addLineToTop('\\include "{0}.ly"'.format(lang)) if start and not includeCommandChanged: KMessageBox.information( self.doc.app.mainwin, "<p>{0}</p>" '<p><tt>\\include "{1}.ly"</tt> {2}</p>' '<p><tt>\\language "{1}"</tt> {3}</p>'.format( i18n( "The pitch language of the selected text has been " "updated, but you need to manually add the following " "command to your document:" ), lang, i18n("(for LilyPond below 2.14), or"), i18n("(for LilyPond 2.14 and higher.)"), ), i18n("Pitch Name Language"), )
def music(self, layout): clefs = self.clefs.currentText().upper() length = self.staffCount.value() if clefs and set(clefs) <= set("SATB"): # pad to staff count if necessary clefs = (clefs + clefs[-1] * length)[:length] else: clefs = [None] * length layout.add('Staff', "\\override Clef #'transparent = ##t") if lilyPondVersion() < (2, 13, 4): layout.add("Staff", "\\override VerticalAxisGroup #'minimum-Y-extent = #'(-6 . 4)") music = ['\\new ChoirStaff <<'] for clef in clefs: music.append('\\new Staff {{{0} \\music }}'.format({ 'S': ' \\clef treble', 'A': ' \\clef treble', 'T': ' \\clef "treble_8"', 'B': ' \\clef bass', None: '', }[clef])) music.append('>>') return music
def start(self): """ Starts the process. """ # save some values self._directory, self._basename = os.path.split(self.lyfile) # construct the full LilyPond command. cmd = [self.command] self.verbose and cmd.append("--verbose") cmd.append("-dpoint-and-click=" + scmbool(self.preview)) cmd.append("-ddelete-intermediate-files=" + scmbool(self.delfiles)) for path in self.include: cmd.append("--include") cmd.append(path) cmd.extend(self.arguments) cmd.append(self._basename) # create KProcess instance that does the work p = self._p = KProcess() p.setOutputChannelMode(KProcess.MergedChannels) p.setWorkingDirectory(self._directory) p.setProgram(cmd) p.finished.connect(self._finished) p.error.connect(self._error) p.readyRead.connect(self._readOutput) mode = i18n("preview mode") if self.preview else i18n("publish mode") version = lilyPondVersion(self.command) if version: self.output.writeLine(i18n("LilyPond %1 [%2] starting (%3)...", format(version), self._basename, mode)) else: self.output.writeLine(i18n("LilyPond [%1] starting (%2)...", self._basename, mode)) self.startTime = time.time() p.start()
def configureJob(self, job, doc=None): """Configure a job, belonging to document. If the document is not given, it is expected to live in the document attribute of the job. If there is already a job running, we just display, but disable the Run button, until the old job finishes. """ doc = doc or job.document # populate the dialog based on remembered settings for this document self.lilypond.clear() # find the configured lilypond versions conf = config("lilypond") paths = conf.readEntry("paths", ["lilypond"]) or ["lilypond"] default = conf.readEntry("default", "lilypond") import ly.version # get all versions ver = dict((path, lilyPondVersion(path)) for path in paths) # default if default not in paths: default = paths[0] # Sort on version paths.sort(key=ver.get) versions = [format(ver.get(p)) for p in paths] # Determine automatic version (lowest possible) autopath = None docVersion = doc.lilyPondVersion() if docVersion: autopath = automaticLilyPondCommand(docVersion) def addItem(version, path, icon, title, tooltip): item = QListWidgetItem(self.lilypond) item.setIcon(KIcon(icon)) item.setText("{0}\n{1}: {2}".format(title, i18n("Command"), path)) item.setToolTip(tooltip) version or item.setFlags(Qt.NoItemFlags) # Add all available LilyPond versions: for path in paths: if ver[path]: title = i18n("LilyPond %1", format(ver[path])) tooltip = i18n("Use LilyPond version %1", format(ver[path])) addenda, tips = [], [] if path == default: addenda.append(i18n("default")) tips.append(i18n("Default LilyPond Version.")) if path == autopath: addenda.append(i18n("automatic")) tips.append(i18n("Automatic LilyPond Version (determined from document).")) if addenda: title += " [{0}]".format(", ".join(addenda)) tooltip += "\n{0}".format("\n".join(tips)) addItem(format(ver[path]), path, "run-lilypond", title, tooltip + "\n" + i18n("Path: %1", ly.version.LilyPondInstance(path).command() or path)) else: addItem("", path, "dialog-error", i18n("LilyPond (version unknown)"), i18n("Use LilyPond (version unknown)\nPath: %1", ly.version.LilyPondInstance(path).command() or path)) # Copy the settings from the document: self.preview.setChecked(doc.metainfo["custom preview"]) self.verbose.setChecked(doc.metainfo["custom verbose"]) try: self.lilypond.setCurrentRow(versions.index( doc.metainfo["custom lilypond version"])) except ValueError: cmd = autopath if autopath and conf.readEntry("automatic version", False) else default self.lilypond.setCurrentRow(paths.index(cmd)) # Focus our listbox: self.lilypond.setFocus() # Disable the Run button if a job is running for this document oldjob = self.mainwin.jobManager().job(doc) self.enableButtonOk(not oldjob) if oldjob: enable = lambda: self.enableButtonOk(True) oldjob.done.connect(enable) # Wait for user interaction: result = self.exec_() # If a job was running, don't listen to it anymore if oldjob: oldjob.done.disconnect(enable) if not result: return False # cancelled # Save the settings in the document's metainfo and configure job: doc.metainfo["custom preview"] = job.preview = self.preview.isChecked() doc.metainfo["custom verbose"] = job.verbose = self.verbose.isChecked() index = self.lilypond.currentRow() doc.metainfo["custom lilypond version"] = versions[index] job.command = paths[index] return True
def ly(self): """ Return the LilyPond document to print the empty staff paper. """ staff = self.stack.currentWidget() output = [] version = lilyPondVersion() if version: output.append('\\version "{0}"\n'.format(version)) output.append('#(set-global-staff-size {0})\n'.format(self.staffSize.value())) # paper section output.append('\\paper {') if self.paperSize.currentIndex() > 0: output.append('#(set-paper-size "{0}")'.format(ly.paperSizes[self.paperSize.currentIndex()-1])) if self.pageNumbers.isChecked(): output.append('top-margin = 10\\mm') output.append('first-page-number = #{0}'.format(self.pageNumStart.value())) output.append('oddHeaderMarkup = \\markup \\fill-line {') output.append('\\strut') output.append("\\fromproperty #'page:page-number-string") output.append('}') else: output.append('top-margin = 16\\mm') output.append('oddHeaderMarkup = ##f') output.append('evenHeaderMarkup = ##f') if self.removeTagline.isChecked(): output.append('bottom-margin = 16\\mm') output.append('oddFooterMarkup = ##f') else: output.append('bottom-margin = 10\\mm') output.append('oddFooterMarkup = \\markup \\abs-fontsize #6 \\fill-line {') tagline = config().readEntry("tagline", '\\with-url #"http://www.frescobaldi.org/" FRESCOBALDI.ORG') output.append('\\sans {{ {0} }}'.format(tagline)) output.append('\\strut') output.append('}') output.append('evenFooterMarkup = ##f') output.append('ragged-last-bottom = ##f') output.append('ragged-right = ##f') output.append('}\n') # music expression output.append('music = \\repeat unfold {0} {{ % pages'.format(self.pageCount.value())) output.append('\\repeat unfold {0} {{ % systems'.format(staff.systemCount())) output.append('\\repeat unfold {0} {{ % bars'.format( self.barLines.isChecked() and self.barsPerLine.value() or 1)) output.extend(('r1', '\\noBreak', '}', '\\break', '\\noPageBreak', '}', '\\pageBreak', '}\n')) # get the layout layout = LayoutContexts() layout.add("Score", '\\remove "Bar_number_engraver"') layout.add("Voice", "\\override Rest #'stencil = ##f") music = staff.music(layout) layout.addToStaffContexts('\\remove "Time_signature_engraver"') if not self.barLines.isChecked(): layout.disableBarLines() # write it out output.append('\\layout {\nindent = #0') output.extend(layout.ly()) output.append('}\n') # score output.append('\\score {') output.extend(music) output.append('}\n') return ly.indent.indent('\n'.join(output))