diff --git a/openformats/formats/yaml/utils.py b/openformats/formats/yaml/utils.py
index 1cfcb7c0..22826dca 100644
--- a/openformats/formats/yaml/utils.py
+++ b/openformats/formats/yaml/utils.py
@@ -142,13 +142,19 @@ def _is_custom_tag(self, tag):
Detect custom tags, like:
`foo: !bar test`
`foo: !xml "Bar"`
+
+ The name of the custom tag can have any of the following characters:
+ `a-z`, `A-Z`, `0-9`, `_`, `.`, `:`, `-`.
+ In any other case, we return `False`.
+
Built-in types, indicated by a `!!` prefix, will not be matched. We
can't preserve the information whether a built-in tag like `!!str` was
used for a value since the PyYAML library will tag such entries with
the built-in identifier. For example `tag:yaml.org,2002:str`, not
`!!str`.
"""
- return re.match(ensure_unicode(r'^[\![a-zA-Z_]*]*$'),
+
+ return re.match(ensure_unicode(r'^\![a-zA-Z0-9_:.\-]*$'),
tag,
re.IGNORECASE)
@@ -222,6 +228,8 @@ def construct_mapping(self, node, deep=True):
and self._is_custom_tag(value_node.tag)
):
tag = six.text_type(value_node.tag)
+ # remove the exclamation mark from the tag
+ tag = tag[1:] if tag.startswith('!') else tag
value = Node(value, start, end, style, tag)
pairs.append((key, value))
@@ -349,8 +357,9 @@ def generate_yaml_dict(self, stringset):
yaml_dict, keys, flags, se.string.get(rule), tag=None,
)
else:
+ tag = '!' + se.context if se.context else se.context
self._insert_translation_in_dict(
- yaml_dict, keys, flags, se.string, tag=se.context,
+ yaml_dict, keys, flags, se.string, tag=tag,
)
return yaml_dict
diff --git a/openformats/formats/yaml/yaml.py b/openformats/formats/yaml/yaml.py
index b6d3bd5f..0e4c7295 100644
--- a/openformats/formats/yaml/yaml.py
+++ b/openformats/formats/yaml/yaml.py
@@ -404,7 +404,8 @@ def _compile_from_template(self, template, stringset, **kwargs):
# it and apply a space afterwards so it doesn't get merged with the
# string
if string.context:
- transcriber.add(string.context)
+ # add an exclamation mark to the context to make it a tag
+ transcriber.add('!' + string.context)
transcriber.add(' ')
transcriber.add(translation)
transcriber.skip(len(string.template_replacement))
diff --git a/openformats/tests/formats/yaml/files/1_el.yml b/openformats/tests/formats/yaml/files/1_el.yml
index ae380ac4..45e24e9b 100644
--- a/openformats/tests/formats/yaml/files/1_el.yml
+++ b/openformats/tests/formats/yaml/files/1_el.yml
@@ -77,6 +77,13 @@ hello: "el:World" # Translatable
number: !!int 123 # Should ignore
bin: !!binary aGVsbG8= # Should ignore
+# Custom tags with numbers and symbols
+context_string: !cs:fd-94_fd.dot. "el:context string"
+verbim_context_string: !context:t5-46_qa "el:verbim context string"
+context_on_nested_map:
+ first: !first_context:54KJFLA95KJ4 "el:context in nested map"
+ second: !second_context:FDKJ40DK "el:context in nested map"
+
# Test with non-ASCII keys
#σχόλιο
σχόλιο: "el:κείμενο"
diff --git a/openformats/tests/formats/yaml/files/1_en.yml b/openformats/tests/formats/yaml/files/1_en.yml
index 7d92dfcb..b751cca8 100644
--- a/openformats/tests/formats/yaml/files/1_en.yml
+++ b/openformats/tests/formats/yaml/files/1_en.yml
@@ -80,6 +80,13 @@ hello: !!str World # Translatable
number: !!int 123 # Should ignore
bin: !!binary aGVsbG8= # Should ignore
+# Custom tags with numbers and symbols
+context_string: !cs:fd-94_fd.dot. "context string"
+verbim_context_string: ! "verbim context string"
+context_on_nested_map:
+ first: !first_context:54KJFLA95KJ4 "context in nested map"
+ second: !second_context:FDKJ40DK "context in nested map"
+
# Test with non-ASCII keys
#σχόλιο
σχόλιο: κείμενο
diff --git a/openformats/tests/formats/yaml/files/1_en_exported.yml b/openformats/tests/formats/yaml/files/1_en_exported.yml
index 7a0af47d..4e324640 100644
--- a/openformats/tests/formats/yaml/files/1_en_exported.yml
+++ b/openformats/tests/formats/yaml/files/1_en_exported.yml
@@ -77,6 +77,13 @@ hello: World # Translatable
number: !!int 123 # Should ignore
bin: !!binary aGVsbG8= # Should ignore
+# Custom tags with numbers and symbols
+context_string: !cs:fd-94_fd.dot. "context string"
+verbim_context_string: !context:t5-46_qa "verbim context string"
+context_on_nested_map:
+ first: !first_context:54KJFLA95KJ4 "context in nested map"
+ second: !second_context:FDKJ40DK "context in nested map"
+
# Test with non-ASCII keys
#σχόλιο
σχόλιο: κείμενο
diff --git a/openformats/tests/formats/yaml/files/1_en_exported_without_template.yml b/openformats/tests/formats/yaml/files/1_en_exported_without_template.yml
index cda13ac4..2a21c55f 100644
--- a/openformats/tests/formats/yaml/files/1_en_exported_without_template.yml
+++ b/openformats/tests/formats/yaml/files/1_en_exported_without_template.yml
@@ -39,6 +39,11 @@ alias_key:
foo: !test 'bar'
bar: !xml "foo bar"
hello: World
+context_string: !cs:fd-94_fd.dot. "context string"
+verbim_context_string: !context:t5-46_qa "verbim context string"
+context_on_nested_map:
+ first: "context in nested map"
+ second: "context in nested map"
σχόλιο: κείμενο
emojis: \uD83D\uDC40 🏹🍍🍍 \U0001F418
anchor_with_label:
diff --git a/openformats/tests/formats/yaml/files/1_tpl.yml b/openformats/tests/formats/yaml/files/1_tpl.yml
index f9931de2..0a5efd5d 100644
--- a/openformats/tests/formats/yaml/files/1_tpl.yml
+++ b/openformats/tests/formats/yaml/files/1_tpl.yml
@@ -65,12 +65,19 @@ alias_key:
- ddc3cfcedcf1686d9e3ba6b99a0d091b_tr
# Custom tags
-foo: 3e4000f6f4cd8bb27db6fb82e1b50bb4_tr # Should treat as string and ignore leading spaces
-bar: 75ce597a505a4faf6369b66b885926c8_tr # Also a string
+foo: 023503fb466f78932b77209b6581156e_tr # Should treat as string and ignore leading spaces
+bar: fac8140a2ec031af14bc758e73f59017_tr # Also a string
hello: b0ed9cf22c0a5186d1c5b483a910dd33_tr # Translatable
number: !!int 123 # Should ignore
bin: !!binary aGVsbG8= # Should ignore
+# Custom tags with numbers and symbols
+context_string: 17d854ee46fe3d3bc91fadb4cf4df426_tr
+verbim_context_string: 0a3c1ae205b2c0d09ab69ab540e481f2_tr
+context_on_nested_map:
+ first: 95175e30d6fbfe0f658e75919cd4982c_tr
+ second: dce391c231a7ad7fef9e6cc0ddcbf549_tr
+
# Test with non-ASCII keys
#σχόλιο
σχόλιο: 8687f34a9bf89770b456b48ad2395788_tr
diff --git a/openformats/tests/formats/yaml/test_yaml.py b/openformats/tests/formats/yaml/test_yaml.py
index d547796b..cec516ec 100644
--- a/openformats/tests/formats/yaml/test_yaml.py
+++ b/openformats/tests/formats/yaml/test_yaml.py
@@ -144,7 +144,7 @@ def test_openstring_attributes(self):
self.assertEqual(test_string.flags, '')
content_string = strings[1]
- self.assertEqual(content_string.context, '!tag')
+ self.assertEqual(content_string.context, 'tag')
self.assertEqual(content_string.flags, "'")
def test_parse_duplicate_keys(self):
diff --git a/openformats/tests/formats/yamlinternationalization/files/1_el.yml b/openformats/tests/formats/yamlinternationalization/files/1_el.yml
index 8a76cc8c..7f45b6d8 100644
--- a/openformats/tests/formats/yamlinternationalization/files/1_el.yml
+++ b/openformats/tests/formats/yamlinternationalization/files/1_el.yml
@@ -100,3 +100,10 @@ en:
anchor_mapping: &another_anchor
one: el:one
other: el:other
+
+ # context
+ context_string: !cs:fd-94_fd.dot. "el:context string"
+ verbim_context_string: !context:t5-46_qa "el:verbim context string"
+ context_on_nested_map:
+ first: !first_context:54KJFLA95KJ4 "el:context in nested map"
+ second: !second_context:FDKJ40DK "el:context in nested map"
diff --git a/openformats/tests/formats/yamlinternationalization/files/1_en.yml b/openformats/tests/formats/yamlinternationalization/files/1_en.yml
index 8f7496ca..deb2a70e 100644
--- a/openformats/tests/formats/yamlinternationalization/files/1_en.yml
+++ b/openformats/tests/formats/yamlinternationalization/files/1_en.yml
@@ -104,3 +104,10 @@ en:
anchor_mapping: &another_anchor
one: one
other: other
+
+ # context
+ context_string: !cs:fd-94_fd.dot. "context string"
+ verbim_context_string: ! "verbim context string"
+ context_on_nested_map:
+ first: !first_context:54KJFLA95KJ4 "context in nested map"
+ second: !second_context:FDKJ40DK "context in nested map"
diff --git a/openformats/tests/formats/yamlinternationalization/files/1_en_exported.yml b/openformats/tests/formats/yamlinternationalization/files/1_en_exported.yml
index 6c0fd992..d603d85e 100644
--- a/openformats/tests/formats/yamlinternationalization/files/1_en_exported.yml
+++ b/openformats/tests/formats/yamlinternationalization/files/1_en_exported.yml
@@ -100,3 +100,10 @@ en:
anchor_mapping: &another_anchor
one: one
other: other
+
+ # context
+ context_string: !cs:fd-94_fd.dot. "context string"
+ verbim_context_string: !context:t5-46_qa "verbim context string"
+ context_on_nested_map:
+ first: !first_context:54KJFLA95KJ4 "context in nested map"
+ second: !second_context:FDKJ40DK "context in nested map"
diff --git a/openformats/tests/formats/yamlinternationalization/files/1_en_exported_without_template.yml b/openformats/tests/formats/yamlinternationalization/files/1_en_exported_without_template.yml
index 68ea80f7..1595af46 100644
--- a/openformats/tests/formats/yamlinternationalization/files/1_en_exported_without_template.yml
+++ b/openformats/tests/formats/yamlinternationalization/files/1_en_exported_without_template.yml
@@ -59,3 +59,8 @@ en:
anchor_mapping:
one: one
other: other
+ context_string: !cs:fd-94_fd.dot. "context string"
+ verbim_context_string: !context:t5-46_qa "verbim context string"
+ context_on_nested_map:
+ first: "context in nested map"
+ second: "context in nested map"
diff --git a/openformats/tests/formats/yamlinternationalization/files/1_tpl.yml b/openformats/tests/formats/yamlinternationalization/files/1_tpl.yml
index 656597e7..85943df5 100644
--- a/openformats/tests/formats/yamlinternationalization/files/1_tpl.yml
+++ b/openformats/tests/formats/yamlinternationalization/files/1_tpl.yml
@@ -90,3 +90,10 @@ en:
anchor_mapping: &another_anchor
798cf4a4e275a90e80b0aac837f06793_pl
+
+ # context
+ context_string: 17d854ee46fe3d3bc91fadb4cf4df426_tr
+ verbim_context_string: 0a3c1ae205b2c0d09ab69ab540e481f2_tr
+ context_on_nested_map:
+ first: 95175e30d6fbfe0f658e75919cd4982c_tr
+ second: dce391c231a7ad7fef9e6cc0ddcbf549_tr