Skip to content

Commit

Permalink
Refactor localized and user-defined strings
Browse files Browse the repository at this point in the history
- collect all localized string in Language
- remove StringCollection and subclasses
  - the sections in a template file corresponding to the string
    collections are replaced by the [STRINGS] section
- differentiate between builtin/user-defined strings by means of the
  @/$ symbols preceding the string identifiers (e.g. in [STRINGS])
- localize more strings: paragraph, section, listing
  • Loading branch information
brechtm committed Jun 20, 2024
1 parent c9ff698 commit 80bd53a
Show file tree
Hide file tree
Showing 32 changed files with 173 additions and 355 deletions.
7 changes: 6 additions & 1 deletion CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ New Features:

Changed:

* handling of localized strings and user-defined strings has been reworked
* built-in (localized) strings are now indicated by a ``@`` prefix, while
user-defined strings have the ``$`` prefix
* built-in strings can be overridden, and user-defined strings can be set in
a template configuration file in the ``[STRINGS]`` section (with prefix!)
* "words" containing spaces (such as paths and URLs) can now be split before
each forward slash for line wrapping (#188, #416)
* Support for Python 3.7 was dropped (end-of-life in June 2023)
Expand All @@ -61,7 +66,7 @@ Changed:

Fixed:

* Caption labels ("Figure" ad "Table") were not localized
* Caption labels ("Figure", "Table", "Listing") were not localized
* Rendering of tables with no body (#420, PR #422 by th0mr)
* Hyphenation of the first word on a line (#188, #416)
* AttributeError: 'ZeroWidthSpace' object has no attribute 'hyphenate' (#415,
Expand Down
12 changes: 0 additions & 12 deletions doc/api/strings.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,6 @@
Strings (:mod:`rinoh.strings`)
==============================

.. autoclass:: String
:members:


.. autoclass:: StringCollection
:members:


.. autoclass:: UserStrings
:members:


.. autoclass:: Strings
:members:

Expand Down
4 changes: 0 additions & 4 deletions doc/api/structure.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,6 @@ Sections
:members:


.. autoclass:: SectionTitles
:members:


Lists
~~~~~

Expand Down
9 changes: 4 additions & 5 deletions doc/basicstyling.rst
Original file line number Diff line number Diff line change
Expand Up @@ -167,11 +167,10 @@ distinction is only visible when using multiple columns for the page contents

The standard document strings configured by the
:attr:`~.DocumentTemplate.language` option described above can be overridden by
user-defined strings in the :class:`~.SectionTitles` and
:class:`~.AdmonitionTitles` sections of the configuration file. For example,
the default title for the table of contents section (*Table of Contents*) is
replaced with *Contents*. The configuration also sets custom titles for the
caution and warning admonitions.
user-defined strings in the ``STRINGS`` section of the configuration file. For
example, the default title for the table of contents section (*Table of
Contents*) is replaced with *Contents*. The configuration also sets custom
titles for the caution and warning admonitions.

The others sections in the configuration file are the ``VARIABLES`` section,
followed by document part and page template sections. Similar to style sheets,
Expand Down
10 changes: 4 additions & 6 deletions doc/my_book.rtt
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,10 @@ parts =
stylesheet = sphinx_base14
language = fr

[SectionTitles]
contents = 'Contents'

[AdmonitionTitles]
caution = 'Careful!'
warning = 'Please be warned'
[STRINGS]
@contents = 'Contents'
@caution = 'Careful!'
@warning = 'Please be warned'

[VARIABLES]
paper_size = A5
Expand Down
4 changes: 2 additions & 2 deletions doc/rinohtype.rtt
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ parts =
stylesheet = rinohtype.rts


[SectionTitles]
contents='Contents'
[STRINGS]
@contents='Contents'


[VARIABLES]
Expand Down
6 changes: 0 additions & 6 deletions src/rinoh/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,3 @@

register_template = resource._DISTRIBUTION.register_template
register_typeface = resource._DISTRIBUTION.register_typeface

# list all StringCollection subclasses in its docstring
_ = ['* :class:`.{}`'.format(subclass_name)
for subclass_name in sorted(strings.StringCollection.subclasses)]
strings.StringCollection.__doc__ += ('\n\n :Subclasses: '
+ '\n '.join(_))
35 changes: 21 additions & 14 deletions src/rinoh/document.py
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,8 @@ class Document(object):
document_tree (DocumentTree): a tree of the document's contents
stylesheet (StyleSheet): style sheet used to style document elements
language (Language): the language to use for standard strings
strings (Strings): overrides localized strings provided by `language`
strings (Strings): user-defined string variables and can override
localized strings provided by `language`
backend: the backend used for rendering the document
"""
Expand Down Expand Up @@ -380,21 +381,27 @@ def _save_cache(self, filename):
cache = (self.part_page_counts, self.page_references)
pickle.dump(cache, file)

def set_string(self, strings_class, key, value):
self._strings[strings_class][key] = value

def get_string(self, strings_class, key):
if (strings_class in self._strings
and key in self._strings[strings_class]):
return self._strings[strings_class][key]
def set_string(self, key, value, user=False):
if user:
self._strings.set_user_string(key, value)
else:
self._strings.set_builtin_string(key, value)

def get_string(self, key, user=False):
if user:
result = self._strings.user.get(key, None)
if result is None:
warn('The "{}" user string is not defined.')
return result or ''
if key in self._strings.builtin:
return self._strings.builtin[key]
try:
return self.language.strings[strings_class][key]
return self.language.strings[key]
except KeyError:
warn('The {} "{}" string is not defined for {} ({}). Using the '
'English string instead.'.format(strings_class.__name__, key,
self.language.name,
self.language.code))
return EN.strings[strings_class][key]
warn('The "{}" string is not defined for {} ({}). Using the English'
' string instead.'
.format(key, self.language.name, self.language.code))
return EN.strings[key]

def add_sideways_float(self, float):
self.sideways_floats.append(float)
Expand Down
3 changes: 1 addition & 2 deletions src/rinoh/flowable.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
from .layout import (InlineDownExpandingContainer, VirtualContainer,
MaybeContainer, ContainerOverflow, EndOfContainer,
PageBreakException, ReflowRequired)
from .strings import UserStrings
from .style import Styled, Style
from .text import StyledText
from .util import clamp, ReadAliasAttribute
Expand Down Expand Up @@ -431,7 +430,7 @@ def __init__(self, label, content, parent=None):

def build_document(self, flowable_target):
doc = flowable_target.document
doc.set_string(UserStrings, self.label, self.content)
doc.set_string(self.label, self.content, user=True)


class SetOutOfLineFlowables(DummyFlowable):
Expand Down
2 changes: 1 addition & 1 deletion src/rinoh/highlight.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ class CodeBlockWithCaptionStyle(FloatStyle, GroupedFlowablesStyle):

class CodeBlockWithCaption(Float, StaticGroupedFlowables):
style_class = CodeBlockWithCaptionStyle
category = 'Listing'
category = 'listing'


def highlight_block(language, text, lexer_getter):
Expand Down
11 changes: 2 additions & 9 deletions src/rinoh/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
from .layout import ContainerOverflow, EndOfContainer
from .number import NumberFormat
from .paragraph import StaticParagraph, Paragraph, ParagraphStyle
from .strings import StringCollection, String, StringField
from .strings import StringField
from .structure import ListOf, ListOfSection
from .text import MixedStyledText, SingleStyledText, TextStyle, ErrorText
from .util import posix_path, ReadAliasAttribute, PeekIterator
Expand Down Expand Up @@ -398,7 +398,7 @@ def referenceable(self):
def text(self, container):
try:
number = self.number(container)
category_label = StringField(FloatLabels, self.referenceable.category)
category_label = StringField(self.referenceable.category)
label = [category_label, ' ', number]
except KeyError:
label = []
Expand All @@ -420,10 +420,3 @@ class ListOfFigures(ListOf):

class ListOfFiguresSection(ListOfSection):
list_class = ListOfFigures


class FloatLabels(StringCollection):
"""Collection of localized titles for common sections"""

figure = String('Caption label for figures')
table = String('Caption label for tables')
6 changes: 3 additions & 3 deletions src/rinoh/index.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from .paragraph import Paragraph
from .reference import Reference
from .strings import StringField
from .structure import Section, Heading, SectionTitles
from .structure import Section, Heading
from .style import Styled
from .text import MixedStyledText, StyledText
from .util import intersperse
Expand All @@ -23,7 +23,7 @@

class IndexSection(Section):
def __init__(self, title=None, flowables=None, style=None):
section_title = title or StringField(SectionTitles, 'index')
section_title = title or StringField('index')
contents = [Heading(section_title, style='unnumbered')]
if flowables:
contents += list(flowables)
Expand Down Expand Up @@ -127,7 +127,7 @@ def spans(self, container):


class IndexTarget(IndexTargetBase, DummyFlowable):
category = 'Index'
category = 'index'

def __init__(self, index_terms, parent=None):
super().__init__(index_terms, parent=parent)
Expand Down
8 changes: 2 additions & 6 deletions src/rinoh/language/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,6 @@
for code, language_ref in Language.languages.items():
language = language_ref()
lines = ['Localized strings for {}'.format(language.name)]
for string_collection in language.strings.values():
lines.append("\n.. rubric:: {}\n"
.format(type(string_collection).__name__))
for string in string_collection._strings:
lines.append(":{}: {}".format(string.name,
string_collection[string.name]))
for name, localized_string in language.strings.items():
lines.append(":{}: {}".format(name, localized_string))
language.__doc__ = '\n'.join(lines)
33 changes: 24 additions & 9 deletions src/rinoh/language/cls.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import weakref

from ..attribute import AttributeType
from ..strings import StringCollection


__all__ = ['Language']
Expand All @@ -22,27 +21,43 @@ class Language(AttributeType):
code (str): short code identifying the language
name (str): native name of the language
paragraph: label for referencing paragraphs
section: label for referencing sections
chapter: label for top-level sections
figure: caption label for figures
table: caption label for tables
listing: caption label for (source code) listings
contents: title for the table of contents section
list_of_figures: title for the list of figures section
list_of_tables: title for the list of tables section
index: title for the index section
attention: title for attention admonitions
caution: title for caution admonitions
danger: title for danger admonitions
error: title for error admonitions
hint: title for hint admonitions
important: title for important admonitions
note: title for note admonitions
tip: title for tip admonitions
warning: title for warning admonitions
seealso: title for see-also admonitions
"""

languages = {} #: Dictionary mapping codes to :class:`Language`\ s

def __init__(self, code, name):
def __init__(self, code, name, **localized_strings):
self.languages[code] = weakref.ref(self)
self.code = code
self.name = name
self.strings = {}
self.strings = localized_strings
self.no_break_after = []

def __repr__(self):
return "{}('{}', '{}')".format(type(self).__name__,
self.code, self.name)

def __contains__(self, item):
assert isinstance(item, StringCollection)
strings_class = type(item)
assert strings_class not in self.strings
self.strings[strings_class] = item

@classmethod
def parse_string(cls, string, source):
return cls.languages[string.lower()]()
Expand Down
14 changes: 3 additions & 11 deletions src/rinoh/language/cs.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,18 @@


from .cls import Language
from ..image import FloatLabels
from ..structure import SectionTitles, AdmonitionTitles


CS = Language('cs', 'Česky')

FloatLabels(
CS = Language('cs', 'Česky',
figure='Obrázek',
table='Tabulka',
) in CS

SectionTitles(
contents='Obsah',
list_of_figures='Seznam obrázků',
list_of_tables='Seznam tabulek',
chapter='Kapitola',
index='Rejstřík',
) in CS

AdmonitionTitles(
# admonitions
attention='Pozor!',
caution='Pozor!',
danger='!NEBEZPEČÍ!',
Expand All @@ -37,7 +29,7 @@
tip='Tip',
warning='Varování',
seealso='Viz také',
) in CS
)


CS.no_break_after = ("do od u z ze za k ke o na v ve nad pod za po s se "
Expand Down
14 changes: 3 additions & 11 deletions src/rinoh/language/de.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,18 @@


from .cls import Language
from ..image import FloatLabels
from ..structure import SectionTitles, AdmonitionTitles


DE = Language('de', 'Deutsch')

FloatLabels(
DE = Language('de', 'Deutsch',
figure='Abbildung',
table='Tabelle',
) in DE

SectionTitles(
contents='Inhalt',
list_of_figures='Abbildungsverzeichnis',
list_of_tables='Tabellenverzeichnis',
chapter='Kapitel',
index='Index',
) in DE

AdmonitionTitles(
# admonitions
attention='Aufgepasst!',
caution='Vorsicht!',
danger='!GEFAHR!',
Expand All @@ -37,4 +29,4 @@
tip='Tipp',
warning='Warnung',
seealso='Siehe auch',
) in DE
)
Loading

0 comments on commit 80bd53a

Please sign in to comment.