diff options
| author | eivanov89 <[email protected]> | 2025-08-29 10:12:02 +0300 |
|---|---|---|
| committer | eivanov89 <[email protected]> | 2025-08-29 10:27:27 +0300 |
| commit | 140ced4d34c422c9f3cbe096f8dd35243b67d6e4 (patch) | |
| tree | b7373341f64151c0ab9839ee692dc919366590d5 /contrib/python/markdown-it-py/markdown_it/_punycode.py | |
| parent | 136471c8b2f3ab8cd7993200c0de0456b7018118 (diff) | |
Add python/textual to YDB
commit_hash:eda16a869229724fec5479fa27fa5cdbccbe0395
Diffstat (limited to 'contrib/python/markdown-it-py/markdown_it/_punycode.py')
| -rw-r--r-- | contrib/python/markdown-it-py/markdown_it/_punycode.py | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/contrib/python/markdown-it-py/markdown_it/_punycode.py b/contrib/python/markdown-it-py/markdown_it/_punycode.py new file mode 100644 index 00000000000..312048bf79c --- /dev/null +++ b/contrib/python/markdown-it-py/markdown_it/_punycode.py @@ -0,0 +1,67 @@ +# Copyright 2014 Mathias Bynens <https://mathiasbynens.be/> +# Copyright 2021 Taneli Hukkinen +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +import codecs +from collections.abc import Callable +import re + +REGEX_SEPARATORS = re.compile(r"[\x2E\u3002\uFF0E\uFF61]") +REGEX_NON_ASCII = re.compile(r"[^\0-\x7E]") + + +def encode(uni: str) -> str: + return codecs.encode(uni, encoding="punycode").decode() + + +def decode(ascii: str) -> str: + return codecs.decode(ascii, encoding="punycode") # type: ignore + + +def map_domain(string: str, fn: Callable[[str], str]) -> str: + parts = string.split("@") + result = "" + if len(parts) > 1: + # In email addresses, only the domain name should be punycoded. Leave + # the local part (i.e. everything up to `@`) intact. + result = parts[0] + "@" + string = parts[1] + labels = REGEX_SEPARATORS.split(string) + encoded = ".".join(fn(label) for label in labels) + return result + encoded + + +def to_unicode(obj: str) -> str: + def mapping(obj: str) -> str: + if obj.startswith("xn--"): + return decode(obj[4:].lower()) + return obj + + return map_domain(obj, mapping) + + +def to_ascii(obj: str) -> str: + def mapping(obj: str) -> str: + if REGEX_NON_ASCII.search(obj): + return "xn--" + encode(obj) + return obj + + return map_domain(obj, mapping) |
