+@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
+