if re.search(r'\\oldaddlyrics', str):
stderr_write (NOT_SMART % "oldaddlyrics")
stderr_write (_ ("oldaddlyrics is no longer supported. \n \
- Use addlyrics or lyrsicsto instead.\n"))
+ Use addlyrics or lyricsto instead.\n"))
stderr_write (UPDATE_MANUALLY)
raise FatalConversionError ()
return str
r"\1\2.\3", str)
str = re.sub (r'''(\\(?:alterBroken|overrideProperty)\s+)#?"([A-Za-z]+)\s*\.\s*([A-Za-z]+)"''',
r"\1\2.\3", str)
- str = re.sub (r'''(\\tweak\s+)#?"?([A-Za-z]+)"?\s+?#'([-A-Za-z]+)''',
+ str = re.sub (r'''(\\tweak\s+)#?"?([A-W][A-Za-z]*)"?\s+?#'([a-zX-Z][-A-Za-z]*)''',
r"\1\2.\3", str)
- str = re.sub (r'''(\\tweak\s+)#'([-A-Za-z]+)''',
+ str = re.sub (r'''(\\tweak\s+)#'([a-zX-Z][-A-Za-z]*)''',
r"\1\2", str)
str = re.sub ("(" + matchmarkup + ")|"
+ r"(\\footnote(?:\s*"
+ after_id, r'\1-\2', str)
return str
-@rule ((2, 19, 22), "(define-xxx-function (parser location ...) -> (define-xxx-function (...)")
+@rule ((2, 19, 22), """whiteout -> whiteout-box
+(define-xxx-function (parser location ...) -> (define-xxx-function (...)
+(xxx ... parser ...) -> (xxx ... ...)""")
def conv(str):
+ # whiteout -> whiteout-box
+ str = re.sub (r"\\whiteout(?![a-z_-])", r"\\whiteout-box", str)
+ str = re.sub (r"\b\.whiteout(?![a-z_-])\b", r".whiteout-box", str)
+ str = re.sub (r"#'whiteout(?![a-z_-])\b", r"#'whiteout-box", str)
+ str = re.sub (r"\bstencil-whiteout\b", r"stencil-whiteout-box", str)
+
+ # (define-xxx-function (parser location ...) -> (define-xxx-function (...)
def subst(m):
def subsub(m):
str = (m.group (1)
subsub, m.group (0))
str = re.sub (r'\(define-(?:music|event|scheme|void)-function(?=\s|["(])'
+ paren_matcher (20) + r'\)', subst, str)
+
+ # (xxx ... parser ...) -> (xxx ... ...)
+ def repl (m):
+ return m.group (1) + inner (m.group (2))
+ def inner (str):
+ str = re.sub (r"(\((?:" +
+ r"ly:parser-lexer|" +
+ r"ly:parser-clone|" +
+ r"ly:parser-output-name|" +
+ r"ly:parser-error|" +
+ r"ly:parser-define!|" +
+ r"ly:parser-lookup|" +
+ r"ly:parser-has-error\?|" +
+ r"ly:parser-clear-error|" +
+ r"ly:parser-set-note-names|" +
+ r"ly:parser-include-string|" +
+ r"note-names-language|" +
+ r"display-lily-music|" +
+ r"music->lily-string|" +
+ r"note-name->lily-string|" +
+ r"value->lily-string|"
+ r"check-grob-path|" +
+ r"event-chord-wrap!|" +
+ r"collect-bookpart-for-book|" +
+ r"collect-scores-for-book|" +
+ r"collect-music-aux|" +
+ r"collect-book-music-for-book|" +
+ r"scorify-music|" +
+ r"collect-music-for-book|" +
+ r"collect-book-music-for-book|" +
+ r"toplevel-book-handler|" +
+ r"default-toplevel-book-handler|" +
+ r"print-book-with-defaults|" +
+ r"toplevel-music-handler|" +
+ r"toplevel-score-handler|" +
+ r"toplevel-text-handler|" +
+ r"toplevel-bookpart-handler|" +
+ r"book-music-handler|" +
+ r"context-mod-music-handler|" +
+ r"bookpart-music-handler|" +
+ r"output-def-music-handler|" +
+ r"print-book-with-defaults-as-systems|" +
+ r"add-score|" +
+ r"add-text|" +
+ r"add-music|" +
+ r"make-part-combine-music|" +
+ r"make-directed-part-combine-music|" +
+ r"add-quotable|" +
+ r"paper-variable|" +
+ r"make-autochange-music|" +
+ r"context-mod-from-music|" +
+ r"context-defs-from-music)" +
+ r'(?=\s|[()]))(' + paren_matcher (20) + ")"
+ r"(?:\s+parser(?=\s|[()])|\s*\(\*parser\*\))", repl, str)
+ return str
+ str = inner (str)
+ # This is the simplest case, resulting from one music function
+ # trying to call another one via Scheme. The caller is supposed
+ # to have its uses of parser/location converted to
+ # (*parser*)/(*location*) already. Other uses of
+ # ly:music-function-extract are harder to convert but unlikely.
+ str = re.sub (r'(\(\s*\(ly:music-function-extract\s+' + wordsyntax +
+ r'\s*\)\s+)\(\*parser\*\)\s*\(\*location\*\)', r'\1',
+ str)
+ return str
+
+@rule ((2, 19, 24), r"""music-has-type -> music-is-of-type?
+\applyOutput #'Context -> \applyOutput Context""")
+def conv (str):
+ str = re.sub (r'(?<=\s|["\\()])' + "music-has-type" + r'(?=\s|["\\()])',
+ "music-is-of-type?", str)
+ str = re.sub (r"(\\applyOutput\s+)#'([a-zA-Z])", r"\1\2", str)
+ return str
+
+@rule ((2, 19, 28), r"c:5.x, c:5^x, c:sus -> c:3.5.x, c:3.5^x, c:5")
+def conv (str):
+ str = re.sub (r":5([.^][1-9])", r":3.5\1", str)
+ # row back for self-defeating forms
+ str = re.sub (r":3\.5((?:\.[0-9]+)*\^(?:[0-9]+\.)*)3\.", r":5\1", str)
+ str = re.sub (r":3\.5((?:\.[0-9]+)*\^?:[0-9]+(?:\.[0-9]+)*)\.3(?![.0-9])", r":5\1", str)
+ str = re.sub (r":3\.5((?:\.[0-9]+)*)\^3(?=\s|\})", r":5\1", str)
+ str = re.sub (r":sus(?=\s|\})", ":5", str)
+ str = re.sub (r":1\.5(?=\s|[.^}])", r":5", str)
+ return str
+
+@rule ((2, 19, 29), r"partcombine*Once -> \once \partcombine*")
+def conv(str):
+ str = re.sub (r"(\\partcombine(?:Apart|Chords|Unisono|SoloII?|Automatic))Once\b",
+ r"\\once \1", str)
+ str = re.sub (r"(\\partcombineForce" + matcharg + r")\s*##f(\s)",
+ r"\1\2", str)
+ str = re.sub (r"(\\partcombineForce" + matcharg + r")\s*##t(\s)",
+ r"\\once \1\2", str)
+ return str
+
+@rule ((2, 19, 32), r"whiteout-box -> whiteout")
+def conv(str):
+ str = re.sub (r"\\whiteout-box(?![a-z_-])", r"\\whiteout", str)
+ str = re.sub (r"\b\.whiteout-box(?![a-z_-])\b", r".whiteout", str)
+ str = re.sub (r"#'whiteout-box(?![a-z_-])\b", r"#'whiteout", str)
+ return str
+
+@rule ((2, 19, 40), r"\time #'(2 3) ... -> \time 2,3 ...")
+def conv (str):
+ def repl (m):
+ return m.group(1) + re.sub (r"\s+", ",", m.group (2))
+
+ str = re.sub (r"(beatStructure\s*=\s*)#'\(([0-9]+(?:\s+[0-9]+)+)\)",
+ repl, str)
+
+ str = re.sub (r"(\\time\s*)#'\(([0-9]+(?:\s+[0-9]+)+)\)", repl, str)
+ def repl (m):
+ subst = re.sub (r"\s+", ",", m.group (1))
+ return subst + (4 + len (m.group (1)) - len (subst)) * " " + m.group (2)
+
+ str = re.sub (r"#'\(([0-9]+(?:\s+[0-9]+)+)\)(\s+%\s*beatStructure)",
+ repl, str)
+ return str
+
+@rule ((2, 19, 46), r"""\context ... \modification -> \context ... \with \modification
+\consists "Output_property_engraver" ->""")
+def conv (str):
+ word=r'(?:#?"[^"]*"|\b' + wordsyntax + r'\b)'
+ mods = string.join (re.findall ("\n(" + wordsyntax + r")\s*=\s*\\with(?:\s|\\|\{)", str)
+ + ['RemoveEmptyStaves','RemoveAllEmptyStaves'], "|")
+ str = re.sub (r"(\\(?:drums|figures|chords|lyrics|addlyrics|"
+ + r"(?:new|context)\s*" + word
+ + r"(?:\s*=\s*" + word + r")?)\s*)(\\(?:" + mods + "))",
+ r"\1\\with \2", str)
+
+ str = re.sub (r'\\(consists|remove)\s+"?Output_property_engraver"?\s*',
+ '', str)
+ return str
+
+@rule ((2, 19, 49), r"""id -> output-attributes.id or output-attributes
+for \tweak, \override, \overrideProperty, and \revert""")
+def conv (str):
+ # path cannot start with '-' or '_' and matches zero or more path
+ # units that each end in a dot
+ path = r"(?:[a-zA-Z\200-\377](?:[-_]?[a-zA-Z\200-\377])*(?:\s*\.\s*))*"
+
+ # Manual editing is needed when id is set to #(...) or \xxx
+ manual_edits = r"(\\(?:tweak|override|overrideProperty)\s+" + path + r")id(\s*=?\s*(?:\\|#\s*\())"
+ automatic = r"(\\(?:tweak|override|overrideProperty|revert)\s+" + path + r")id"
+ if re.search (manual_edits, str):
+ stderr_write (NOT_SMART % "\"output-attributes\"")
+ stderr_write (_ ("Previously the \"id\" grob property (string) was used for SVG output.") + "\n")
+ stderr_write (_ ("Now \"output-attributes\" (association list) is used instead.") + "\n")
+ stderr_write (UPDATE_MANUALLY)
+
+ # First, for manual editing cases we convert 'id' to 'output-attributes'
+ # because Grob.output-attributes.id = #(lambda ... ) will not work.
+ # Then for the rest we convert 'id' to 'output-attributes.id'
+ str = re.sub (manual_edits, r"\1output-attributes\2", str)
+ str = re.sub (automatic, r"\1output-attributes.id", str)
return str
# Guidelines to write rules (please keep this at the end of this file)