pybabel-angularjs 1.3.5__tar.gz → 1.5.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pybabel_angularjs-1.5.0/PKG-INFO +116 -0
- pybabel_angularjs-1.5.0/README.md +91 -0
- pybabel_angularjs-1.5.0/pyproject.toml +43 -0
- pybabel_angularjs-1.5.0/setup.cfg +4 -0
- pybabel_angularjs-1.5.0/src/pybabel_angularjs/extractor.py +270 -0
- pybabel_angularjs-1.5.0/src/pybabel_angularjs.egg-info/PKG-INFO +116 -0
- {pybabel-angularjs-1.3.5 → pybabel_angularjs-1.5.0}/src/pybabel_angularjs.egg-info/SOURCES.txt +1 -2
- {pybabel-angularjs-1.3.5 → pybabel_angularjs-1.5.0}/src/pybabel_angularjs.egg-info/entry_points.txt +0 -1
- pybabel_angularjs-1.5.0/src/pybabel_angularjs.egg-info/requires.txt +1 -0
- pybabel-angularjs-1.3.5/PKG-INFO +0 -95
- pybabel-angularjs-1.3.5/README.md +0 -70
- pybabel-angularjs-1.3.5/setup.cfg +0 -10
- pybabel-angularjs-1.3.5/setup.py +0 -41
- pybabel-angularjs-1.3.5/src/pybabel_angularjs/extractor.py +0 -235
- pybabel-angularjs-1.3.5/src/pybabel_angularjs.egg-info/PKG-INFO +0 -95
- pybabel-angularjs-1.3.5/src/pybabel_angularjs.egg-info/requires.txt +0 -2
- {pybabel-angularjs-1.3.5 → pybabel_angularjs-1.5.0}/LICENSE +0 -0
- {pybabel-angularjs-1.3.5 → pybabel_angularjs-1.5.0}/MANIFEST.in +0 -0
- {pybabel-angularjs-1.3.5 → pybabel_angularjs-1.5.0}/src/pybabel_angularjs/__init__.py +0 -0
- {pybabel-angularjs-1.3.5 → pybabel_angularjs-1.5.0}/src/pybabel_angularjs.egg-info/dependency_links.txt +0 -0
- {pybabel-angularjs-1.3.5 → pybabel_angularjs-1.5.0}/src/pybabel_angularjs.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pybabel-angularjs
|
|
3
|
+
Version: 1.5.0
|
|
4
|
+
Summary: An AngularJS extractor for Babel
|
|
5
|
+
Author-email: Jaromír Pufler <jaromir.pufler@gmail.com>
|
|
6
|
+
License: Apache Software License
|
|
7
|
+
Project-URL: Homepage, https://github.com/chuckyblack/pybabel-angularjs
|
|
8
|
+
Keywords: angularjs,gettext,babel,i18n,translate
|
|
9
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: Topic :: Software Development :: Internationalization
|
|
12
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: Programming Language :: Python
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
20
|
+
Requires-Python: >=3.12
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
License-File: LICENSE
|
|
23
|
+
Requires-Dist: babel
|
|
24
|
+
Dynamic: license-file
|
|
25
|
+
|
|
26
|
+
# pybabel-angularjs
|
|
27
|
+
|
|
28
|
+
[](https://github.com/chuckyblack/pybabel-angularjs/actions/workflows/release.yml)
|
|
29
|
+
[](https://pypi.org/project/pybabel-angularjs/)
|
|
30
|
+
|
|
31
|
+
A [Babel](https://babel.pocoo.org/) message extractor for AngularJS HTML
|
|
32
|
+
templates. It extracts element content and attributes marked for translation,
|
|
33
|
+
including strings containing AngularJS expressions such as `{{ name }}`.
|
|
34
|
+
|
|
35
|
+
Requires Python 3.12 or newer.
|
|
36
|
+
|
|
37
|
+
## Installation
|
|
38
|
+
|
|
39
|
+
```console
|
|
40
|
+
python -m pip install pybabel-angularjs
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
The package installs the `angularjs` Babel extractor entry point. Add it to a
|
|
44
|
+
Babel mapping file such as `babel.cfg`:
|
|
45
|
+
|
|
46
|
+
```ini
|
|
47
|
+
[angularjs: **/*.html]
|
|
48
|
+
encoding = utf-8
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Then extract messages in the usual way:
|
|
52
|
+
|
|
53
|
+
```console
|
|
54
|
+
pybabel extract -F babel.cfg -o messages.pot .
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Marking messages
|
|
58
|
+
|
|
59
|
+
Mark an element's content with `i18n`:
|
|
60
|
+
|
|
61
|
+
```html
|
|
62
|
+
<div i18n>Hello world!</div>
|
|
63
|
+
<p i18n>Hello {{ name }}!</p>
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
The value of `i18n`, when present, is included as a comment for translators:
|
|
67
|
+
|
|
68
|
+
```html
|
|
69
|
+
<h1 i18n="Page heading">Welcome</h1>
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Mark an individual attribute by adding the `i18n-` prefix:
|
|
73
|
+
|
|
74
|
+
```html
|
|
75
|
+
<input placeholder="Your name" i18n-placeholder>
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Configuration
|
|
79
|
+
|
|
80
|
+
Options are set in the extractor section of the Babel mapping file. Lists can
|
|
81
|
+
be separated by commas or whitespace.
|
|
82
|
+
|
|
83
|
+
```ini
|
|
84
|
+
[angularjs: **/*.html]
|
|
85
|
+
encoding = utf-8
|
|
86
|
+
include_tags = h1, h2, p
|
|
87
|
+
include_attributes = title, alt, placeholder
|
|
88
|
+
allowed_tags = a, strong, br, i
|
|
89
|
+
allowed_attributes_a = href, target
|
|
90
|
+
include_format_flags = false
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
- `extract_attribute` changes the marker from the default `i18n`, for example
|
|
94
|
+
to `data-translate`.
|
|
95
|
+
- `include_tags` extracts all content from the listed tags without requiring an
|
|
96
|
+
explicit marker.
|
|
97
|
+
- `include_attributes` extracts the listed attributes wherever they occur.
|
|
98
|
+
- `allowed_tags` controls which nested HTML tags may appear inside a translated
|
|
99
|
+
message. The default is `strong, br, i`.
|
|
100
|
+
- `allowed_attributes_<tag>` controls attributes allowed on a nested tag, for
|
|
101
|
+
example `allowed_attributes_a = href, target`.
|
|
102
|
+
- `encoding` controls template decoding and defaults to `utf-8`.
|
|
103
|
+
- `include_format_flags` makes the extractor return an extended five-value
|
|
104
|
+
result and marks messages containing AngularJS interpolation with
|
|
105
|
+
`angularjs-format`. It defaults to `false` because official Babel releases
|
|
106
|
+
accept only the standard four-value extractor result. Enable it only with a
|
|
107
|
+
Babel build that explicitly supports extractor-provided flags.
|
|
108
|
+
|
|
109
|
+
Use `no-i18n` to exclude an automatically included tag. A `<div no-i18n>`
|
|
110
|
+
excludes its entire subtree. For automatically included attributes, use the
|
|
111
|
+
corresponding marker such as `no-i18n-title`.
|
|
112
|
+
|
|
113
|
+
## License
|
|
114
|
+
|
|
115
|
+
Apache License 2.0. The project was heavily inspired by the original
|
|
116
|
+
[shoreware/pybabel-angularjs](https://bitbucket.org/shoreware/pybabel-angularjs).
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# pybabel-angularjs
|
|
2
|
+
|
|
3
|
+
[](https://github.com/chuckyblack/pybabel-angularjs/actions/workflows/release.yml)
|
|
4
|
+
[](https://pypi.org/project/pybabel-angularjs/)
|
|
5
|
+
|
|
6
|
+
A [Babel](https://babel.pocoo.org/) message extractor for AngularJS HTML
|
|
7
|
+
templates. It extracts element content and attributes marked for translation,
|
|
8
|
+
including strings containing AngularJS expressions such as `{{ name }}`.
|
|
9
|
+
|
|
10
|
+
Requires Python 3.12 or newer.
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
```console
|
|
15
|
+
python -m pip install pybabel-angularjs
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
The package installs the `angularjs` Babel extractor entry point. Add it to a
|
|
19
|
+
Babel mapping file such as `babel.cfg`:
|
|
20
|
+
|
|
21
|
+
```ini
|
|
22
|
+
[angularjs: **/*.html]
|
|
23
|
+
encoding = utf-8
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Then extract messages in the usual way:
|
|
27
|
+
|
|
28
|
+
```console
|
|
29
|
+
pybabel extract -F babel.cfg -o messages.pot .
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Marking messages
|
|
33
|
+
|
|
34
|
+
Mark an element's content with `i18n`:
|
|
35
|
+
|
|
36
|
+
```html
|
|
37
|
+
<div i18n>Hello world!</div>
|
|
38
|
+
<p i18n>Hello {{ name }}!</p>
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
The value of `i18n`, when present, is included as a comment for translators:
|
|
42
|
+
|
|
43
|
+
```html
|
|
44
|
+
<h1 i18n="Page heading">Welcome</h1>
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Mark an individual attribute by adding the `i18n-` prefix:
|
|
48
|
+
|
|
49
|
+
```html
|
|
50
|
+
<input placeholder="Your name" i18n-placeholder>
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Configuration
|
|
54
|
+
|
|
55
|
+
Options are set in the extractor section of the Babel mapping file. Lists can
|
|
56
|
+
be separated by commas or whitespace.
|
|
57
|
+
|
|
58
|
+
```ini
|
|
59
|
+
[angularjs: **/*.html]
|
|
60
|
+
encoding = utf-8
|
|
61
|
+
include_tags = h1, h2, p
|
|
62
|
+
include_attributes = title, alt, placeholder
|
|
63
|
+
allowed_tags = a, strong, br, i
|
|
64
|
+
allowed_attributes_a = href, target
|
|
65
|
+
include_format_flags = false
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
- `extract_attribute` changes the marker from the default `i18n`, for example
|
|
69
|
+
to `data-translate`.
|
|
70
|
+
- `include_tags` extracts all content from the listed tags without requiring an
|
|
71
|
+
explicit marker.
|
|
72
|
+
- `include_attributes` extracts the listed attributes wherever they occur.
|
|
73
|
+
- `allowed_tags` controls which nested HTML tags may appear inside a translated
|
|
74
|
+
message. The default is `strong, br, i`.
|
|
75
|
+
- `allowed_attributes_<tag>` controls attributes allowed on a nested tag, for
|
|
76
|
+
example `allowed_attributes_a = href, target`.
|
|
77
|
+
- `encoding` controls template decoding and defaults to `utf-8`.
|
|
78
|
+
- `include_format_flags` makes the extractor return an extended five-value
|
|
79
|
+
result and marks messages containing AngularJS interpolation with
|
|
80
|
+
`angularjs-format`. It defaults to `false` because official Babel releases
|
|
81
|
+
accept only the standard four-value extractor result. Enable it only with a
|
|
82
|
+
Babel build that explicitly supports extractor-provided flags.
|
|
83
|
+
|
|
84
|
+
Use `no-i18n` to exclude an automatically included tag. A `<div no-i18n>`
|
|
85
|
+
excludes its entire subtree. For automatically included attributes, use the
|
|
86
|
+
corresponding marker such as `no-i18n-title`.
|
|
87
|
+
|
|
88
|
+
## License
|
|
89
|
+
|
|
90
|
+
Apache License 2.0. The project was heavily inspired by the original
|
|
91
|
+
[shoreware/pybabel-angularjs](https://bitbucket.org/shoreware/pybabel-angularjs).
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "pybabel-angularjs"
|
|
7
|
+
version = "1.5.0"
|
|
8
|
+
description = "An AngularJS extractor for Babel"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.12"
|
|
11
|
+
authors = [
|
|
12
|
+
{ name = "Jaromír Pufler", email = "jaromir.pufler@gmail.com" },
|
|
13
|
+
]
|
|
14
|
+
license = { text = "Apache Software License" }
|
|
15
|
+
keywords = ["angularjs", "gettext", "babel", "i18n", "translate"]
|
|
16
|
+
dependencies = [
|
|
17
|
+
"babel",
|
|
18
|
+
]
|
|
19
|
+
classifiers = [
|
|
20
|
+
"Development Status :: 5 - Production/Stable",
|
|
21
|
+
"Intended Audience :: Developers",
|
|
22
|
+
"Topic :: Software Development :: Internationalization",
|
|
23
|
+
"License :: OSI Approved :: Apache Software License",
|
|
24
|
+
"Operating System :: OS Independent",
|
|
25
|
+
"Programming Language :: Python",
|
|
26
|
+
"Programming Language :: Python :: 3",
|
|
27
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
28
|
+
"Programming Language :: Python :: 3.12",
|
|
29
|
+
"Programming Language :: Python :: 3.13",
|
|
30
|
+
"Programming Language :: Python :: 3.14",
|
|
31
|
+
]
|
|
32
|
+
|
|
33
|
+
[project.urls]
|
|
34
|
+
Homepage = "https://github.com/chuckyblack/pybabel-angularjs"
|
|
35
|
+
|
|
36
|
+
[project.entry-points."babel.extractors"]
|
|
37
|
+
angularjs = "pybabel_angularjs.extractor:extract_angularjs"
|
|
38
|
+
|
|
39
|
+
[tool.setuptools]
|
|
40
|
+
package-dir = { "" = "src" }
|
|
41
|
+
|
|
42
|
+
[tool.setuptools.packages.find]
|
|
43
|
+
where = ["src"]
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
from html.parser import HTMLParser
|
|
2
|
+
from typing import Any, Iterable, Iterator, Mapping, Sequence
|
|
3
|
+
|
|
4
|
+
import re
|
|
5
|
+
|
|
6
|
+
type StandardExtractorEntry = tuple[int, str, str, list[str]]
|
|
7
|
+
type FlaggedExtractorEntry = tuple[int, str, str, list[str], tuple[str, ...]]
|
|
8
|
+
type ExtractorEntry = StandardExtractorEntry | FlaggedExtractorEntry
|
|
9
|
+
type AllowedAttributesByTag = dict[str, list[str]]
|
|
10
|
+
type HtmlAttributes = list[tuple[str, str | None]]
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class TagNotAllowedException(Exception):
|
|
14
|
+
pass
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class TagAttributeNotAllowedException(Exception):
|
|
18
|
+
pass
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class ExtractAttributeNotAllowedException(Exception):
|
|
22
|
+
pass
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class MissingAttributeException(Exception):
|
|
26
|
+
pass
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class AngularJSGettextHTMLParser(HTMLParser):
|
|
30
|
+
"""Parse HTML to find translate directives.
|
|
31
|
+
|
|
32
|
+
Currently this parses for these forms of translation:
|
|
33
|
+
|
|
34
|
+
<p data-translate>content</p>
|
|
35
|
+
The content will be translated. Angular value templating will be
|
|
36
|
+
recognised and transformed into gettext-familiar translation
|
|
37
|
+
entries (i.e. "{$ expression $}" becomes "%(expression)")
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
VOID_TAGS = ("br", "input", "img")
|
|
41
|
+
|
|
42
|
+
def __init__(
|
|
43
|
+
self,
|
|
44
|
+
include_tags: list[str],
|
|
45
|
+
include_attributes: list[str],
|
|
46
|
+
extract_attribute: str,
|
|
47
|
+
allowed_attributes_by_tag: AllowedAttributesByTag,
|
|
48
|
+
include_format_flags: bool = False,
|
|
49
|
+
) -> None:
|
|
50
|
+
super().__init__()
|
|
51
|
+
|
|
52
|
+
self.include_tags: list[str] = include_tags
|
|
53
|
+
self.include_attributes: list[str] = include_attributes
|
|
54
|
+
self.extract_attribute: str = extract_attribute
|
|
55
|
+
self.allowed_attributes_by_tag: AllowedAttributesByTag = allowed_attributes_by_tag
|
|
56
|
+
self.include_format_flags = include_format_flags
|
|
57
|
+
|
|
58
|
+
self.in_translate: bool = False
|
|
59
|
+
self.inner_tags: list[str] = []
|
|
60
|
+
self.data: list[str] = []
|
|
61
|
+
self.entries: list[ExtractorEntry] = []
|
|
62
|
+
self.start_lineno: int = 0
|
|
63
|
+
self.comments: list[str] = []
|
|
64
|
+
self.re_collapse_whitespaces: re.Pattern[str] = re.compile(r"\s+")
|
|
65
|
+
self.in_do_not_translate: bool = False
|
|
66
|
+
|
|
67
|
+
@property
|
|
68
|
+
def do_not_extract_attribute(self) -> str:
|
|
69
|
+
return "no-" + self.extract_attribute
|
|
70
|
+
|
|
71
|
+
def normalize_string(self, string: str, replace_whitespace: str = " ") -> str:
|
|
72
|
+
"""
|
|
73
|
+
:type string: str
|
|
74
|
+
:type replace_whitespace: str
|
|
75
|
+
"""
|
|
76
|
+
string = (
|
|
77
|
+
string
|
|
78
|
+
.replace("\n", " ")
|
|
79
|
+
.replace("\t", " ")
|
|
80
|
+
.replace(" ", " ")
|
|
81
|
+
)
|
|
82
|
+
return self.re_collapse_whitespaces.sub(replace_whitespace, string).strip()
|
|
83
|
+
|
|
84
|
+
def add_entry(self, message: str, comments: Sequence[str] | None = None, lineno: int | None = None) -> None:
|
|
85
|
+
comments = comments or []
|
|
86
|
+
entry: StandardExtractorEntry = (
|
|
87
|
+
lineno or self.start_lineno,
|
|
88
|
+
"gettext",
|
|
89
|
+
self.normalize_string(message),
|
|
90
|
+
[self.normalize_string(comment) for comment in comments],
|
|
91
|
+
)
|
|
92
|
+
if self.include_format_flags:
|
|
93
|
+
flags = ("angularjs-format",) if "{{" in message else ()
|
|
94
|
+
self.entries.append((*entry, flags))
|
|
95
|
+
else:
|
|
96
|
+
self.entries.append(entry)
|
|
97
|
+
|
|
98
|
+
def append_inner_tag(self, tag: str) -> None:
|
|
99
|
+
if tag not in self.VOID_TAGS:
|
|
100
|
+
self.inner_tags.append(tag)
|
|
101
|
+
|
|
102
|
+
def handle_startendtag(self, tag: str, attrs: HtmlAttributes) -> None:
|
|
103
|
+
self.handle_starttag(tag, attrs)
|
|
104
|
+
if tag not in self.VOID_TAGS:
|
|
105
|
+
self.handle_endtag(tag)
|
|
106
|
+
|
|
107
|
+
def attrdict_contains(self, attrdict: Mapping[str, str | None], search: Sequence[str] | None = None) -> bool:
|
|
108
|
+
search = search or [self.extract_attribute, self.do_not_extract_attribute]
|
|
109
|
+
for attr in attrdict:
|
|
110
|
+
for prefix in search:
|
|
111
|
+
if attr.startswith(prefix):
|
|
112
|
+
return True
|
|
113
|
+
return False
|
|
114
|
+
|
|
115
|
+
def handle_starttag(self, tag: str, attrs: HtmlAttributes) -> None:
|
|
116
|
+
attrdict = dict(attrs)
|
|
117
|
+
lineno = self.getpos()[0]
|
|
118
|
+
|
|
119
|
+
if self.in_do_not_translate:
|
|
120
|
+
if self.attrdict_contains(attrdict):
|
|
121
|
+
raise ExtractAttributeNotAllowedException((lineno, tag, attrdict))
|
|
122
|
+
self.append_inner_tag(tag)
|
|
123
|
+
return
|
|
124
|
+
|
|
125
|
+
if self.in_translate and (
|
|
126
|
+
self.extract_attribute in attrdict or self.do_not_extract_attribute in attrdict
|
|
127
|
+
):
|
|
128
|
+
raise ExtractAttributeNotAllowedException((lineno, tag, attrdict))
|
|
129
|
+
|
|
130
|
+
if tag == "div" and self.do_not_extract_attribute in attrdict:
|
|
131
|
+
self.in_do_not_translate = True
|
|
132
|
+
if self.attrdict_contains(attrdict, [self.extract_attribute]):
|
|
133
|
+
raise ExtractAttributeNotAllowedException((lineno, tag, attrdict))
|
|
134
|
+
return
|
|
135
|
+
|
|
136
|
+
# handle data-translate attribute for translating content
|
|
137
|
+
if self.in_translate:
|
|
138
|
+
if tag not in self.allowed_attributes_by_tag:
|
|
139
|
+
raise TagNotAllowedException((lineno, tag))
|
|
140
|
+
|
|
141
|
+
allowed_attributes = self.allowed_attributes_by_tag[tag]
|
|
142
|
+
diff_attributes = set(attrdict.keys()) - set(allowed_attributes)
|
|
143
|
+
for attr in diff_attributes:
|
|
144
|
+
if attr.startswith(self.extract_attribute + "-"): # i18n-
|
|
145
|
+
pair_attr = attr.removeprefix(self.extract_attribute + "-")
|
|
146
|
+
else:
|
|
147
|
+
pair_attr = f"{self.extract_attribute}-{attr}"
|
|
148
|
+
if pair_attr not in attrdict:
|
|
149
|
+
raise TagAttributeNotAllowedException((lineno, tag, attrdict))
|
|
150
|
+
|
|
151
|
+
if attrs:
|
|
152
|
+
rendered_attrs = " ".join(f'{name}="{value or ""}"' for name, value in attrs)
|
|
153
|
+
self.data.append(f"<{tag} {rendered_attrs}>")
|
|
154
|
+
else:
|
|
155
|
+
self.data.append(f"<{tag}>")
|
|
156
|
+
|
|
157
|
+
self.append_inner_tag(tag)
|
|
158
|
+
elif self.extract_attribute in attrdict or (tag in self.include_tags and self.do_not_extract_attribute not in attrdict):
|
|
159
|
+
self.start_lineno = lineno
|
|
160
|
+
self.in_translate = True
|
|
161
|
+
comment = attrdict.get(self.extract_attribute)
|
|
162
|
+
if comment:
|
|
163
|
+
self.comments.append(comment)
|
|
164
|
+
|
|
165
|
+
already_added_attrs = []
|
|
166
|
+
# auto-add attributes
|
|
167
|
+
for attr in self.include_attributes:
|
|
168
|
+
exclude_attribute = f"{self.do_not_extract_attribute}-{attr}"
|
|
169
|
+
value = attrdict.get(attr)
|
|
170
|
+
if value is not None and exclude_attribute not in attrdict:
|
|
171
|
+
self.add_entry(value, [attr], lineno)
|
|
172
|
+
already_added_attrs.append(attr)
|
|
173
|
+
|
|
174
|
+
# i18n-marked attributes
|
|
175
|
+
for attr in attrdict:
|
|
176
|
+
if attr.startswith(self.extract_attribute + "-"):
|
|
177
|
+
name = attr.removeprefix(self.extract_attribute + "-")
|
|
178
|
+
if name not in attrdict:
|
|
179
|
+
raise MissingAttributeException((lineno, tag, name))
|
|
180
|
+
|
|
181
|
+
value = attrdict[name]
|
|
182
|
+
if value is not None and name not in already_added_attrs:
|
|
183
|
+
self.add_entry(value, [name], lineno)
|
|
184
|
+
|
|
185
|
+
def handle_data(self, data: str) -> None:
|
|
186
|
+
if self.in_translate:
|
|
187
|
+
self.data.append(data)
|
|
188
|
+
|
|
189
|
+
def handle_endtag(self, tag: str) -> None:
|
|
190
|
+
if self.in_do_not_translate:
|
|
191
|
+
if len(self.inner_tags) > 0:
|
|
192
|
+
self.inner_tags.pop()
|
|
193
|
+
return
|
|
194
|
+
|
|
195
|
+
self.in_do_not_translate = False
|
|
196
|
+
|
|
197
|
+
if self.in_translate:
|
|
198
|
+
if len(self.inner_tags) > 0:
|
|
199
|
+
tag = self.inner_tags.pop()
|
|
200
|
+
self.data.append(f"</{tag}>")
|
|
201
|
+
return
|
|
202
|
+
|
|
203
|
+
self.add_entry("".join(self.data), self.comments)
|
|
204
|
+
self.in_translate = False
|
|
205
|
+
self.data.clear()
|
|
206
|
+
self.comments = []
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
def get_option_list(options: Mapping[str, str], name: str, default: list[str] | None = None) -> list[str]:
|
|
210
|
+
if default is None:
|
|
211
|
+
default = []
|
|
212
|
+
value = options.get(name)
|
|
213
|
+
return value.replace(",", " ").split() if value else default
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
def get_option_bool(options: Mapping[str, str], name: str, default: bool = False) -> bool:
|
|
217
|
+
value = options.get(name)
|
|
218
|
+
if value is None:
|
|
219
|
+
return default
|
|
220
|
+
if isinstance(value, bool):
|
|
221
|
+
return value
|
|
222
|
+
normalized_value = value.strip().lower()
|
|
223
|
+
if normalized_value in {"1", "true", "yes", "on"}:
|
|
224
|
+
return True
|
|
225
|
+
if normalized_value in {"0", "false", "no", "off"}:
|
|
226
|
+
return False
|
|
227
|
+
raise ValueError(f"Invalid boolean value for {name}: {value!r}")
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
def extract_angularjs(
|
|
231
|
+
fileobj: Iterable[str | bytes],
|
|
232
|
+
keywords: Any,
|
|
233
|
+
comment_tags: Any,
|
|
234
|
+
options: Mapping[str, str],
|
|
235
|
+
) -> Iterator[ExtractorEntry]:
|
|
236
|
+
"""Extract messages from AngularJS template (HTML) files that use the
|
|
237
|
+
data-translate directive as per.
|
|
238
|
+
|
|
239
|
+
:param fileobj: the file-like object the messages should be extracted from
|
|
240
|
+
:param keywords: This is a standard parameter so it isaccepted but ignored.
|
|
241
|
+
:param comment_tags: This is a standard parameter so it is accepted but ignored.
|
|
242
|
+
:param options: Extractor configuration options.
|
|
243
|
+
:return: an iterator over ``(lineno, funcname, message, comments)`` tuples,
|
|
244
|
+
optionally extended by a fifth ``flags`` value
|
|
245
|
+
:rtype: ``iterator``
|
|
246
|
+
"""
|
|
247
|
+
include_tags = get_option_list(options, "include_tags")
|
|
248
|
+
include_attributes = get_option_list(options, "include_attributes")
|
|
249
|
+
allowed_tags = get_option_list(options, "allowed_tags", ["strong", "br", "i"])
|
|
250
|
+
extract_attribute = options.get("extract_attribute") or "i18n"
|
|
251
|
+
include_format_flags = get_option_bool(options, "include_format_flags")
|
|
252
|
+
allowed_attributes_by_tag = {tag: get_option_list(options, "allowed_attributes_" + tag) for tag in allowed_tags}
|
|
253
|
+
encoding = options.get('encoding', 'utf-8')
|
|
254
|
+
|
|
255
|
+
parser = AngularJSGettextHTMLParser(
|
|
256
|
+
include_tags,
|
|
257
|
+
include_attributes,
|
|
258
|
+
extract_attribute,
|
|
259
|
+
allowed_attributes_by_tag,
|
|
260
|
+
include_format_flags,
|
|
261
|
+
)
|
|
262
|
+
|
|
263
|
+
for line in fileobj:
|
|
264
|
+
if isinstance(line, bytes):
|
|
265
|
+
line = line.decode(encoding)
|
|
266
|
+
line = line.replace("
", "<br>")
|
|
267
|
+
line = line.replace(" ", " ")
|
|
268
|
+
parser.feed(line)
|
|
269
|
+
|
|
270
|
+
yield from parser.entries
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pybabel-angularjs
|
|
3
|
+
Version: 1.5.0
|
|
4
|
+
Summary: An AngularJS extractor for Babel
|
|
5
|
+
Author-email: Jaromír Pufler <jaromir.pufler@gmail.com>
|
|
6
|
+
License: Apache Software License
|
|
7
|
+
Project-URL: Homepage, https://github.com/chuckyblack/pybabel-angularjs
|
|
8
|
+
Keywords: angularjs,gettext,babel,i18n,translate
|
|
9
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: Topic :: Software Development :: Internationalization
|
|
12
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: Programming Language :: Python
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
20
|
+
Requires-Python: >=3.12
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
License-File: LICENSE
|
|
23
|
+
Requires-Dist: babel
|
|
24
|
+
Dynamic: license-file
|
|
25
|
+
|
|
26
|
+
# pybabel-angularjs
|
|
27
|
+
|
|
28
|
+
[](https://github.com/chuckyblack/pybabel-angularjs/actions/workflows/release.yml)
|
|
29
|
+
[](https://pypi.org/project/pybabel-angularjs/)
|
|
30
|
+
|
|
31
|
+
A [Babel](https://babel.pocoo.org/) message extractor for AngularJS HTML
|
|
32
|
+
templates. It extracts element content and attributes marked for translation,
|
|
33
|
+
including strings containing AngularJS expressions such as `{{ name }}`.
|
|
34
|
+
|
|
35
|
+
Requires Python 3.12 or newer.
|
|
36
|
+
|
|
37
|
+
## Installation
|
|
38
|
+
|
|
39
|
+
```console
|
|
40
|
+
python -m pip install pybabel-angularjs
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
The package installs the `angularjs` Babel extractor entry point. Add it to a
|
|
44
|
+
Babel mapping file such as `babel.cfg`:
|
|
45
|
+
|
|
46
|
+
```ini
|
|
47
|
+
[angularjs: **/*.html]
|
|
48
|
+
encoding = utf-8
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Then extract messages in the usual way:
|
|
52
|
+
|
|
53
|
+
```console
|
|
54
|
+
pybabel extract -F babel.cfg -o messages.pot .
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Marking messages
|
|
58
|
+
|
|
59
|
+
Mark an element's content with `i18n`:
|
|
60
|
+
|
|
61
|
+
```html
|
|
62
|
+
<div i18n>Hello world!</div>
|
|
63
|
+
<p i18n>Hello {{ name }}!</p>
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
The value of `i18n`, when present, is included as a comment for translators:
|
|
67
|
+
|
|
68
|
+
```html
|
|
69
|
+
<h1 i18n="Page heading">Welcome</h1>
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Mark an individual attribute by adding the `i18n-` prefix:
|
|
73
|
+
|
|
74
|
+
```html
|
|
75
|
+
<input placeholder="Your name" i18n-placeholder>
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Configuration
|
|
79
|
+
|
|
80
|
+
Options are set in the extractor section of the Babel mapping file. Lists can
|
|
81
|
+
be separated by commas or whitespace.
|
|
82
|
+
|
|
83
|
+
```ini
|
|
84
|
+
[angularjs: **/*.html]
|
|
85
|
+
encoding = utf-8
|
|
86
|
+
include_tags = h1, h2, p
|
|
87
|
+
include_attributes = title, alt, placeholder
|
|
88
|
+
allowed_tags = a, strong, br, i
|
|
89
|
+
allowed_attributes_a = href, target
|
|
90
|
+
include_format_flags = false
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
- `extract_attribute` changes the marker from the default `i18n`, for example
|
|
94
|
+
to `data-translate`.
|
|
95
|
+
- `include_tags` extracts all content from the listed tags without requiring an
|
|
96
|
+
explicit marker.
|
|
97
|
+
- `include_attributes` extracts the listed attributes wherever they occur.
|
|
98
|
+
- `allowed_tags` controls which nested HTML tags may appear inside a translated
|
|
99
|
+
message. The default is `strong, br, i`.
|
|
100
|
+
- `allowed_attributes_<tag>` controls attributes allowed on a nested tag, for
|
|
101
|
+
example `allowed_attributes_a = href, target`.
|
|
102
|
+
- `encoding` controls template decoding and defaults to `utf-8`.
|
|
103
|
+
- `include_format_flags` makes the extractor return an extended five-value
|
|
104
|
+
result and marks messages containing AngularJS interpolation with
|
|
105
|
+
`angularjs-format`. It defaults to `false` because official Babel releases
|
|
106
|
+
accept only the standard four-value extractor result. Enable it only with a
|
|
107
|
+
Babel build that explicitly supports extractor-provided flags.
|
|
108
|
+
|
|
109
|
+
Use `no-i18n` to exclude an automatically included tag. A `<div no-i18n>`
|
|
110
|
+
excludes its entire subtree. For automatically included attributes, use the
|
|
111
|
+
corresponding marker such as `no-i18n-title`.
|
|
112
|
+
|
|
113
|
+
## License
|
|
114
|
+
|
|
115
|
+
Apache License 2.0. The project was heavily inspired by the original
|
|
116
|
+
[shoreware/pybabel-angularjs](https://bitbucket.org/shoreware/pybabel-angularjs).
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
babel
|
pybabel-angularjs-1.3.5/PKG-INFO
DELETED
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 1.1
|
|
2
|
-
Name: pybabel-angularjs
|
|
3
|
-
Version: 1.3.5
|
|
4
|
-
Summary: An AngularJS extractor for Babel
|
|
5
|
-
Home-page: https://github.com/chuckyblack/pybabel-angularjs
|
|
6
|
-
Author: Jaromír Pufler
|
|
7
|
-
Author-email: jaromir.pufler@gmail.com
|
|
8
|
-
License: Apache Software License
|
|
9
|
-
Description: pybabel-angularjs
|
|
10
|
-
=================
|
|
11
|
-
|
|
12
|
-
[](https://travis-ci.org/chuckyblack/pybabel-angularjs.svg?branch=master)
|
|
13
|
-
|
|
14
|
-
A Babel extractor for AngularJS templates.
|
|
15
|
-
|
|
16
|
-
To translate the content of an HTML element use the `i18n`
|
|
17
|
-
attribute:
|
|
18
|
-
|
|
19
|
-
<div i18n>hello world!</div>
|
|
20
|
-
|
|
21
|
-
To give somme context to your translators add value to the attribute:
|
|
22
|
-
|
|
23
|
-
<div i18n="page title">hello world!</div>
|
|
24
|
-
|
|
25
|
-
## Babel configuration
|
|
26
|
-
|
|
27
|
-
### extract_attribute
|
|
28
|
-
|
|
29
|
-
To change default `i18n` attribute use `extract_attribute` options:
|
|
30
|
-
|
|
31
|
-
[angularjs: **/*.html]
|
|
32
|
-
encoding = utf-8
|
|
33
|
-
extract_attribute = translate
|
|
34
|
-
|
|
35
|
-
Then use in template:
|
|
36
|
-
|
|
37
|
-
<div translate="page title">hello world!</div>
|
|
38
|
-
|
|
39
|
-
### include_attributes
|
|
40
|
-
|
|
41
|
-
To translate attributes of HTML nodes use `include_attributes` options:
|
|
42
|
-
|
|
43
|
-
[angularjs: **/*.html]
|
|
44
|
-
encoding = utf-8
|
|
45
|
-
include_attributes = title, alt
|
|
46
|
-
|
|
47
|
-
Then use in template:
|
|
48
|
-
|
|
49
|
-
<div title="some title">hello world!</div>
|
|
50
|
-
<img src="..." alt="some image description">
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
### allowed_tags
|
|
54
|
-
|
|
55
|
-
Content of every translated tag is checked for tags it contains. You have to define sub-tags that can occur.
|
|
56
|
-
Tags allowed by default are: strong, br, i
|
|
57
|
-
|
|
58
|
-
[angularjs: **/*.html]
|
|
59
|
-
encoding = utf-8
|
|
60
|
-
allowed_tags = a, strong, br
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
### allowed_attributes_x
|
|
64
|
-
|
|
65
|
-
Sub-tags (described in 'allowed_tags') may by default contain NO attributes at all.
|
|
66
|
-
If you want to enable them to, you have to use this notation:
|
|
67
|
-
|
|
68
|
-
[angularjs: **/*.html]
|
|
69
|
-
encoding = utf-8
|
|
70
|
-
allowed_tags = a, i
|
|
71
|
-
allowed_attributes_a = href
|
|
72
|
-
allowed_attributes_i = class
|
|
73
|
-
|
|
74
|
-
The allowed_attribues_x setting needs to be accompanied by appropriate 'allowed_tags' setting.
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
Heavily inspired by
|
|
78
|
-
https://bitbucket.org/shoreware/pybabel-angularjs
|
|
79
|
-
|
|
80
|
-
Keywords: angularjs gettext babel i18n translate
|
|
81
|
-
Platform: UNKNOWN
|
|
82
|
-
Classifier: Development Status :: 5 - Production/Stable
|
|
83
|
-
Classifier: Intended Audience :: Developers
|
|
84
|
-
Classifier: Topic :: Software Development :: Internationalization
|
|
85
|
-
Classifier: License :: OSI Approved :: Apache Software License
|
|
86
|
-
Classifier: Operating System :: OS Independent
|
|
87
|
-
Classifier: Programming Language :: Python
|
|
88
|
-
Classifier: Programming Language :: Python :: 2
|
|
89
|
-
Classifier: Programming Language :: Python :: 2.6
|
|
90
|
-
Classifier: Programming Language :: Python :: 2.7
|
|
91
|
-
Classifier: Programming Language :: Python :: 3
|
|
92
|
-
Classifier: Programming Language :: Python :: 3.2
|
|
93
|
-
Classifier: Programming Language :: Python :: 3.3
|
|
94
|
-
Classifier: Programming Language :: Python :: 3.4
|
|
95
|
-
Classifier: Programming Language :: Python :: 3.5
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
pybabel-angularjs
|
|
2
|
-
=================
|
|
3
|
-
|
|
4
|
-
[](https://travis-ci.org/chuckyblack/pybabel-angularjs.svg?branch=master)
|
|
5
|
-
|
|
6
|
-
A Babel extractor for AngularJS templates.
|
|
7
|
-
|
|
8
|
-
To translate the content of an HTML element use the `i18n`
|
|
9
|
-
attribute:
|
|
10
|
-
|
|
11
|
-
<div i18n>hello world!</div>
|
|
12
|
-
|
|
13
|
-
To give somme context to your translators add value to the attribute:
|
|
14
|
-
|
|
15
|
-
<div i18n="page title">hello world!</div>
|
|
16
|
-
|
|
17
|
-
## Babel configuration
|
|
18
|
-
|
|
19
|
-
### extract_attribute
|
|
20
|
-
|
|
21
|
-
To change default `i18n` attribute use `extract_attribute` options:
|
|
22
|
-
|
|
23
|
-
[angularjs: **/*.html]
|
|
24
|
-
encoding = utf-8
|
|
25
|
-
extract_attribute = translate
|
|
26
|
-
|
|
27
|
-
Then use in template:
|
|
28
|
-
|
|
29
|
-
<div translate="page title">hello world!</div>
|
|
30
|
-
|
|
31
|
-
### include_attributes
|
|
32
|
-
|
|
33
|
-
To translate attributes of HTML nodes use `include_attributes` options:
|
|
34
|
-
|
|
35
|
-
[angularjs: **/*.html]
|
|
36
|
-
encoding = utf-8
|
|
37
|
-
include_attributes = title, alt
|
|
38
|
-
|
|
39
|
-
Then use in template:
|
|
40
|
-
|
|
41
|
-
<div title="some title">hello world!</div>
|
|
42
|
-
<img src="..." alt="some image description">
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
### allowed_tags
|
|
46
|
-
|
|
47
|
-
Content of every translated tag is checked for tags it contains. You have to define sub-tags that can occur.
|
|
48
|
-
Tags allowed by default are: strong, br, i
|
|
49
|
-
|
|
50
|
-
[angularjs: **/*.html]
|
|
51
|
-
encoding = utf-8
|
|
52
|
-
allowed_tags = a, strong, br
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
### allowed_attributes_x
|
|
56
|
-
|
|
57
|
-
Sub-tags (described in 'allowed_tags') may by default contain NO attributes at all.
|
|
58
|
-
If you want to enable them to, you have to use this notation:
|
|
59
|
-
|
|
60
|
-
[angularjs: **/*.html]
|
|
61
|
-
encoding = utf-8
|
|
62
|
-
allowed_tags = a, i
|
|
63
|
-
allowed_attributes_a = href
|
|
64
|
-
allowed_attributes_i = class
|
|
65
|
-
|
|
66
|
-
The allowed_attribues_x setting needs to be accompanied by appropriate 'allowed_tags' setting.
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
Heavily inspired by
|
|
70
|
-
https://bitbucket.org/shoreware/pybabel-angularjs
|
pybabel-angularjs-1.3.5/setup.py
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
# coding=utf-8
|
|
2
|
-
|
|
3
|
-
from setuptools import setup, find_packages
|
|
4
|
-
|
|
5
|
-
setup(
|
|
6
|
-
name="pybabel-angularjs",
|
|
7
|
-
version="1.3.5",
|
|
8
|
-
author="Jaromír Pufler",
|
|
9
|
-
author_email="jaromir.pufler@gmail.com",
|
|
10
|
-
url="https://github.com/chuckyblack/pybabel-angularjs",
|
|
11
|
-
description="An AngularJS extractor for Babel",
|
|
12
|
-
long_description=open('README.md').read(),
|
|
13
|
-
package_dir={'': 'src'},
|
|
14
|
-
packages=find_packages('src'),
|
|
15
|
-
install_requires=['babel', 'beautifulsoup4'],
|
|
16
|
-
setup_requires=['pytest-runner'],
|
|
17
|
-
tests_require=['pytest'],
|
|
18
|
-
entry_points={
|
|
19
|
-
'babel.extractors': [
|
|
20
|
-
'angularjs=pybabel_angularjs.extractor:extract_angularjs',
|
|
21
|
-
],
|
|
22
|
-
},
|
|
23
|
-
license="Apache Software License",
|
|
24
|
-
keywords="angularjs gettext babel i18n translate",
|
|
25
|
-
classifiers=[
|
|
26
|
-
"Development Status :: 5 - Production/Stable",
|
|
27
|
-
"Intended Audience :: Developers",
|
|
28
|
-
"Topic :: Software Development :: Internationalization",
|
|
29
|
-
"License :: OSI Approved :: Apache Software License",
|
|
30
|
-
"Operating System :: OS Independent",
|
|
31
|
-
"Programming Language :: Python",
|
|
32
|
-
"Programming Language :: Python :: 2",
|
|
33
|
-
"Programming Language :: Python :: 2.6",
|
|
34
|
-
"Programming Language :: Python :: 2.7",
|
|
35
|
-
"Programming Language :: Python :: 3",
|
|
36
|
-
"Programming Language :: Python :: 3.2",
|
|
37
|
-
"Programming Language :: Python :: 3.3",
|
|
38
|
-
"Programming Language :: Python :: 3.4",
|
|
39
|
-
"Programming Language :: Python :: 3.5",
|
|
40
|
-
],
|
|
41
|
-
)
|
|
@@ -1,235 +0,0 @@
|
|
|
1
|
-
# coding=utf-8
|
|
2
|
-
|
|
3
|
-
try:
|
|
4
|
-
from html.parser import HTMLParser
|
|
5
|
-
except ImportError:
|
|
6
|
-
from HTMLParser import HTMLParser
|
|
7
|
-
|
|
8
|
-
import re
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
class TagNotAllowedException(Exception):
|
|
12
|
-
pass
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
class TagAttributeNotAllowedException(Exception):
|
|
16
|
-
pass
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
class ExtractAttributeNotAllowedException(Exception):
|
|
20
|
-
pass
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
class MissingAttributeException(Exception):
|
|
24
|
-
pass
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
class AngularJSGettextHTMLParser(HTMLParser):
|
|
28
|
-
"""Parse HTML to find translate directives.
|
|
29
|
-
|
|
30
|
-
Currently this parses for these forms of translation:
|
|
31
|
-
|
|
32
|
-
<p data-translate>content</p>
|
|
33
|
-
The content will be translated. Angular value templating will be
|
|
34
|
-
recognised and transformed into gettext-familiar translation
|
|
35
|
-
entries (i.e. "{$ expression $}" becomes "%(expression)")
|
|
36
|
-
"""
|
|
37
|
-
|
|
38
|
-
def __init__(self, encoding, include_tags, include_attributes, extract_attribute, allowed_attributes_by_tag):
|
|
39
|
-
try:
|
|
40
|
-
super(AngularJSGettextHTMLParser, self).__init__()
|
|
41
|
-
except TypeError:
|
|
42
|
-
HTMLParser.__init__(self)
|
|
43
|
-
|
|
44
|
-
self.encoding = encoding
|
|
45
|
-
self.include_tags = include_tags
|
|
46
|
-
self.include_attributes = include_attributes
|
|
47
|
-
self.extract_attribute = extract_attribute
|
|
48
|
-
self.allowed_attributes_by_tag = allowed_attributes_by_tag
|
|
49
|
-
|
|
50
|
-
self.in_translate = False
|
|
51
|
-
self.inner_tags = []
|
|
52
|
-
self.data = ''
|
|
53
|
-
self.entries = []
|
|
54
|
-
self.start_lineno = 0
|
|
55
|
-
self.plural = False
|
|
56
|
-
self.plural_form = ''
|
|
57
|
-
self.comments = []
|
|
58
|
-
self.re_collapse_whitespaces = re.compile("\s+")
|
|
59
|
-
self.in_do_not_translate = False
|
|
60
|
-
|
|
61
|
-
@property
|
|
62
|
-
def do_not_extract_attribute(self):
|
|
63
|
-
return "no-" + self.extract_attribute
|
|
64
|
-
|
|
65
|
-
def normalize_string(self, string, replace_whitespace=u" "):
|
|
66
|
-
"""
|
|
67
|
-
:type string: str
|
|
68
|
-
:type replace_whitespace: str
|
|
69
|
-
"""
|
|
70
|
-
string = (
|
|
71
|
-
string
|
|
72
|
-
.replace("\n", " ")
|
|
73
|
-
.replace("\t", " ")
|
|
74
|
-
.replace("/>", ">")
|
|
75
|
-
.replace("</br>", "")
|
|
76
|
-
.replace(u" ", " ")
|
|
77
|
-
)
|
|
78
|
-
if isinstance(string, bytes):
|
|
79
|
-
string = string.decode("utf-8")
|
|
80
|
-
return self.re_collapse_whitespaces.sub(replace_whitespace, string).strip()
|
|
81
|
-
|
|
82
|
-
def add_entry(self, message, comments=[], lineno=None):
|
|
83
|
-
self.entries.append(
|
|
84
|
-
(
|
|
85
|
-
lineno or self.start_lineno,
|
|
86
|
-
u'gettext',
|
|
87
|
-
self.normalize_string(message),
|
|
88
|
-
[self.normalize_string(comment) for comment in comments],
|
|
89
|
-
("angularjs-format", ) if "{{" in message else tuple()
|
|
90
|
-
)
|
|
91
|
-
)
|
|
92
|
-
|
|
93
|
-
def append_inner_tag(self, tag):
|
|
94
|
-
if tag not in ("br", "input", "img"):
|
|
95
|
-
self.inner_tags.append(tag)
|
|
96
|
-
|
|
97
|
-
def attrdict_contains(self, attrdict, search=None):
|
|
98
|
-
search = search or [self.extract_attribute, self.do_not_extract_attribute]
|
|
99
|
-
for attr in attrdict: # type: str
|
|
100
|
-
for string in search:
|
|
101
|
-
if attr.startswith(string):
|
|
102
|
-
return True
|
|
103
|
-
return False
|
|
104
|
-
|
|
105
|
-
def handle_starttag(self, tag, attrs):
|
|
106
|
-
attrdict = dict(attrs)
|
|
107
|
-
lineno = self.getpos()[0]
|
|
108
|
-
|
|
109
|
-
if self.in_do_not_translate:
|
|
110
|
-
if self.attrdict_contains(attrdict):
|
|
111
|
-
raise ExtractAttributeNotAllowedException((lineno, tag, attrdict))
|
|
112
|
-
self.append_inner_tag(tag)
|
|
113
|
-
return
|
|
114
|
-
|
|
115
|
-
if tag == "div" and self.do_not_extract_attribute in attrdict:
|
|
116
|
-
self.in_do_not_translate = True
|
|
117
|
-
if self.attrdict_contains(attrdict, [self.extract_attribute]):
|
|
118
|
-
raise ExtractAttributeNotAllowedException((lineno, tag, attrdict))
|
|
119
|
-
return
|
|
120
|
-
|
|
121
|
-
# handle data-translate attribute for translating content
|
|
122
|
-
if self.extract_attribute in attrdict or (tag in self.include_tags and self.do_not_extract_attribute not in attrdict):
|
|
123
|
-
self.start_lineno = lineno
|
|
124
|
-
self.in_translate = True
|
|
125
|
-
comment = attrdict.get(self.extract_attribute)
|
|
126
|
-
if comment:
|
|
127
|
-
self.comments.append(comment)
|
|
128
|
-
elif self.in_translate:
|
|
129
|
-
if tag not in self.allowed_attributes_by_tag:
|
|
130
|
-
raise TagNotAllowedException((lineno, tag))
|
|
131
|
-
|
|
132
|
-
allowed_attributes = self.allowed_attributes_by_tag[tag]
|
|
133
|
-
diff_attributes = set(attrdict.keys()) - set(allowed_attributes)
|
|
134
|
-
for attr in diff_attributes:
|
|
135
|
-
if attr.startswith(self.extract_attribute + "-"): # i18n-
|
|
136
|
-
pairAttr = attr.split("-", 1)[1]
|
|
137
|
-
else:
|
|
138
|
-
pairAttr = "%s-%s" % (self.extract_attribute, attr)
|
|
139
|
-
if pairAttr not in attrdict:
|
|
140
|
-
raise TagAttributeNotAllowedException((lineno, tag, attrdict))
|
|
141
|
-
|
|
142
|
-
if attrs:
|
|
143
|
-
insert_value = ""
|
|
144
|
-
for attr in attrs:
|
|
145
|
-
name = attr[0]
|
|
146
|
-
value = attr[1]
|
|
147
|
-
insert_value += " " + '%s="%s"' % (name, value or "")
|
|
148
|
-
self.data += '<%s %s>' % (tag, insert_value)
|
|
149
|
-
else:
|
|
150
|
-
self.data += '<%s>' % tag
|
|
151
|
-
|
|
152
|
-
self.append_inner_tag(tag)
|
|
153
|
-
|
|
154
|
-
already_added_attrs = []
|
|
155
|
-
# auto-add attributes
|
|
156
|
-
for attr in self.include_attributes:
|
|
157
|
-
exclude_attribute = "%s-%s" % (self.do_not_extract_attribute, attr)
|
|
158
|
-
if attr in attrdict and exclude_attribute not in attrdict:
|
|
159
|
-
self.add_entry(attrdict[attr], [attr], lineno)
|
|
160
|
-
already_added_attrs.append(attr)
|
|
161
|
-
|
|
162
|
-
# i18n-marked attributes
|
|
163
|
-
for attr in attrdict: # type: str
|
|
164
|
-
if attr.startswith(self.extract_attribute + "-"):
|
|
165
|
-
name = attr.split("-", 1)[1]
|
|
166
|
-
if name not in attrdict:
|
|
167
|
-
raise MissingAttributeException((lineno, tag, name))
|
|
168
|
-
|
|
169
|
-
if name not in already_added_attrs:
|
|
170
|
-
self.add_entry(attrdict[name], [name], lineno)
|
|
171
|
-
|
|
172
|
-
def handle_data(self, data):
|
|
173
|
-
if self.in_translate:
|
|
174
|
-
self.data += data
|
|
175
|
-
|
|
176
|
-
def handle_endtag(self, tag):
|
|
177
|
-
if self.in_do_not_translate:
|
|
178
|
-
if len(self.inner_tags) > 0:
|
|
179
|
-
self.inner_tags.pop()
|
|
180
|
-
return
|
|
181
|
-
|
|
182
|
-
self.in_do_not_translate = False
|
|
183
|
-
|
|
184
|
-
if self.in_translate:
|
|
185
|
-
if len(self.inner_tags) > 0:
|
|
186
|
-
tag = self.inner_tags.pop()
|
|
187
|
-
self.data += "</%s>" % tag
|
|
188
|
-
return
|
|
189
|
-
|
|
190
|
-
self.add_entry(self.data, self.comments)
|
|
191
|
-
self.in_translate = False
|
|
192
|
-
self.data = ''
|
|
193
|
-
self.comments = []
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
def get_option_list(options, name, default=[]):
|
|
197
|
-
value = options.get(name)
|
|
198
|
-
return value and value.split(" ") or default
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
def extract_angularjs(fileobj, keywords, comment_tags, options):
|
|
202
|
-
"""Extract messages from AngularJS template (HTML) files that use the
|
|
203
|
-
data-translate directive as per.
|
|
204
|
-
|
|
205
|
-
:param fileobj: the file-like object the messages should be extracted from
|
|
206
|
-
:param keywords: This is a standard parameter so it isaccepted but ignored.
|
|
207
|
-
:param comment_tags: This is a standard parameter so it is accepted but ignored.
|
|
208
|
-
:param options: Another standard parameter that is accepted but ignored.
|
|
209
|
-
:return: an iterator over ``(lineno, funcname, message, comments, flags)`` tuples
|
|
210
|
-
:rtype: ``iterator``
|
|
211
|
-
"""
|
|
212
|
-
include_tags = get_option_list(options, "include_tags")
|
|
213
|
-
include_attributes = get_option_list(options, "include_attributes")
|
|
214
|
-
allowed_tags = get_option_list(options, "allowed_tags", ["strong", "br", "i"])
|
|
215
|
-
extract_attribute = options.get("extract_attribute") or "i18n"
|
|
216
|
-
allowed_attributes_by_tag = {tag: get_option_list(options, "allowed_attributes_" + tag) for tag in allowed_tags}
|
|
217
|
-
encoding = options.get('encoding', 'utf-8')
|
|
218
|
-
|
|
219
|
-
parser = AngularJSGettextHTMLParser(
|
|
220
|
-
encoding,
|
|
221
|
-
include_tags,
|
|
222
|
-
include_attributes,
|
|
223
|
-
extract_attribute,
|
|
224
|
-
allowed_attributes_by_tag
|
|
225
|
-
)
|
|
226
|
-
|
|
227
|
-
for line in fileobj:
|
|
228
|
-
if isinstance(line, bytes):
|
|
229
|
-
line = line.decode("utf-8")
|
|
230
|
-
line = line.replace("
", "<br>")
|
|
231
|
-
line = line.replace(" ", u" ")
|
|
232
|
-
parser.feed(line)
|
|
233
|
-
|
|
234
|
-
for entry in parser.entries:
|
|
235
|
-
yield entry
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 1.1
|
|
2
|
-
Name: pybabel-angularjs
|
|
3
|
-
Version: 1.3.5
|
|
4
|
-
Summary: An AngularJS extractor for Babel
|
|
5
|
-
Home-page: https://github.com/chuckyblack/pybabel-angularjs
|
|
6
|
-
Author: Jaromír Pufler
|
|
7
|
-
Author-email: jaromir.pufler@gmail.com
|
|
8
|
-
License: Apache Software License
|
|
9
|
-
Description: pybabel-angularjs
|
|
10
|
-
=================
|
|
11
|
-
|
|
12
|
-
[](https://travis-ci.org/chuckyblack/pybabel-angularjs.svg?branch=master)
|
|
13
|
-
|
|
14
|
-
A Babel extractor for AngularJS templates.
|
|
15
|
-
|
|
16
|
-
To translate the content of an HTML element use the `i18n`
|
|
17
|
-
attribute:
|
|
18
|
-
|
|
19
|
-
<div i18n>hello world!</div>
|
|
20
|
-
|
|
21
|
-
To give somme context to your translators add value to the attribute:
|
|
22
|
-
|
|
23
|
-
<div i18n="page title">hello world!</div>
|
|
24
|
-
|
|
25
|
-
## Babel configuration
|
|
26
|
-
|
|
27
|
-
### extract_attribute
|
|
28
|
-
|
|
29
|
-
To change default `i18n` attribute use `extract_attribute` options:
|
|
30
|
-
|
|
31
|
-
[angularjs: **/*.html]
|
|
32
|
-
encoding = utf-8
|
|
33
|
-
extract_attribute = translate
|
|
34
|
-
|
|
35
|
-
Then use in template:
|
|
36
|
-
|
|
37
|
-
<div translate="page title">hello world!</div>
|
|
38
|
-
|
|
39
|
-
### include_attributes
|
|
40
|
-
|
|
41
|
-
To translate attributes of HTML nodes use `include_attributes` options:
|
|
42
|
-
|
|
43
|
-
[angularjs: **/*.html]
|
|
44
|
-
encoding = utf-8
|
|
45
|
-
include_attributes = title, alt
|
|
46
|
-
|
|
47
|
-
Then use in template:
|
|
48
|
-
|
|
49
|
-
<div title="some title">hello world!</div>
|
|
50
|
-
<img src="..." alt="some image description">
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
### allowed_tags
|
|
54
|
-
|
|
55
|
-
Content of every translated tag is checked for tags it contains. You have to define sub-tags that can occur.
|
|
56
|
-
Tags allowed by default are: strong, br, i
|
|
57
|
-
|
|
58
|
-
[angularjs: **/*.html]
|
|
59
|
-
encoding = utf-8
|
|
60
|
-
allowed_tags = a, strong, br
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
### allowed_attributes_x
|
|
64
|
-
|
|
65
|
-
Sub-tags (described in 'allowed_tags') may by default contain NO attributes at all.
|
|
66
|
-
If you want to enable them to, you have to use this notation:
|
|
67
|
-
|
|
68
|
-
[angularjs: **/*.html]
|
|
69
|
-
encoding = utf-8
|
|
70
|
-
allowed_tags = a, i
|
|
71
|
-
allowed_attributes_a = href
|
|
72
|
-
allowed_attributes_i = class
|
|
73
|
-
|
|
74
|
-
The allowed_attribues_x setting needs to be accompanied by appropriate 'allowed_tags' setting.
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
Heavily inspired by
|
|
78
|
-
https://bitbucket.org/shoreware/pybabel-angularjs
|
|
79
|
-
|
|
80
|
-
Keywords: angularjs gettext babel i18n translate
|
|
81
|
-
Platform: UNKNOWN
|
|
82
|
-
Classifier: Development Status :: 5 - Production/Stable
|
|
83
|
-
Classifier: Intended Audience :: Developers
|
|
84
|
-
Classifier: Topic :: Software Development :: Internationalization
|
|
85
|
-
Classifier: License :: OSI Approved :: Apache Software License
|
|
86
|
-
Classifier: Operating System :: OS Independent
|
|
87
|
-
Classifier: Programming Language :: Python
|
|
88
|
-
Classifier: Programming Language :: Python :: 2
|
|
89
|
-
Classifier: Programming Language :: Python :: 2.6
|
|
90
|
-
Classifier: Programming Language :: Python :: 2.7
|
|
91
|
-
Classifier: Programming Language :: Python :: 3
|
|
92
|
-
Classifier: Programming Language :: Python :: 3.2
|
|
93
|
-
Classifier: Programming Language :: Python :: 3.3
|
|
94
|
-
Classifier: Programming Language :: Python :: 3.4
|
|
95
|
-
Classifier: Programming Language :: Python :: 3.5
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pybabel-angularjs-1.3.5 → pybabel_angularjs-1.5.0}/src/pybabel_angularjs.egg-info/top_level.txt
RENAMED
|
File without changes
|