def _add_container_identifiers(self): if self.environment == "docs" and not getattr( self, "test_container_identifiers", False ): return segment_name = self.segment_name or "" segment_name = String(segment_name).to_segment_lilypond_identifier() contexts = [] try: context = self.score["Global_Skips"] contexts.append(context) except ValueError: pass try: context = self.score["Global_Rests"] contexts.append(context) except ValueError: pass for voice in iterate(self.score).components(Voice): if inspect(voice).annotation("INTERMITTENT") is True: continue contexts.append(voice) container_to_part_assignment = OrderedDict() for context in contexts: if segment_name: context_identifier = f"{segment_name}_{context.name}" else: context_identifier = context.name context.identifier = f"%*% {context_identifier}" part_container_count = 0 for container in iterate(context).components(Container): if not container.identifier: continue if container.identifier.startswith("%*% Part"): part_container_count += 1 globals_ = globals() part = container.identifier.strip("%*% ") part = eval(part, globals_) suffix = String().base_26(part_container_count).lower() container_identifier = f"{context_identifier}_{suffix}" container_identifier = String(container_identifier) assert container_identifier.is_lilypond_identifier() assert ( container_identifier not in container_to_part_assignment ) timespan = inspect(container).timespan() pair = (part, timespan) container_to_part_assignment[container_identifier] = pair container.identifier = f"%*% {container_identifier}" for staff in iterate(self.score).components(Staff): if segment_name: context_identifier = f"{segment_name}_{staff.name}" else: context_identifier = staff.name staff.identifier = f"%*% {context_identifier}" self._container_to_part_assignment = container_to_part_assignment
def _add_container_identifiers(self): if (self.environment == 'docs' and not getattr(self, 'test_container_identifiers', False)): return segment_name = self.segment_name or '' segment_name = String(segment_name).to_segment_lilypond_identifier() contexts = [] try: context = self.score['Global_Skips'] contexts.append(context) except ValueError: pass try: context = self.score['Global_Rests'] contexts.append(context) except ValueError: pass for voice in iterate(self.score).components(Voice): if inspect(voice).annotation('INTERMITTENT') is True: continue contexts.append(voice) container_to_part_assignment = OrderedDict() for context in contexts: if segment_name: context_identifier = f'{segment_name}_{context.name}' else: context_identifier = context.name context.identifier = f'%*% {context_identifier}' part_container_count = 0 for container in iterate(context).components(Container): if not container.identifier: continue if container.identifier.startswith('%*% Part'): part_container_count += 1 globals_ = globals() part = container.identifier.strip('%*% ') part = eval(part, globals_) suffix = String().base_26(part_container_count).lower() container_identifier = f'{context_identifier}_{suffix}' container_identifier = String(container_identifier) assert container_identifier.is_lilypond_identifier() assert container_identifier not in \ container_to_part_assignment timespan = inspect(container).timespan() pair = (part, timespan) container_to_part_assignment[container_identifier] = pair container.identifier = f'%*% {container_identifier}' for staff in iterate(self.score).components(Staff): if segment_name: context_identifier = f'{segment_name}_{staff.name}' else: context_identifier = staff.name staff.identifier = f'%*% {context_identifier}' self._container_to_part_assignment = container_to_part_assignment
def __init__( self, name: str = None, *, direction: typing.Union[str, enums.VerticalAlignment] = None, tweaks: LilyPondTweakManager = None, ) -> None: if isinstance(name, type(self)): argument = name name = argument.name direction = direction or argument.direction name = str(name) if "\\" in name: raise Exception("DEPRECATED?") direction, name = name.split("\\") direction = direction.strip() name = name.strip() self._name = name direction_ = String.to_tridirectional_ordinal_constant(direction) if direction_ is not None: assert isinstance(direction_, enums.VerticalAlignment), repr( direction_ ) assert direction_ in (enums.Up, enums.Down, enums.Center), repr( direction_ ) self._direction = direction_ self._format_slot = "after" if tweaks is not None: assert isinstance(tweaks, LilyPondTweakManager), repr(tweaks) self._tweaks = LilyPondTweakManager.set_tweaks(self, tweaks)
def __init__( self, *, beam_lone_notes: bool = None, beam_rests: bool = None, direction: typing.Union[str, enums.VerticalAlignment] = None, durations: typing.Iterable[Duration] = None, span_beam_count: int = 1, stemlet_length: typings.Number = None, ) -> None: Spanner.__init__(self) direction = String.to_tridirectional_lilypond_symbol(direction) if beam_lone_notes is not None: beam_lone_notes = bool(beam_lone_notes) self._beam_lone_notes = beam_lone_notes if beam_rests is not None: beam_rests = bool(beam_rests) self._beam_rests = beam_rests self._direction = direction durations = self._coerce_durations(durations) self._durations: typing.Tuple[Duration, ...] = durations if span_beam_count is not None: assert isinstance(span_beam_count, int) self._span_beam_count = span_beam_count self._stemlet_length = stemlet_length
def __init__( self, descriptor: str = None, *, direction: enums.VerticalAlignment = None, ) -> None: Spanner.__init__(self) direction_ = String.to_tridirectional_lilypond_symbol(direction) self._direction = direction_ self._descriptor: typing.Optional[str] = None if descriptor is not None: assert self._is_valid_descriptor(descriptor), repr(descriptor) result = self._parse_descriptor(descriptor) start_dynamic, shape_string, stop_dynamic = result self._descriptor = descriptor assert shape_string in ('<', '>') self._shape_string = shape_string if start_dynamic is not None: start_dynamic = Dynamic(start_dynamic) self._start_dynamic = start_dynamic if stop_dynamic is not None: stop_dynamic = Dynamic(stop_dynamic) self._stop_dynamic = stop_dynamic else: self._descriptor = None self._shape_string = None self._start_dynamic = None self._stop_dynamic = None
def _format_effort_dynamic(self): name = self.name.strip('"') before = { "f": -0.4, "m": -0.1, "p": -0.1, "r": -0.1, "s": -0.3, "z": -0.2, }[name[0]] after = {"f": -0.2, "m": -0.1, "p": -0.25, "r": 0, "s": 0, "z": -0.2}[ name[-1] ] direction = self.direction direction = String.to_tridirectional_lilypond_symbol(direction) strings = [] strings.append(f"{direction} #(make-dynamic-script") strings.append(" (markup") strings.append(" #:whiteout") strings.append(" #:line (") strings.append( ' #:general-align Y -2 #:normal-text #:larger "“"' ) strings.append(f" #:hspace {before}") strings.append(f' #:dynamic "{name}"') strings.append(f" #:hspace {after}") strings.append( ' #:general-align Y -2 #:normal-text #:larger "”"' ) strings.append(" )") strings.append(" )") strings.append(" )") string = "\n".join(strings) return string
def __init__( self, name: str = None, *, direction: typing.Union[str, enums.VerticalAlignment] = None, tweaks: LilyPondTweakManager = None, ) -> None: if isinstance(name, type(self)): argument = name name = argument.name direction = direction or argument.direction name = str(name) if '\\' in name: raise Exception('DEPRECATED?') direction, name = name.split('\\') direction = direction.strip() name = name.strip() self._name = name direction_ = String.to_tridirectional_ordinal_constant(direction) if direction_ is not None: assert isinstance(direction_, enums.VerticalAlignment), repr(direction_) assert direction_ in (enums.Up, enums.Down, enums.Center), repr(direction_) self._direction = direction_ self._format_slot = 'after' if tweaks is not None: assert isinstance(tweaks, LilyPondTweakManager), repr(tweaks) self._tweaks = LilyPondTweakManager.set_tweaks(self, tweaks)
def __init__( self, name: str = None, *, direction: typing.Union[str, enums.VerticalAlignment] = None, tweaks: LilyPondTweakManager = None, ) -> None: if isinstance(name, type(self)): argument = name name = argument.name direction = direction or argument.direction name = str(name) if "\\" in name: message = "articulation names need no backslash:\n" message += f" {repr(name)}" raise Exception(message) self._name = name direction_ = String.to_tridirectional_ordinal_constant(direction) if direction_ is not None: assert isinstance(direction_, enums.VerticalAlignment), repr(direction_) assert direction_ in (enums.Up, enums.Down, enums.Center), repr(direction_) self._direction = direction_ self._format_slot = "after" if tweaks is not None: assert isinstance(tweaks, LilyPondTweakManager), repr(tweaks) self._tweaks = LilyPondTweakManager.set_tweaks(self, tweaks)
def __init__( self, *, direction: typing.Union[str, enums.VerticalAlignment] = None, ) -> None: Spanner.__init__(self) direction_ = String.to_tridirectional_lilypond_symbol(direction) self._direction = direction_
def _format_textual(direction, string): if direction is None: direction = enums.Down direction = String.to_tridirectional_lilypond_symbol(direction) assert isinstance(string, str), repr(string) string = f'(markup #:whiteout #:normal-text #:italic "{string}")' string = f"{direction} #(make-dynamic-script {string})" return string
def _get_format_specification(self): values = self._value if String.is_string(self._value): values = [self._value] return FormatSpecification( client=self, storage_format_args_values=values, storage_format_kwargs_names=[], )
def __init__(self, *, direction: int = None, tweaks: LilyPondTweakManager = None) -> None: direction_ = String.to_tridirectional_lilypond_symbol(direction) self._direction = direction_ if tweaks is not None: assert isinstance(tweaks, LilyPondTweakManager), repr(tweaks) self._tweaks = LilyPondTweakManager.set_tweaks(self, tweaks)
def __str__(self) -> str: """ Gets string representation of articulation. """ if self.name: string = self._shortcut_to_word.get(self.name) if not string: string = self.name if self.direction is None: direction = String("-") else: direction_ = String.to_tridirectional_lilypond_symbol( self.direction) assert isinstance(direction_, String), repr(direction) direction = direction_ return fr"{direction} \{string}" else: return ""
def __getattr__(self, name: str) -> typing.Any: r""" Gets arbitrary object keyed to ``name``. .. container:: example >>> staff = abjad.Staff("c'4 d' e' f'") >>> abjad.setting(staff).instrument_name = abjad.Markup('Vn. I') >>> abjad.show(staff) # doctest: +SKIP .. docs:: >>> abjad.f(staff) \new Staff \with { instrumentName = \markup { "Vn. I" } } { c'4 d'4 e'4 f'4 } .. container:: example Returns arbitrary object keyed to ``name``: >>> abjad.setting(staff).instrument_name Markup(contents=['Vn. I']) """ from abjad.ly import contexts camel_name = String(name).to_upper_camel_case() if name.startswith('_'): try: return vars(self)[name] except KeyError: type_name = type(self).__name__ message = '{type_name!r} object has no attribute: {name!r}.' raise AttributeError(message) elif camel_name in contexts: try: return vars(self)['_' + name] except KeyError: context = LilyPondNameManager() vars(self)['_' + name] = context return context else: try: return vars(self)[name] except KeyError: type_name = type(self).__name__ message = '{type_name!r} object has no attribute: {name!r}.' raise AttributeError(message)
def make_lilypond_override_string( grob, attribute, value, context=None, once=False ) -> str: """ Makes Lilypond override string. """ grob = String(grob).to_upper_camel_case() attribute = LilyPondFormatManager.format_lilypond_attribute(attribute) value = LilyPondFormatManager.format_lilypond_value(value) if context is not None: context = String(context).capitalize_start() + "." else: context = "" if once is True: once = r"\once " else: once = "" result = rf"{once}\override {context}{grob}.{attribute} = {value}" return result
def __init__( self, *, direction: enums.VerticalAlignment = None, tweaks: LilyPondTweakManager = None, ) -> None: direction_ = String.to_tridirectional_lilypond_symbol(direction) self._direction = direction_ if tweaks is not None: assert isinstance(tweaks, LilyPondTweakManager), repr(tweaks) self._tweaks = LilyPondTweakManager.set_tweaks(self, tweaks)
def make_lilypond_revert_string(grob, attribute, context=None) -> str: r""" Makes LilyPond revert string. .. container:: example >>> abjad.LilyPondFormatManager.make_lilypond_revert_string( ... 'glissando', ... 'bound_details__right__arrow', ... ) '\\revert Glissando.bound-details.right.arrow' """ grob = String(grob).to_upper_camel_case() dotted = LilyPondFormatManager.format_lilypond_attribute(attribute) if context is not None: context = String(context).to_upper_camel_case() context += '.' else: context = '' result = rf'\revert {context}{grob}.{dotted}' return result
def _get_lilypond_format(self): if self.command: string = self.command elif self.effort: string = self._format_effort_dynamic() elif self.name_is_textual: string = self._format_textual(self.direction, self.name) else: string = rf"\{self.name}" if self.direction is not None: direction_ = self.direction direction = String.to_tridirectional_lilypond_symbol(direction_) string = f"{direction} {string}" return string
def __init__( self, shape="<", *, direction: enums.VerticalAlignment = None, tweaks: LilyPondTweakManager = None, ) -> None: direction_ = String.to_tridirectional_lilypond_symbol(direction) self._direction = direction_ assert shape in self._known_shapes, repr(shape) self._shape = shape if tweaks is not None: assert isinstance(tweaks, LilyPondTweakManager), repr(tweaks) self._tweaks = LilyPondTweakManager.set_tweaks(self, tweaks)
def __init__( self, *, direction: enums.VerticalAlignment = None, tweaks: LilyPondTweakManager = None, ) -> None: direction_ = String.to_tridirectional_ordinal_constant(direction) if direction_ is not None: assert isinstance(direction_, enums.VerticalAlignment), repr(direction_) directions = (enums.Up, enums.Down, enums.Center, None) assert direction_ in directions, repr(direction_) self._direction = direction_ if tweaks is not None: assert isinstance(tweaks, LilyPondTweakManager), repr(tweaks) self._tweaks = LilyPondTweakManager.set_tweaks(self, tweaks)
def __init__( self, *, direction: enums.VerticalAlignment = None, left_broken: bool = None, tweaks: LilyPondTweakManager = None, ) -> None: direction_ = String.to_tridirectional_lilypond_symbol(direction) self._direction = direction_ if left_broken is not None: left_broken = bool(left_broken) self._left_broken = left_broken if tweaks is not None: assert isinstance(tweaks, LilyPondTweakManager), repr(tweaks) self._tweaks = LilyPondTweakManager.set_tweaks(self, tweaks)
def __str__(self) -> str: r""" Gets string representation of staccato. .. container:: example >>> str(abjad.Staccato()) '\\staccato' """ string = r"\staccato" if self.direction is None: return string direction = String.to_tridirectional_lilypond_symbol(self.direction) assert isinstance(direction, String), repr(direction) return fr"{direction} {string}"
def __init__( self, *, command: str = r'\startTextSpan', concat_hspace_left: typings.Number = 0.5, concat_hspace_right: typings.Number = None, direction: enums.VerticalAlignment = None, left_broken_text: typing.Union[bool, LilyPondLiteral, markups.Markup] = None, left_text: typing.Union[LilyPondLiteral, markups.Markup] = None, right_padding: typings.Number = None, right_text: typing.Union[LilyPondLiteral, markups.Markup] = None, style: str = None, tweaks: typing.Union[typing.List[typing.Tuple], LilyPondTweakManager] = None, ) -> None: assert isinstance(command, str), repr(command) assert command.startswith('\\'), repr(command) self._command = command if concat_hspace_left is not None: assert isinstance(concat_hspace_left, (int, float)) self._concat_hspace_left = concat_hspace_left if concat_hspace_right is not None: assert isinstance(concat_hspace_right, (int, float)) self._concat_hspace_right = concat_hspace_right direction_ = String.to_tridirectional_lilypond_symbol(direction) self._direction = direction_ if left_broken_text is not None: assert isinstance(left_broken_text, (bool, markups.Markup)) self._left_broken_text = left_broken_text if left_text is not None: prototype = (LilyPondLiteral, markups.Markup) assert isinstance(left_text, prototype), repr(left_text) self._left_text = left_text if right_padding is not None: assert isinstance(right_padding, (int, float)), repr(right_padding) self._right_padding = right_padding if right_text is not None: prototype = (LilyPondLiteral, markups.Markup) assert isinstance(right_text, prototype), repr(right_text) self._right_text = right_text if style is not None: assert style in self._styles, repr(style) self._style = style self._tweaks = None LilyPondTweakManager.set_tweaks(self, tweaks)
def __init__( self, *, direction: enums.VerticalAlignment = None, tweaks: LilyPondTweakManager = None, ) -> None: direction_ = String.to_tridirectional_ordinal_constant(direction) if direction_ is not None: assert isinstance(direction_, enums.VerticalAlignment), repr( direction_ ) directions = (enums.Up, enums.Down, enums.Center, None) assert direction_ in directions, repr(direction_) self._direction = direction_ if tweaks is not None: assert isinstance(tweaks, LilyPondTweakManager), repr(tweaks) self._tweaks = LilyPondTweakManager.set_tweaks(self, tweaks)
def __init__( self, *, command: str = r"\startTextSpan", concat_hspace_left: typings.Number = 0.5, concat_hspace_right: typings.Number = None, direction: enums.VerticalAlignment = None, left_broken_text: typing.Union[bool, str, markups.Markup] = None, left_text: typing.Union[str, markups.Markup] = None, right_padding: typings.Number = None, right_text: typing.Union[str, markups.Markup] = None, style: str = None, tweaks: LilyPondTweakManager = None, ) -> None: assert isinstance(command, str), repr(command) assert command.startswith("\\"), repr(command) self._command = command if concat_hspace_left is not None: assert isinstance(concat_hspace_left, (int, float)) self._concat_hspace_left = concat_hspace_left if concat_hspace_right is not None: assert isinstance(concat_hspace_right, (int, float)) self._concat_hspace_right = concat_hspace_right direction_ = String.to_tridirectional_lilypond_symbol(direction) self._direction = direction_ if left_broken_text is not None: assert isinstance(left_broken_text, (bool, markups.Markup)) self._left_broken_text = left_broken_text if left_text is not None: prototype = (str, markups.Markup) assert isinstance(left_text, prototype), repr(left_text) self._left_text = left_text if right_padding is not None: assert isinstance(right_padding, (int, float)), repr(right_padding) self._right_padding = right_padding if right_text is not None: prototype = (str, markups.Markup) assert isinstance(right_text, prototype), repr(right_text) self._right_text = right_text if style is not None: assert style in self._styles, repr(style) self._style = style if tweaks is not None: assert isinstance(tweaks, LilyPondTweakManager), repr(tweaks) self._tweaks = LilyPondTweakManager.set_tweaks(self, tweaks)
def __init__( self, shape="<", *, direction: enums.VerticalAlignment = None, left_broken: bool = None, tweaks: LilyPondTweakManager = None, ) -> None: direction_ = String.to_tridirectional_lilypond_symbol(direction) self._direction = direction_ if left_broken is not None: left_broken = bool(left_broken) self._left_broken = left_broken assert shape in self._known_shapes, repr(shape) self._shape = shape if tweaks is not None: assert isinstance(tweaks, LilyPondTweakManager), repr(tweaks) self._tweaks = LilyPondTweakManager.set_tweaks(self, tweaks)
def make_lilypond_tweak_string( attribute, value, directed=True, grob=None ) -> str: r""" Makes Lilypond \tweak string. Returns string. """ if grob is not None: grob = String(grob).to_upper_camel_case() grob += "." else: grob = "" attribute = LilyPondFormatManager.format_lilypond_attribute(attribute) value = LilyPondFormatManager.format_lilypond_value(value) string = rf"\tweak {grob}{attribute} {value}" if directed: string = "- " + string return string
def __str__(self) -> str: """ Gets string representation of articulation. """ if self.name: string = self._shortcut_to_word.get(self.name) if not string: string = self.name if self.direction is None: direction = String("-") else: direction_ = String.to_tridirectional_lilypond_symbol( self.direction ) assert isinstance(direction_, String), repr(direction) direction = direction_ return fr"{direction} \{string}" else: return ""
def __init__( self, *, direction: typing.Union[str, enums.VerticalAlignment] = None, left_broken: bool = None, repeat: typing.Union[bool, typings.IntegerPair, DurationInequality, ] = None, right_broken: bool = None, ) -> None: Spanner.__init__(self) direction = String.to_tridirectional_lilypond_symbol(direction) self._direction = direction if left_broken is not None: left_broken = bool(left_broken) self._left_broken = left_broken repeat_ = repeat repeat_ = self._coerce_inequality(repeat) if repeat_ is not None: assert isinstance(repeat_, (bool, DurationInequality)) self._repeat = repeat_ if right_broken is not None: right_broken = bool(right_broken) self._right_broken = right_broken
def _format_effort_dynamic(self): name = self.name.strip('"') before = { 'f': -0.4, 'm': -0.1, 'p': -0.1, 'r': -0.1, 's': -0.3, 'z': -0.2, }[name[0]] after = { 'f': -0.2, 'm': -0.1, 'p': -0.25, 'r': 0, 's': 0, 'z': -0.2, }[name[-1]] direction = self.direction direction = String.to_tridirectional_lilypond_symbol(direction) strings = [] strings.append(f'{direction} #(make-dynamic-script') strings.append(' (markup') strings.append(' #:whiteout') strings.append(' #:line (') strings.append( ' #:general-align Y -2 #:normal-text #:larger "“"') strings.append(f' #:hspace {before}') strings.append(f' #:dynamic "{name}"') strings.append(f' #:hspace {after}') strings.append( ' #:general-align Y -2 #:normal-text #:larger "”"') strings.append(' )') strings.append(' )') strings.append(' )') string = '\n'.join(strings) return string
def _add_container_identifiers(self): if self.environment == "docs" and not getattr( self, "test_container_identifiers", False): return segment_name = self.segment_name or "" segment_name = String(segment_name).to_segment_lilypond_identifier() contexts = [] try: context = self.score["Global_Skips"] contexts.append(context) except ValueError: pass try: context = self.score["Global_Rests"] contexts.append(context) except ValueError: pass for voice in iterate(self.score).components(Voice): if inspect(voice).has_indicator(const.INTERMITTENT): continue contexts.append(voice) container_to_part_assignment = OrderedDict() context_name_counts = {} for context in contexts: if context.name is None: message = "all contexts must be named:\n" message += f" {repr(context)}" raise Exception(message) count = context_name_counts.get(context.name, 0) if count == 0: suffixed_context_name = context.name else: suffix = String.base_26(count) suffixed_context_name = f"{context.name}_{suffix}" context_name_counts[context.name] = count + 1 if segment_name: context_identifier = f"{segment_name}_{suffixed_context_name}" else: context_identifier = suffixed_context_name context.identifier = f"%*% {context_identifier}" part_container_count = 0 for container in iterate(context).components(Container): if not container.identifier: continue if container.identifier.startswith("%*% Part"): part_container_count += 1 globals_ = globals() part = container.identifier.strip("%*% ") part = eval(part, globals_) suffix = String().base_26(part_container_count).lower() container_identifier = f"{context_identifier}_{suffix}" container_identifier = String(container_identifier) assert container_identifier.is_lilypond_identifier() assert (container_identifier not in container_to_part_assignment) timespan = inspect(container).timespan() pair = (part, timespan) container_to_part_assignment[container_identifier] = pair container.identifier = f"%*% {container_identifier}" for staff in iterate(self.score).components(Staff): if segment_name: context_identifier = f"{segment_name}_{staff.name}" else: context_identifier = staff.name staff.identifier = f"%*% {context_identifier}" self._container_to_part_assignment = container_to_part_assignment
def __call__(self) -> typing.List[String]: """ Calls job on job ``path``. """ messages = [] if self.title is not None: messages.append(String(self.title).capitalize_start()) total_count = 0 if isinstance(self.path, str): text = self.path if self.deactivate_first is True: if self.deactivate is not None: assert isinstance(self.deactivate, tuple) match, name = self.deactivate if match is not None: if isinstance(self.path, Path): count, skipped, messages_ = self.path.deactivate( match, indent=1, message_zero=True, name=name, ) messages.extend(messages_) total_count += count else: assert isinstance(self.path, str) text, count, skipped = deactivate( text, match, skipped=True, ) if self.activate is not None: assert isinstance(self.activate, tuple) match, name = self.activate if match is not None: if isinstance(self.path, Path): count, skipped, messages_ = self.path.activate( match, indent=1, message_zero=True, name=name, ) messages.extend(messages_) total_count += count else: assert isinstance(self.path, str) text, count, skipped = activate( text, match, skipped=True, ) if self.deactivate_first is not True: if self.deactivate is not None: assert isinstance(self.deactivate, tuple) match, name = self.deactivate if match is not None: if isinstance(self.path, Path): count, skipped, messages_ = self.path.deactivate( match, indent=1, message_zero=True, name=name, ) messages.extend(messages_) total_count += count else: assert isinstance(self.path, str) text, count, skipped = deactivate( text, match, skipped=True, ) if total_count == 0 and not self.message_zero: messages = [] if isinstance(self.path, Path): return messages else: assert isinstance(self.path, str) return text
def __getattr__( self, name ) -> typing.Union[LilyPondNameManager, 'LilyPondGrobNameManager']: r""" Gets LilyPondNameManager (or LilyPondGrobNameManager) keyed to ``name``. .. container:: example Somewhat confusingly, getting a grob name returns a LilyPondNameManager: >>> staff = abjad.Staff("c'4 d' e' f'") >>> abjad.override(staff[0]).note_head LilyPondNameManager() While getting a context name returns a LilyPondGrobNameManager: >>> staff = abjad.Staff("c'4 d' e' f'") >>> abjad.override(staff[0]).staff LilyPondGrobNameManager() Which can then be deferenced to get a LilyPondNameManager: >>> staff = abjad.Staff("c'4 d' e' f'") >>> abjad.override(staff[0]).staff.note_head LilyPondNameManager() Note that the dot-chained user syntax is unproblematic. But the class of each manager returned in the chain is likely to be surprising at first encounter. """ from abjad.ly import contexts from abjad.ly import grob_interfaces camel_name = String(name).to_upper_camel_case() if name.startswith('_'): try: return vars(self)[name] except KeyError: type_name = type(self).__name__ message = '{type_name!r} object has no attribute: {name!r}.' raise AttributeError(message) elif camel_name in contexts: try: return vars(self)['_' + name] except KeyError: context = LilyPondGrobNameManager() vars(self)['_' + name] = context return context elif camel_name in grob_interfaces: try: return vars(self)[name] except KeyError: vars(self)[name] = LilyPondNameManager() return vars(self)[name] else: try: return vars(self)[name] except KeyError: type_name = type(self).__name__ message = f'{type_name!r} object has no attribute: {name!r}.' raise AttributeError(message)
def __getattr__(self, name) -> typing.Union[LilyPondNameManager, typing.Any]: r""" Gets LilyPondNameManager (or LilyPondGrobNameManager) keyed to ``name``. .. container:: example Tweaks may be tagged: >>> staff = abjad.Staff("c'4 d' e' f'") >>> markup = abjad.Markup('Allegro', direction=abjad.Up).italic() >>> abjad.tweak(markup, tag=abjad.tags.ONLY_PARTS).color = 'red' >>> abjad.attach(markup, staff[0]) >>> abjad.show(staff) # doctest: +SKIP >>> abjad.f(staff) \new Staff { c'4 - \tweak color #red %! +PARTS ^ \markup { \italic Allegro } d'4 e'4 f'4 } Tweaks may be tagged with ``deactivate=True``: >>> staff = abjad.Staff("c'4 d' e' f'") >>> markup = abjad.Markup('Allegro', direction=abjad.Up).italic() >>> abjad.tweak( ... markup, deactivate=True, tag=abjad.tags.ONLY_PARTS ... ).color = 'red' >>> abjad.attach(markup, staff[0]) >>> abjad.show(staff) # doctest: +SKIP >>> abjad.f(staff) \new Staff { c'4 - \tweak color #red %! +PARTS ^ \markup { \italic Allegro } d'4 e'4 f'4 } Tweak tags and indicator tags may be set together: >>> staff = abjad.Staff("c'4 d' e' f'") >>> markup = abjad.Markup("Allegro", direction=abjad.Up).italic() >>> abjad.tweak(markup, tag=abjad.tags.ONLY_PARTS).color = "red" >>> abjad.attach(markup, staff[0], tag=abjad.Tag("RED:M1")) >>> abjad.show(staff) # doctest: +SKIP >>> abjad.f(staff, strict=40) \new Staff { c'4 - \tweak color #red %! +PARTS ^ \markup { %! RED:M1 \italic %! RED:M1 Allegro %! RED:M1 } %! RED:M1 d'4 e'4 f'4 } .. container:: example Preloaded tweak managers can be made like this: >>> tweaks = abjad.LilyPondTweakManager() >>> tweaks.color = 'red' >>> tweaks.Y_offset = 6 >>> tweaks LilyPondTweakManager(('Y_offset', 6), ('_literal', None), ('color', 'red')) Use the ``abjad.tweak()`` factory function for a shortcut: >>> tweaks = abjad.tweak('red').color >>> tweaks LilyPondTweakManager(('_literal', None), ('color', 'red')) >>> tweaks.Y_offset = 6 >>> tweaks LilyPondTweakManager(('Y_offset', 6), ('_literal', None), ('color', 'red')) .. container:: example Set long LilyPond grob chains like this: >>> abjad.tweak(False).bound_details__left_broken__text LilyPondTweakManager(('_literal', None), ('bound_details__left_broken__text', False)) """ from abjad.ly import contexts from abjad.ly import grob_interfaces if name == "_currently_deactivated": return vars(self).get("_currently_deactivated") if name == "_currently_tagging": return vars(self).get("_currently_tagging") if name == "_literal": return vars(self).get("_literal") if "_pending_value" in vars(self): _pending_value = self._pending_value self.__setattr__(name, _pending_value) delattr(self, "_pending_value") return self camel_name = String(name).to_upper_camel_case() if name.startswith("_"): try: return vars(self)[name] except KeyError: type_name = type(self).__name__ message = f"{type_name} object has no attribute {name!r}." raise AttributeError(message) elif camel_name in grob_interfaces: try: return vars(self)[name] except KeyError: vars(self)[name] = LilyPondNameManager() return vars(self)[name] else: try: return vars(self)[name] except KeyError: type_name = type(self).__name__ message = f"{type_name} object has no attribute {name!r}." raise AttributeError(message)
def __getattr__(self, name) -> typing.Union[LilyPondNameManager, typing.Any, ]: r""" Gets LilyPondNameManager (or LilyPondGrobNameManager) keyed to ``name``. .. container:: example Getting a grob name returns a LilyPondNameManager: >>> hairpin = abjad.Hairpin('p < f') >>> abjad.tweak(hairpin).dynamic_line_spanner LilyPondNameManager() Set a tweak with explicit grob like this: >>> abjad.tweak(hairpin).dynamic_line_spanner.staff_padding = 5 This changes tweak manager state: >>> abjad.tweak(hairpin) LilyPondTweakManager(('dynamic_line_spanner', LilyPondNameManager(('staff_padding', 5)))) Grob is available like this: >>> abjad.tweak(hairpin).dynamic_line_spanner LilyPondNameManager(('staff_padding', 5)) Attribute is available like this: >>> abjad.tweak(hairpin).dynamic_line_spanner.staff_padding 5 Grob-explicit tweak appears like this: >>> staff = abjad.Staff("c'4 d' e' f'") >>> abjad.attach(hairpin, staff[:]) >>> abjad.show(staff) # doctest: +SKIP .. docs:: >>> abjad.f(staff) \new Staff { c'4 - \tweak DynamicLineSpanner.staff-padding #5 \< \p d'4 e'4 f'4 \f } .. container:: example Tweak expressions work like this: >>> abjad.tweak('red').color LilyPondTweakManager(('color', 'red')) >>> abjad.tweak(6).Y_offset LilyPondTweakManager(('Y_offset', 6)) >>> abjad.tweak(False).bound_details__left_broken__text LilyPondTweakManager(('bound_details__left_broken__text', False)) """ from abjad.ly import contexts from abjad.ly import grob_interfaces if '_pending_value' in vars(self): _pending_value = self._pending_value self.__setattr__(name, _pending_value) delattr(self, '_pending_value') return self camel_name = String(name).to_upper_camel_case() if name.startswith('_'): try: return vars(self)[name] except KeyError: type_name = type(self).__name__ message = f'{type_name} object has no attribute {name!r}.' raise AttributeError(message) elif camel_name in grob_interfaces: try: return vars(self)[name] except KeyError: vars(self)[name] = LilyPondNameManager() return vars(self)[name] else: try: return vars(self)[name] except KeyError: type_name = type(self).__name__ message = f'{type_name} object has no attribute {name!r}.' raise AttributeError(message)