Skip to content

Commit 70b7b83

Browse files
authored
improve handling of different languages (#112)
Signed-off-by: Matthew Peveler <matt.peveler@gmail.com>
1 parent 1407d92 commit 70b7b83

File tree

3 files changed

+74
-27
lines changed

3 files changed

+74
-27
lines changed

README.md

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ A `Python` command line client for [tldr](https://github.com/tldr-pages/tldr).
2727

2828
## Configuration
2929

30-
You can configure the behaviour and output of the `tldr` client by setting environment variables. For example, in the `.bashrc` file:
30+
You can configure the behavior and output of the `tldr` client by setting environment variables. For example, in the `.bashrc` file:
3131

3232
export TLDR_COLOR_NAME="cyan"
3333
export TLDR_COLOR_DESCRIPTION="white"
@@ -38,6 +38,7 @@ You can configure the behaviour and output of the `tldr` client by setting envir
3838
export TLDR_CACHE_MAX_AGE=720
3939
export TLDR_PAGES_SOURCE_LOCATION="https://raw.githubusercontent.com/tldr-pages/tldr/master/pages"
4040
export TLDR_DOWNLOAD_CACHE_LOCATION="https://tldr-pages.github.io/assets/tldr.zip"
41+
export TLDR_LANGUAGE="en"
4142

4243
### Cache
4344

@@ -82,7 +83,18 @@ Any of the values of above may be omitted. For example, you can do similar thing
8283
* `TLDR_COLOR_PARAMETER="red on_yellow underline"` for underlined red text on yellow background
8384
* `TLDR_COLOR_NAME="bold underline"` for default system font and background colors with underline and bolded effects
8485

85-
## Remote source
86+
### Language
87+
88+
The language that tldr will use is dependent on a number of factors. If you specify a language via the
89+
`--language` flag, tldr will attempt to use that language and only that language. Otherwise, it will
90+
default to language set using either `TLDR_LANGUAGE` before falling back to `LANG` (ignoring the value `C`).
91+
If neither are set, then tldr will always attempt to get the `en` page. Finally, if `LANGUAGES` is set, it uses
92+
this as the priority list to try languages in, with the exception that it will attempt `TLDR_LANGUAGE` and `LANG`
93+
first, and if neither are set, will use `en` last (assuming it does not already appear somewhere in `LANGUAGES`).
94+
All language values should be set to a value that follows [RFC 1766](https://tools.ietf.org/html/rfc1766.html),
95+
with the special exception of `C` which is ignored.
96+
97+
### Remote source
8698

8799
If you wish to use your own instance of the tldr pages instead of the default repository, you
88100
can either use the `--source` flag when using tldr or by specifying the following environment variables:
@@ -91,4 +103,4 @@ can either use the `--source` flag when using tldr or by specifying the followin
91103
* defaults to `https://raw.githubusercontent.com/tldr-pages/tldr/master/pages`
92104
* it can also point to local directory using `file:///path/to/directory`
93105
* `TLDR_DOWNLOAD_CACHE_LOCATION` to control where to pull a zip of all pages from
94-
* defaults to `https://tldr-pages.github.io/assets/tldr.zip`
106+
* defaults to `https://tldr-pages.github.io/assets/tldr.zip`

tests/test_tldr.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import sys
22
import io
3+
import types
34
import unittest
45
import tldr
56

@@ -10,6 +11,8 @@ def test_whole_page(self):
1011
with open("tests/data/gem_rendered", "rb") as f_rendered:
1112
old_stdout = sys.stdout
1213
sys.stdout = io.StringIO()
14+
sys.stdout.buffer = types.SimpleNamespace()
15+
sys.stdout.buffer.write = lambda x: sys.stdout.write(x.decode('utf-8'))
1316
tldr.output(f_original)
1417

1518
sys.stdout.seek(0)

tldr.py

Lines changed: 56 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import sys
44
import os
55
import re
6-
import locale
76
from argparse import ArgumentParser
87
from zipfile import ZipFile
98
from datetime import datetime
@@ -27,9 +26,18 @@
2726
'TLDR_DOWNLOAD_CACHE_LOCATION',
2827
'https://tldr-pages.github.io/assets/tldr.zip'
2928
)
30-
DEFAULT_LANG = os.environ.get('LANG', locale.getlocale()[0]).split("_")[0]
29+
30+
DEFAULT_LANG = os.environ.get(
31+
'TLDR_LANGUAGE',
32+
os.environ.get('LANG', None)
33+
).split('_')[0]
34+
35+
if DEFAULT_LANG == 'C':
36+
DEFAULT_LANG = None
37+
3138
USE_CACHE = int(os.environ.get('TLDR_CACHE_ENABLED', '1')) > 0
3239
MAX_CACHE_AGE = int(os.environ.get('TLDR_CACHE_MAX_AGE', 24))
40+
3341
URLOPEN_CONTEXT = None
3442
if int(os.environ.get('TLDR_ALLOW_INSECURE', '0')) == 1:
3543
URLOPEN_CONTEXT = ssl.create_default_context()
@@ -148,20 +156,40 @@ def get_platform_list():
148156
return platforms
149157

150158

151-
def get_page(command, remote=None, platform=None, language=None):
152-
if platform is None:
153-
platform = get_platform_list()
154-
for _platform in platform:
155-
if _platform is None:
156-
continue
159+
def get_language_list():
160+
languages = os.environ.get('LANGUAGES', '').split(':')
161+
languages = list(map(
162+
lambda x: x.split('_')[0],
163+
filter(lambda x: x != 'C', languages)
164+
))
165+
if DEFAULT_LANG is not None:
157166
try:
158-
return get_page_for_platform(command, _platform, remote, language)
159-
except HTTPError as err:
160-
if err.code != 404:
161-
raise
162-
except URLError:
163-
if not PAGES_SOURCE_LOCATION.startswith('file://'):
164-
raise
167+
languages.remove(DEFAULT_LANG)
168+
except ValueError:
169+
pass
170+
languages.insert(0, DEFAULT_LANG)
171+
else:
172+
languages.append('en')
173+
return languages
174+
175+
176+
def get_page(command, remote=None, platforms=None, languages=None):
177+
if platforms is None:
178+
platforms = get_platform_list()
179+
if languages is None:
180+
languages = get_language_list()
181+
for platform in platforms:
182+
for language in languages:
183+
if platform is None:
184+
continue
185+
try:
186+
return get_page_for_platform(command, platform, remote, language)
187+
except HTTPError as err:
188+
if err.code != 404:
189+
raise
190+
except URLError:
191+
if not PAGES_SOURCE_LOCATION.startswith('file://'):
192+
raise
165193

166194
return False
167195

@@ -218,22 +246,22 @@ def output(page):
218246
for line in page:
219247
line = line.rstrip().decode('utf-8')
220248
if len(line) == 0:
221-
pass
249+
continue
222250
elif line[0] == '#':
223251
line = ' ' * LEADING_SPACES_NUM + \
224252
colored(line.replace('# ', ''), *colors_of('name')) + '\n'
225-
print(line)
253+
sys.stdout.buffer.write(line.encode('utf-8'))
226254
elif line[0] == '>':
227255
line = ' ' * (LEADING_SPACES_NUM - 1) + \
228256
colored(
229257
line.replace('>', '').replace('<', ''),
230258
*colors_of('description')
231259
)
232-
print(line)
260+
sys.stdout.buffer.write(line.encode('utf-8'))
233261
elif line[0] == '-':
234262
line = '\n' + ' ' * LEADING_SPACES_NUM + \
235263
colored(line, *colors_of('example'))
236-
print(line)
264+
sys.stdout.buffer.write(line.encode('utf-8'))
237265
elif line[0] == '`':
238266
line = line[1:-1] # need to actually parse ``
239267
elements = [' ' * 2 * LEADING_SPACES_NUM]
@@ -245,11 +273,14 @@ def output(page):
245273
if not replaced:
246274
item = colored(item, *colors_of('command'))
247275
elements.append(item)
248-
print(''.join(elements))
276+
sys.stdout.buffer.write(''.join(elements).encode('utf-8'))
277+
print()
249278
print()
250279

251280

252281
def update_cache(language=None):
282+
if language is None:
283+
language = DEFAULT_LANG if DEFAULT_LANG is not None else 'en'
253284
try:
254285
pages_dir = "pages"
255286
if language and language != 'en':
@@ -322,7 +353,8 @@ def main():
322353
)
323354

324355
parser.add_argument('-L', '--language',
325-
default=DEFAULT_LANG,
356+
nargs=1,
357+
default=None,
326358
type=str,
327359
help='Override the default language')
328360

@@ -354,9 +386,9 @@ def main():
354386
command = '-'.join(rest.command)
355387
result = get_page(
356388
command,
357-
platform=options.platform,
358-
remote=options.source,
359-
language=options.language
389+
options.source,
390+
options.platform,
391+
options.language
360392
)
361393
if not result:
362394
print((

0 commit comments

Comments
 (0)