Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ NEW: Add translations for all buttons and tooltips #214

Merged
merged 3 commits into from
Sep 23, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,7 @@ include web-compile-config.yml
include sphinx_book_theme/theme.conf
recursive-include sphinx_book_theme *.html
recursive-include sphinx_book_theme/static *.js *.png *.css *.svg
include sphinx_book_theme/translations/README.md
recursive-include sphinx_book_theme/translations *.mo
exclude jsons
recursive-exclude sphinx_book_theme/translations *.json
16 changes: 14 additions & 2 deletions sphinx_book_theme/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from bs4 import BeautifulSoup as bs
from docutils.parsers.rst import directives
from docutils import nodes
from sphinx.application import Sphinx
from sphinx.locale import get_translation
from sphinx.util import logging

Expand All @@ -21,6 +22,7 @@
"""sphinx-book-theme version"""

SPHINX_LOGGER = logging.getLogger(__name__)
MESSAGE_CATALOG_NAME = "booktheme"


def get_html_theme_path():
Expand Down Expand Up @@ -272,7 +274,12 @@ def add_header_level_recursive(ul, level):
if key in context:
context[key] = _string_or_bool(context[key])

context["translate"] = get_translation("sphinx")
translation = get_translation(MESSAGE_CATALOG_NAME)
context["translate"] = translation
# this is set in the html_theme
context["theme_search_bar_text"] = translation(
context.get("theme_search_bar_text", "Search the docs ...")
)


def update_thebe_config(app, env, docnames):
Expand Down Expand Up @@ -349,7 +356,7 @@ def run(self):
return nodes


def setup(app):
def setup(app: Sphinx):
app.connect("env-before-read-docs", update_thebe_config)

# Configuration for Juypter Book
Expand All @@ -358,6 +365,11 @@ def setup(app):
app.connect("builder-inited", add_static_paths)
app.connect("env-updated", update_all)

# add translations
package_dir = os.path.abspath(os.path.dirname(__file__))
locale_dir = os.path.join(package_dir, "translations", "locales")
app.add_message_catalog(MESSAGE_CATALOG_NAME, locale_dir)

app.add_html_theme("sphinx_book_theme", get_html_theme_path())
app.connect("html-page-context", add_to_context)

Expand Down
8 changes: 4 additions & 4 deletions sphinx_book_theme/topbar.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
{% if theme_single_page != True %}
<button id="navbar-toggler" class="navbar-toggler ml-0" type="button" data-toggle="collapse"
data-toggle="tooltip" data-placement="bottom" data-target=".site-navigation" aria-controls="navbar-menu"
aria-expanded="true" aria-label="Toggle navigation" aria-controls="site-navigation"
title="Toggle navigation" data-toggle="tooltip" data-placement="left">
aria-expanded="true" aria-label="{{ translate('Toggle navigation') }}" aria-controls="site-navigation"
title="{{ translate('Toggle navigation') }}" data-toggle="tooltip" data-placement="left">
<i class="fas fa-bars"></i>
<i class="fas fa-arrow-left"></i>
<i class="fas fa-arrow-up"></i>
Expand All @@ -17,7 +17,7 @@

<!-- Full screen (wrap in <a> to have style consistency -->
<a class="full-screen-button"><button type="button" class="btn btn-secondary topbarbtn" data-toggle="tooltip"
data-placement="bottom" onclick="toggleFullScreen()" title="Fullscreen mode"><i
data-placement="bottom" onclick="toggleFullScreen()" title="{{ translate('Fullscreen mode') }}"><i
class="fas fa-expand"></i></button></a>

{% include "topbar/launchbuttons.html" %}
Expand All @@ -27,7 +27,7 @@
<div class="d-none d-md-block col-md-2 bd-toc show">
{%- if toc %}
<div class="tocsection onthispage pt-5 pb-3">
<i class="fas fa-list"></i> {{ translate("Contents") }}
<i class="fas fa-list"></i> {{ translate('Contents') }}
</div>
{%- endif %}
<nav id="bd-toc-nav">
Expand Down
8 changes: 4 additions & 4 deletions sphinx_book_theme/topbar/download.html
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
<div class="dropdown-buttons-trigger">
<button id="dropdown-buttons-trigger" class="btn btn-secondary topbarbtn" aria-label="Download this page"><i
<button id="dropdown-buttons-trigger" class="btn btn-secondary topbarbtn" aria-label="{{ translate('Download this page') }}"><i
class="fas fa-download"></i></button>

{% if page_source_suffix %}
<div class="dropdown-buttons">
<!-- ipynb file if we had a myst markdown file -->
{% if ipynb_source %}<a class="dropdown-buttons"
href="{{ pathto('_sources', 1) }}/{{ ipynb_source }}"><button type="button"
class="btn btn-secondary topbarbtn" title="Download notebook file" data-toggle="tooltip"
class="btn btn-secondary topbarbtn" title="{{ translate('Download notebook file') }}" data-toggle="tooltip"
data-placement="left">.ipynb</button></a>{% endif %}
<!-- Download raw file -->
<a class="dropdown-buttons" href="{{ pathto('_sources', 1) }}/{{ sourcename }}"><button type="button"
class="btn btn-secondary topbarbtn" title="Download source file" data-toggle="tooltip"
class="btn btn-secondary topbarbtn" title="{{ translate('Download source file') }}" data-toggle="tooltip"
data-placement="left">{{ page_source_suffix }}</button></a>
<!-- Download PDF via print -->
<button type="button" id="download-print" class="btn btn-secondary topbarbtn" title="Print to PDF"
<button type="button" id="download-print" class="btn btn-secondary topbarbtn" title="{{ translate('Print to PDF') }}"
onClick="window.print()" data-toggle="tooltip" data-placement="left">.pdf</button>
</div>
{% endif %}
Expand Down
8 changes: 4 additions & 4 deletions sphinx_book_theme/topbar/launchbuttons.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,27 @@
<div class="dropdown-buttons">
{% if binder_url %}
<a class="binder-button" href="{{ binder_url }}"><button type="button"
class="btn btn-secondary topbarbtn" title="Launch Binder" data-toggle="tooltip"
class="btn btn-secondary topbarbtn" title="{{ translate('Launch') }} Binder" data-toggle="tooltip"
data-placement="left"><img class="binder-button-logo"
src="{{ pathto('_static/images/logo_binder.svg', 1) }}"
alt="Interact on binder">Binder</button></a>
{% endif %}
{% if jupyterhub_url %}
<a class="jupyterhub-button" href="{{ jupyterhub_url }}"><button type="button"
class="btn btn-secondary topbarbtn" title="Launch JupyterHub" data-toggle="tooltip"
class="btn btn-secondary topbarbtn" title="{{ translate('Launch') }} JupyterHub" data-toggle="tooltip"
data-placement="left"><img class="jupyterhub-button-logo"
src="{{ pathto('_static/images/logo_jupyterhub.svg', 1) }}"
alt="Interact on JupyterHub">JupyterHub</button></a>
{% endif %}
{% if colab_url and page_source_suffix==".ipynb" %}
<a class="colab-button" href="{{ colab_url }}"><button type="button" class="btn btn-secondary topbarbtn"
title="Launch Colab" data-toggle="tooltip" data-placement="left"><img class="colab-button-logo"
title="{{ translate('Launch') }} Colab" data-toggle="tooltip" data-placement="left"><img class="colab-button-logo"
src="{{ pathto('_static/images/logo_colab.png', 1) }}"
alt="Interact on Colab">Colab</button></a>
{% endif %}
{% if use_thebe -%}
<button type="button" class="btn btn-secondary topbarbtn"
onclick="initThebeSBT()" title="Launch Thebe" data-toggle="tooltip" data-placement="left"><i
onclick="initThebeSBT()" title="{{ translate('Launch') }} Thebe" data-toggle="tooltip" data-placement="left"><i
class="fas fa-play"></i><span style="margin-left: .4em;">Live Code</span></button>
{% endif %}
</div>
Expand Down
8 changes: 4 additions & 4 deletions sphinx_book_theme/topbar/repobuttons.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@
<div class="dropdown-buttons sourcebuttons">
{% if theme_use_repository_button %}<a class="repository-button"
href="{{ theme_repository_url }}"><button type="button" class="btn btn-secondary topbarbtn"
data-toggle="tooltip" data-placement="left" title="Source repository"><i
class="fab fa-github"></i>repository</button></a>{% endif %}
data-toggle="tooltip" data-placement="left" title="{{ translate('Source repository') }}"><i
class="fab fa-github"></i>{{ translate('repository') }}</button></a>{% endif %}
{% if theme_use_issues_button %}<a class="issues-button"
href="{{ theme_repository_url }}/issues/new?title=Issue%20on%20page%20%2F{{ pagename }}.html&body=Your%20issue%20content%20here."><button
type="button" class="btn btn-secondary topbarbtn" data-toggle="tooltip" data-placement="left"
title="Open an issue"><i class="fas fa-lightbulb"></i>open issue</button></a>{% endif %}
title="{{ translate('Open an issue') }}"><i class="fas fa-lightbulb"></i>{{ translate('open issue') }}</button></a>{% endif %}
{% if theme_use_edit_page_button %}<a class="edit-button" href="{{ get_edit_url() }}"><button
type="button" class="btn btn-secondary topbarbtn" data-toggle="tooltip" data-placement="left"
title="Edit this page"><i class="fas fa-pencil-alt"></i>suggest edit</button></a>{% endif %}
title="{{ translate('Edit this page') }}"><i class="fas fa-pencil-alt"></i>{{ translate('suggest edit') }}</button></a>{% endif %}
</div>
</div>
{% endif %}
2 changes: 2 additions & 0 deletions sphinx_book_theme/translations/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*.po
!*.mo
3 changes: 3 additions & 0 deletions sphinx_book_theme/translations/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
JSONs created using https://smodin.me/translate-one-text-into-multiple-languages

To convert to locale files run `python sphinx_book_theme/translations/_convert.py`
Empty file.
57 changes: 57 additions & 0 deletions sphinx_book_theme/translations/_convert.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import json
import os
from pathlib import Path
import subprocess


def convert_json(folder=None):
folder = folder or Path(__file__).parent

# remove exising
for path in (folder / "locales").glob("**/booktheme.po"):
path.unlink()

# compile po
for path in (folder / "jsons").glob("*.json"):
data = json.loads(path.read_text("utf8"))
assert data[0]["symbol"] == "en"
english = data[0]["text"]
for item in data[1:]:
language = item["symbol"]
out_path = folder / "locales" / language / "LC_MESSAGES" / "booktheme.po"
if not out_path.parent.exists():
out_path.parent.mkdir(parents=True)
if not out_path.exists():
header = f"""
msgid ""
msgstr ""
"Project-Id-Version: Sphinx-Book-Theme\\n"
"MIME-Version: 1.0\\n"
"Content-Type: text/plain; charset=UTF-8\\n"
"Content-Transfer-Encoding: 8bit\\n"
"Language: {language}\\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\\n"
"""
out_path.write_text(header)

with out_path.open("a") as f:
f.write("\n")
f.write(f'msgid "{english}"\n')
text = item["text"].replace('"', '\\"')
f.write(f'msgstr "{text}"\n')

# compile mo
for path in (folder / "locales").glob("**/booktheme.po"):
print(path)
subprocess.check_call(
[
"msgfmt",
os.path.abspath(path),
"-o",
os.path.abspath(path.parent / "booktheme.mo"),
]
)


if __name__ == "__main__":
convert_json()
1 change: 1 addition & 0 deletions sphinx_book_theme/translations/jsons/By the.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[{"language":"English","symbol":"en","text":"By the"}, {"language":"Arabic","symbol":"ar","text":"بواسطة"},{"language":"Bulgarian","symbol":"bg","text":"По"},{"language":"Chinese Simplified","symbol":"zh-cn","text":"由"},{"language":"Chinese Traditional","symbol":"zh-tw","text":"由"},{"language":"Croatian","symbol":"hr","text":"Od strane"},{"language":"Czech","symbol":"cs","text":"Podle"},{"language":"Danish","symbol":"da","text":"Ved"},{"language":"Dutch","symbol":"nl","text":"Door de"},{"language":"Esperanto","symbol":"eo","text":"Per la"},{"language":"Estonian","symbol":"et","text":"Autor"},{"language":"Finnish","symbol":"fi","text":"Mukaan"},{"language":"French","symbol":"fr","text":"Par le"},{"language":"German","symbol":"de","text":"Bis zum"},{"language":"Greek","symbol":"el","text":"Από το"},{"language":"Hebrew","symbol":"iw","text":"דרך"},{"language":"Indonesian","symbol":"id","text":"Oleh"},{"language":"Italian","symbol":"it","text":"Dal"},{"language":"Japanese","symbol":"ja","text":"によって"},{"language":"Korean","symbol":"ko","text":"에 의해"},{"language":"Latvian","symbol":"lv","text":"Ar"},{"language":"Lithuanian","symbol":"lt","text":"Prie"},{"language":"Norwegian","symbol":"no","text":"Ved"},{"language":"Polish","symbol":"pl","text":"Przez"},{"language":"Portuguese","symbol":"pt","text":"Pelo"},{"language":"Romanian","symbol":"ro","text":"Langa"},{"language":"Russian","symbol":"ru","text":"Посредством"},{"language":"Serbian","symbol":"sr","text":"Од"},{"language":"Slovak","symbol":"sk","text":"Podľa"},{"language":"Slovenian","symbol":"sl","text":"Avtor"},{"language":"Spanish","symbol":"es","text":"Por el"},{"language":"Swedish","symbol":"sv","text":"Vid"},{"language":"Tajik","symbol":"tg","text":"Бо"},{"language":"Thai","symbol":"th","text":"โดย"},{"language":"Turkish","symbol":"tr","text":"Tarafından"},{"language":"Ukrainian","symbol":"uk","text":"По"},{"language":"Vietnamese","symbol":"vi","text":"Bằng"},{"language":"Bengali","symbol":"bn","text":"দ্বারা"},{"language":"Filipino","symbol":"tl","text":"Sa pamamagitan ng"},{"language":"Marathi","symbol":"mr","text":"द्वारा"},{"language":"Malay","symbol":"ms","text":"Oleh"},{"language":"Malayalam","symbol":"ml","text":"എഴുതിയത്"},{"language":"Urdu","symbol":"ur","text":"کی طرف"},{"language":"Telugu","symbol":"te","text":"ద్వారా"},{"language":"Tamil","symbol":"ta","text":"மூலம்"},{"language":"Catalan","symbol":"ca","text":"Per la"}]
1 change: 1 addition & 0 deletions sphinx_book_theme/translations/jsons/Contents.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[{"language":"English","symbol":"en","text":"Contents"}, {"language":"Arabic","symbol":"ar","text":"محتويات"},{"language":"Bulgarian","symbol":"bg","text":"Съдържание"},{"language":"Chinese Simplified","symbol":"zh-cn","text":"内容"},{"language":"Chinese Traditional","symbol":"zh-tw","text":"內容"},{"language":"Croatian","symbol":"hr","text":"Sadržaj"},{"language":"Czech","symbol":"cs","text":"Obsah"},{"language":"Danish","symbol":"da","text":"Indhold"},{"language":"Dutch","symbol":"nl","text":"Inhoud"},{"language":"Esperanto","symbol":"eo","text":"Enhavo"},{"language":"Estonian","symbol":"et","text":"Sisu"},{"language":"Finnish","symbol":"fi","text":"Sisällys"},{"language":"French","symbol":"fr","text":"Contenu"},{"language":"German","symbol":"de","text":"Inhalt"},{"language":"Greek","symbol":"el","text":"Περιεχόμενα"},{"language":"Hebrew","symbol":"iw","text":"תוכן"},{"language":"Indonesian","symbol":"id","text":"Isi"},{"language":"Italian","symbol":"it","text":"Contenuti"},{"language":"Japanese","symbol":"ja","text":"目次"},{"language":"Korean","symbol":"ko","text":"내용"},{"language":"Latvian","symbol":"lv","text":"Saturs"},{"language":"Lithuanian","symbol":"lt","text":"Turinys"},{"language":"Norwegian","symbol":"no","text":"Innhold"},{"language":"Polish","symbol":"pl","text":"Zawartość"},{"language":"Portuguese","symbol":"pt","text":"Conteúdo"},{"language":"Romanian","symbol":"ro","text":"Cuprins"},{"language":"Russian","symbol":"ru","text":"Содержание"},{"language":"Serbian","symbol":"sr","text":"Садржај"},{"language":"Slovak","symbol":"sk","text":"Obsah"},{"language":"Slovenian","symbol":"sl","text":"Vsebina"},{"language":"Spanish","symbol":"es","text":"Contenido"},{"language":"Swedish","symbol":"sv","text":"Innehåll"},{"language":"Tajik","symbol":"tg","text":"Мундариҷа"},{"language":"Thai","symbol":"th","text":"สารบัญ"},{"language":"Turkish","symbol":"tr","text":"İçindekiler"},{"language":"Ukrainian","symbol":"uk","text":"Зміст"},{"language":"Vietnamese","symbol":"vi","text":"Nội dung"}]
1 change: 1 addition & 0 deletions sphinx_book_theme/translations/jsons/Copyright.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[{"language":"English","symbol":"en","text":"Copyright"}, {"language":"Arabic","symbol":"ar","text":"حقوق النشر"},{"language":"Bulgarian","symbol":"bg","text":"Авторско право"},{"language":"Chinese Simplified","symbol":"zh-cn","text":"版权"},{"language":"Chinese Traditional","symbol":"zh-tw","text":"版權"},{"language":"Croatian","symbol":"hr","text":"Autorska prava"},{"language":"Czech","symbol":"cs","text":"autorská práva"},{"language":"Danish","symbol":"da","text":"ophavsret"},{"language":"Dutch","symbol":"nl","text":"auteursrechten"},{"language":"Esperanto","symbol":"eo","text":"Kopirajto"},{"language":"Estonian","symbol":"et","text":"Autoriõigus"},{"language":"Finnish","symbol":"fi","text":"Tekijänoikeus"},{"language":"French","symbol":"fr","text":"droits d'auteur"},{"language":"German","symbol":"de","text":"Urheberrechte ©"},{"language":"Greek","symbol":"el","text":"Πνευματική ιδιοκτησία"},{"language":"Hebrew","symbol":"iw","text":"זכויות יוצרים"},{"language":"Indonesian","symbol":"id","text":"hak cipta"},{"language":"Italian","symbol":"it","text":"Diritto d'autore"},{"language":"Japanese","symbol":"ja","text":"著作権"},{"language":"Korean","symbol":"ko","text":"저작권"},{"language":"Latvian","symbol":"lv","text":"Autortiesības"},{"language":"Lithuanian","symbol":"lt","text":"Autorių teisės"},{"language":"Norwegian","symbol":"no","text":"opphavsrett"},{"language":"Polish","symbol":"pl","text":"prawa autorskie"},{"language":"Portuguese","symbol":"pt","text":"direito autoral"},{"language":"Romanian","symbol":"ro","text":"Drepturi de autor"},{"language":"Russian","symbol":"ru","text":"авторское право"},{"language":"Serbian","symbol":"sr","text":"Ауторско право"},{"language":"Slovak","symbol":"sk","text":"Autorské práva"},{"language":"Slovenian","symbol":"sl","text":"avtorske pravice"},{"language":"Spanish","symbol":"es","text":"Derechos de autor"},{"language":"Swedish","symbol":"sv","text":"upphovsrätt"},{"language":"Tajik","symbol":"tg","text":"Ҳуқуқи муаллиф"},{"language":"Thai","symbol":"th","text":"ลิขสิทธิ์"},{"language":"Turkish","symbol":"tr","text":"Telif hakkı"},{"language":"Ukrainian","symbol":"uk","text":"Авторське право"},{"language":"Vietnamese","symbol":"vi","text":"Bản quyền"},{"language":"Bengali","symbol":"bn","text":"কপিরাইট"},{"language":"Catalan","symbol":"ca","text":"Copyright"},{"language":"Filipino","symbol":"tl","text":"Copyright"},{"language":"Malayalam","symbol":"ml","text":"പകർപ്പവകാശം"},{"language":"Malay","symbol":"ms","text":"hak cipta"},{"language":"Marathi","symbol":"mr","text":"कॉपीराइट"},{"language":"Tamil","symbol":"ta","text":"பதிப்புரிமை"},{"language":"Telugu","symbol":"te","text":"కాపీరైట్"},{"language":"Urdu","symbol":"ur","text":"کاپی رائٹ"}]
Loading