Source code for inscriptis.model.canvas.prefix

"""Manage the horizontal prefix (left-indentation, bullets) of canvas lines."""

from contextlib import suppress

[docs]class Prefix: """Class Prefix manages paddings and bullets that prefix an HTML block. Attributes: current_padding: the number of characters used for the current left-indentation. paddings: the list of paddings for the current and all previous tags. bullets: the list of bullets in the current and all previous tags. consumed: whether the current bullet has already been consumed. """ __slots__ = ('current_padding', 'paddings', 'bullets', 'consumed') def __init__(self): self.current_padding = 0 self.paddings = [] self.bullets = [] self.consumed = False
[docs] def register_prefix(self, padding_inline, bullet): """Register the given prefix. Args: padding_inline: the number of characters used for padding_inline bullet: an optional bullet. """ self.current_padding += padding_inline self.paddings.append(padding_inline) self.bullets.append(bullet if bullet else '')
[docs] def remove_last_prefix(self): """Remove the last prefix from the list.""" with suppress(IndexError): self.current_padding -= self.paddings.pop() del self.bullets[-1]
[docs] def pop_next_bullet(self): """Pop the next bullet to use, if any bullet is available.""" next_bullet_idx = next((-idx for idx, val in enumerate(reversed(self.bullets)) if val), 1) - 1 if not next_bullet_idx: return '' bullet = self.bullets[next_bullet_idx] self.bullets[next_bullet_idx] = '' return bullet
@property def first(self): """Return the prefix used at the beginning of a tag. Note:: A new block needs to be prefixed by the current padding and bullet. Once this has happened (i.e., :attr:`consumed` is set to `True`) no further prefixes should be used for a line. """ if self.consumed: return '' self.consumed = True bullet = self.pop_next_bullet() return ' ' * (self.current_padding - len(bullet)) \ + bullet @property def unconsumed_bullet(self): """Yield any yet unconsumed bullet. Note:: This function yields the previous element's bullets, if they have not been consumed yet. """ if self.consumed: return '' bullet = self.pop_next_bullet() if not bullet: return '' padding = self.current_padding - self.paddings[-1] return ' ' * (padding - len(bullet)) \ + bullet @property def rest(self): """Return the prefix used for new lines within a block. This prefix is used for pre-text that contains newlines. The lines need to be prefixed with the right padding to preserver the indentation. """ return ' ' * self.current_padding