symbolfyi 0.1.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.
@@ -0,0 +1,15 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ *$py.class
4
+ *.egg-info/
5
+ dist/
6
+ build/
7
+ .eggs/
8
+ *.egg
9
+ .venv/
10
+ venv/
11
+ .mypy_cache/
12
+ .ruff_cache/
13
+ .pytest_cache/
14
+ *.so
15
+ .DS_Store
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 FYI-Dev
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,123 @@
1
+ Metadata-Version: 2.4
2
+ Name: symbolfyi
3
+ Version: 0.1.0
4
+ Summary: Pure Python symbol & character encoding toolkit — 11 encoding formats, Unicode properties, HTML entities.
5
+ Project-URL: Homepage, https://symbolfyi.com
6
+ Project-URL: Documentation, https://symbolfyi.com/developers/
7
+ Project-URL: Repository, https://github.com/fyipedia/symbolfyi
8
+ Project-URL: Issues, https://github.com/fyipedia/symbolfyi/issues
9
+ Author: FYIPedia
10
+ License-Expression: MIT
11
+ License-File: LICENSE
12
+ Keywords: character,codepoint,encoding,html-entity,symbol,unicode,utf16,utf8
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Programming Language :: Python :: 3.14
22
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
23
+ Classifier: Topic :: Text Processing :: General
24
+ Classifier: Typing :: Typed
25
+ Requires-Python: >=3.10
26
+ Provides-Extra: full
27
+ Requires-Dist: fonttools>=4.50; extra == 'full'
28
+ Description-Content-Type: text/markdown
29
+
30
+ # symbolfyi
31
+
32
+ [![PyPI](https://img.shields.io/pypi/v/symbolfyi)](https://pypi.org/project/symbolfyi/)
33
+ [![Python](https://img.shields.io/pypi/pyversions/symbolfyi)](https://pypi.org/project/symbolfyi/)
34
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
35
+
36
+ Pure Python symbol & character encoding toolkit. Compute 11 encoding representations and full Unicode properties for any character. Includes 51 HTML entity mappings.
37
+
38
+ > Look up any symbol at [symbolfyi.com](https://symbolfyi.com/)
39
+
40
+ ## Install
41
+
42
+ ```bash
43
+ pip install symbolfyi # Core (zero deps)
44
+ pip install "symbolfyi[full]" # + fonttools for Unicode block/script
45
+ ```
46
+
47
+ ## Quick Start
48
+
49
+ ```python
50
+ from symbolfyi import get_encodings, get_info, lookup_html_entity
51
+
52
+ # Encode any character (11 formats)
53
+ enc = get_encodings("→")
54
+ print(enc.unicode) # U+2192
55
+ print(enc.html_entity) # →
56
+ print(enc.css) # \2192
57
+ print(enc.javascript) # \u{2192}
58
+ print(enc.utf8_bytes) # e2 86 92
59
+ print(enc.url_encoded) # %E2%86%92
60
+
61
+ # Full Unicode properties (requires fonttools for block/script)
62
+ info = get_info("♠")
63
+ print(info.name) # BLACK SPADE SUIT
64
+ print(info.category_name) # Other Symbol
65
+ print(info.block) # Miscellaneous Symbols
66
+ print(info.script) # Common
67
+
68
+ # HTML entity reverse lookup
69
+ char = lookup_html_entity("♥")
70
+ print(char) # ♥
71
+ ```
72
+
73
+ ## API Reference
74
+
75
+ ### Core Functions
76
+
77
+ | Function | Description |
78
+ |----------|-------------|
79
+ | `get_encodings(char) -> EncodingInfo` | Compute 11 encoding representations |
80
+ | `get_info(char) -> SymbolInfo \| None` | Full Unicode properties + encodings |
81
+ | `get_category_name(code) -> str` | Category code to human name |
82
+ | `lookup_html_entity(entity) -> str \| None` | Entity string to character |
83
+
84
+ ### Data Types
85
+
86
+ - **`EncodingInfo`** — 11-field NamedTuple: unicode, html_decimal, html_hex, html_entity, css, javascript, python, java, utf8_bytes, utf16_bytes, url_encoded
87
+ - **`SymbolInfo`** — 12-field NamedTuple: codepoint, character, name, category, category_name, block, script, bidirectional, combining, mirrored, decomposition, encodings
88
+
89
+ ### Constants
90
+
91
+ | Constant | Description |
92
+ |----------|-------------|
93
+ | `GENERAL_CATEGORIES` | 27 Unicode category codes with names |
94
+ | `HTML_ENTITIES` | 51 codepoint-to-entity mappings |
95
+ | `HTML_ENTITY_TO_CHAR` | 51 entity-to-character reverse mappings |
96
+
97
+ ## Features
98
+
99
+ - **11 encoding types**: Unicode, HTML decimal/hex/entity, CSS, JavaScript, Python, Java, UTF-8/UTF-16 bytes, URL-encoded
100
+ - **Unicode properties**: name, category, block, script, bidirectional, combining, mirrored, decomposition
101
+ - **51 HTML entities**: Common entities with bidirectional lookup
102
+ - **Zero required deps**: Core uses only stdlib (`unicodedata`, `urllib.parse`)
103
+ - **Optional fonttools**: Install `symbolfyi[full]` for Unicode block and script info
104
+ - **Type-safe**: Full type annotations, `py.typed` marker (PEP 561)
105
+
106
+ ## Related Packages
107
+
108
+ | Package | Description |
109
+ |---------|-------------|
110
+ | [unicodefyi](https://github.com/fyipedia/unicodefyi) | Extended Unicode toolkit with 17 encodings + character search |
111
+ | [colorfyi](https://github.com/fyipedia/colorfyi) | Color conversion, contrast, harmonies, shades |
112
+ | [emojifyi](https://github.com/fyipedia/emojifyi) | Emoji encoding & metadata for 3,781 emojis |
113
+ | [fontfyi](https://github.com/fyipedia/fontfyi) | Google Fonts metadata, CSS helpers, font pairings |
114
+
115
+ ## Links
116
+
117
+ - [Symbol Browser](https://symbolfyi.com/) — Look up any symbol online
118
+ - [API Documentation](https://symbolfyi.com/developers/) — REST API with free access
119
+ - [Source Code](https://github.com/fyipedia/symbolfyi)
120
+
121
+ ## License
122
+
123
+ MIT
@@ -0,0 +1,94 @@
1
+ # symbolfyi
2
+
3
+ [![PyPI](https://img.shields.io/pypi/v/symbolfyi)](https://pypi.org/project/symbolfyi/)
4
+ [![Python](https://img.shields.io/pypi/pyversions/symbolfyi)](https://pypi.org/project/symbolfyi/)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
6
+
7
+ Pure Python symbol & character encoding toolkit. Compute 11 encoding representations and full Unicode properties for any character. Includes 51 HTML entity mappings.
8
+
9
+ > Look up any symbol at [symbolfyi.com](https://symbolfyi.com/)
10
+
11
+ ## Install
12
+
13
+ ```bash
14
+ pip install symbolfyi # Core (zero deps)
15
+ pip install "symbolfyi[full]" # + fonttools for Unicode block/script
16
+ ```
17
+
18
+ ## Quick Start
19
+
20
+ ```python
21
+ from symbolfyi import get_encodings, get_info, lookup_html_entity
22
+
23
+ # Encode any character (11 formats)
24
+ enc = get_encodings("→")
25
+ print(enc.unicode) # U+2192
26
+ print(enc.html_entity) # →
27
+ print(enc.css) # \2192
28
+ print(enc.javascript) # \u{2192}
29
+ print(enc.utf8_bytes) # e2 86 92
30
+ print(enc.url_encoded) # %E2%86%92
31
+
32
+ # Full Unicode properties (requires fonttools for block/script)
33
+ info = get_info("♠")
34
+ print(info.name) # BLACK SPADE SUIT
35
+ print(info.category_name) # Other Symbol
36
+ print(info.block) # Miscellaneous Symbols
37
+ print(info.script) # Common
38
+
39
+ # HTML entity reverse lookup
40
+ char = lookup_html_entity("♥")
41
+ print(char) # ♥
42
+ ```
43
+
44
+ ## API Reference
45
+
46
+ ### Core Functions
47
+
48
+ | Function | Description |
49
+ |----------|-------------|
50
+ | `get_encodings(char) -> EncodingInfo` | Compute 11 encoding representations |
51
+ | `get_info(char) -> SymbolInfo \| None` | Full Unicode properties + encodings |
52
+ | `get_category_name(code) -> str` | Category code to human name |
53
+ | `lookup_html_entity(entity) -> str \| None` | Entity string to character |
54
+
55
+ ### Data Types
56
+
57
+ - **`EncodingInfo`** — 11-field NamedTuple: unicode, html_decimal, html_hex, html_entity, css, javascript, python, java, utf8_bytes, utf16_bytes, url_encoded
58
+ - **`SymbolInfo`** — 12-field NamedTuple: codepoint, character, name, category, category_name, block, script, bidirectional, combining, mirrored, decomposition, encodings
59
+
60
+ ### Constants
61
+
62
+ | Constant | Description |
63
+ |----------|-------------|
64
+ | `GENERAL_CATEGORIES` | 27 Unicode category codes with names |
65
+ | `HTML_ENTITIES` | 51 codepoint-to-entity mappings |
66
+ | `HTML_ENTITY_TO_CHAR` | 51 entity-to-character reverse mappings |
67
+
68
+ ## Features
69
+
70
+ - **11 encoding types**: Unicode, HTML decimal/hex/entity, CSS, JavaScript, Python, Java, UTF-8/UTF-16 bytes, URL-encoded
71
+ - **Unicode properties**: name, category, block, script, bidirectional, combining, mirrored, decomposition
72
+ - **51 HTML entities**: Common entities with bidirectional lookup
73
+ - **Zero required deps**: Core uses only stdlib (`unicodedata`, `urllib.parse`)
74
+ - **Optional fonttools**: Install `symbolfyi[full]` for Unicode block and script info
75
+ - **Type-safe**: Full type annotations, `py.typed` marker (PEP 561)
76
+
77
+ ## Related Packages
78
+
79
+ | Package | Description |
80
+ |---------|-------------|
81
+ | [unicodefyi](https://github.com/fyipedia/unicodefyi) | Extended Unicode toolkit with 17 encodings + character search |
82
+ | [colorfyi](https://github.com/fyipedia/colorfyi) | Color conversion, contrast, harmonies, shades |
83
+ | [emojifyi](https://github.com/fyipedia/emojifyi) | Emoji encoding & metadata for 3,781 emojis |
84
+ | [fontfyi](https://github.com/fyipedia/fontfyi) | Google Fonts metadata, CSS helpers, font pairings |
85
+
86
+ ## Links
87
+
88
+ - [Symbol Browser](https://symbolfyi.com/) — Look up any symbol online
89
+ - [API Documentation](https://symbolfyi.com/developers/) — REST API with free access
90
+ - [Source Code](https://github.com/fyipedia/symbolfyi)
91
+
92
+ ## License
93
+
94
+ MIT
@@ -0,0 +1,64 @@
1
+ [project]
2
+ name = "symbolfyi"
3
+ version = "0.1.0"
4
+ description = "Pure Python symbol & character encoding toolkit — 11 encoding formats, Unicode properties, HTML entities."
5
+ readme = "README.md"
6
+ license = "MIT"
7
+ requires-python = ">=3.10"
8
+ authors = [{ name = "FYIPedia" }]
9
+ keywords = ["unicode", "symbol", "encoding", "html-entity", "utf8", "utf16", "character", "codepoint"]
10
+ classifiers = [
11
+ "Development Status :: 4 - Beta",
12
+ "Intended Audience :: Developers",
13
+ "License :: OSI Approved :: MIT License",
14
+ "Programming Language :: Python :: 3",
15
+ "Programming Language :: Python :: 3.10",
16
+ "Programming Language :: Python :: 3.11",
17
+ "Programming Language :: Python :: 3.12",
18
+ "Programming Language :: Python :: 3.13",
19
+ "Programming Language :: Python :: 3.14",
20
+ "Topic :: Text Processing :: General",
21
+ "Topic :: Software Development :: Libraries :: Python Modules",
22
+ "Typing :: Typed",
23
+ ]
24
+ dependencies = []
25
+
26
+ [project.optional-dependencies]
27
+ full = ["fonttools>=4.50"]
28
+
29
+ [project.urls]
30
+ Homepage = "https://symbolfyi.com"
31
+ Documentation = "https://symbolfyi.com/developers/"
32
+ Repository = "https://github.com/fyipedia/symbolfyi"
33
+ Issues = "https://github.com/fyipedia/symbolfyi/issues"
34
+
35
+ [build-system]
36
+ requires = ["hatchling"]
37
+ build-backend = "hatchling.build"
38
+
39
+ [tool.hatch.build.targets.wheel]
40
+ packages = ["src/symbolfyi"]
41
+
42
+ [tool.pytest.ini_options]
43
+ testpaths = ["tests"]
44
+ addopts = "-v --tb=short"
45
+
46
+ [tool.ruff]
47
+ target-version = "py310"
48
+ line-length = 100
49
+
50
+ [tool.ruff.lint]
51
+ select = ["E", "F", "I", "UP", "B", "SIM", "RUF"]
52
+ ignore = ["RUF022"]
53
+
54
+ [tool.mypy]
55
+ python_version = "3.10"
56
+ strict = true
57
+
58
+ [dependency-groups]
59
+ dev = [
60
+ "fonttools>=4.50",
61
+ "mypy>=1.19.1",
62
+ "pytest>=9.0.2",
63
+ "ruff>=0.15.4",
64
+ ]
@@ -0,0 +1,58 @@
1
+ """symbolfyi — Pure Python symbol & character encoding toolkit.
2
+
3
+ Compute 11 encoding representations (Unicode, HTML, CSS, JavaScript,
4
+ Python, Java, UTF-8, UTF-16, URL) and Unicode properties for any character.
5
+ Includes 47 HTML entity mappings.
6
+
7
+ Zero required dependencies. Optional ``fonttools`` for block/script info.
8
+
9
+ Usage::
10
+
11
+ from symbolfyi import get_encodings, get_info, lookup_html_entity
12
+
13
+ # Encode any character
14
+ enc = get_encodings("→")
15
+ print(enc.unicode) # U+2192
16
+ print(enc.html_entity) # →
17
+ print(enc.css) # \\2192
18
+ print(enc.utf8_bytes) # e2 86 92
19
+
20
+ # Full Unicode properties
21
+ info = get_info("♠")
22
+ print(info.name) # BLACK SPADE SUIT
23
+ print(info.block) # Miscellaneous Symbols (requires fonttools)
24
+ print(info.category_name) # Other Symbol
25
+
26
+ # HTML entity lookup
27
+ char = lookup_html_entity("♥")
28
+ print(char) # ♥
29
+ """
30
+
31
+ from symbolfyi.engine import (
32
+ GENERAL_CATEGORIES,
33
+ HTML_ENTITIES,
34
+ HTML_ENTITY_TO_CHAR,
35
+ EncodingInfo,
36
+ SymbolInfo,
37
+ get_category_name,
38
+ get_encodings,
39
+ get_info,
40
+ lookup_html_entity,
41
+ )
42
+
43
+ __version__ = "0.1.0"
44
+
45
+ __all__ = [
46
+ # Data types
47
+ "EncodingInfo",
48
+ "SymbolInfo",
49
+ # Core functions
50
+ "get_encodings",
51
+ "get_info",
52
+ "get_category_name",
53
+ "lookup_html_entity",
54
+ # Data
55
+ "GENERAL_CATEGORIES",
56
+ "HTML_ENTITIES",
57
+ "HTML_ENTITY_TO_CHAR",
58
+ ]
@@ -0,0 +1,256 @@
1
+ """Symbol encoding and Unicode property engine — stateless, <1ms per call.
2
+
3
+ Computes 11 encoding representations and Unicode properties for any character.
4
+ Uses stdlib ``unicodedata`` for core properties; ``fontTools`` (optional) for
5
+ Unicode block and script data.
6
+
7
+ Zero required dependencies. Install ``fonttools`` for block/script info::
8
+
9
+ pip install symbolfyi[full]
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ import unicodedata
15
+ from typing import NamedTuple
16
+ from urllib.parse import quote
17
+
18
+ # Try fontTools for block/script (optional dependency)
19
+ try:
20
+ from fontTools.unicodedata import block as ft_block
21
+ from fontTools.unicodedata import script as ft_script
22
+
23
+ _HAS_FONTTOOLS = True
24
+ except ImportError:
25
+ _HAS_FONTTOOLS = False
26
+
27
+
28
+ # ─── Unicode general category names ──────────────────────────────────────────
29
+
30
+ GENERAL_CATEGORIES: dict[str, str] = {
31
+ "Lu": "Uppercase Letter",
32
+ "Ll": "Lowercase Letter",
33
+ "Lt": "Titlecase Letter",
34
+ "Lm": "Modifier Letter",
35
+ "Lo": "Other Letter",
36
+ "Mn": "Nonspacing Mark",
37
+ "Mc": "Spacing Mark",
38
+ "Me": "Enclosing Mark",
39
+ "Nd": "Decimal Number",
40
+ "Nl": "Letter Number",
41
+ "No": "Other Number",
42
+ "Pc": "Connector Punctuation",
43
+ "Pd": "Dash Punctuation",
44
+ "Ps": "Open Punctuation",
45
+ "Pe": "Close Punctuation",
46
+ "Pi": "Initial Punctuation",
47
+ "Pf": "Final Punctuation",
48
+ "Po": "Other Punctuation",
49
+ "Sm": "Math Symbol",
50
+ "Sc": "Currency Symbol",
51
+ "Sk": "Modifier Symbol",
52
+ "So": "Other Symbol",
53
+ "Zs": "Space Separator",
54
+ "Zl": "Line Separator",
55
+ "Zp": "Paragraph Separator",
56
+ "Cc": "Control",
57
+ "Cf": "Format",
58
+ }
59
+
60
+
61
+ # ─── HTML entity mappings ────────────────────────────────────────────────────
62
+
63
+ HTML_ENTITIES: dict[int, str] = {
64
+ 0x0026: "&amp;",
65
+ 0x003C: "&lt;",
66
+ 0x003E: "&gt;",
67
+ 0x0022: "&quot;",
68
+ 0x00A9: "&copy;",
69
+ 0x00AE: "&reg;",
70
+ 0x2122: "&trade;",
71
+ 0x00A3: "&pound;",
72
+ 0x00A5: "&yen;",
73
+ 0x20AC: "&euro;",
74
+ 0x00B0: "&deg;",
75
+ 0x00B1: "&plusmn;",
76
+ 0x00D7: "&times;",
77
+ 0x00F7: "&divide;",
78
+ 0x2190: "&larr;",
79
+ 0x2191: "&uarr;",
80
+ 0x2192: "&rarr;",
81
+ 0x2193: "&darr;",
82
+ 0x2194: "&harr;",
83
+ 0x21D0: "&lArr;",
84
+ 0x21D2: "&rArr;",
85
+ 0x21D4: "&hArr;",
86
+ 0x2200: "&forall;",
87
+ 0x2202: "&part;",
88
+ 0x2203: "&exist;",
89
+ 0x2205: "&empty;",
90
+ 0x2207: "&nabla;",
91
+ 0x2208: "&isin;",
92
+ 0x2209: "&notin;",
93
+ 0x220B: "&ni;",
94
+ 0x220F: "&prod;",
95
+ 0x2211: "&sum;",
96
+ 0x221A: "&radic;",
97
+ 0x221E: "&infin;",
98
+ 0x2227: "&and;",
99
+ 0x2228: "&or;",
100
+ 0x2229: "&cap;",
101
+ 0x222A: "&cup;",
102
+ 0x222B: "&int;",
103
+ 0x2260: "&ne;",
104
+ 0x2264: "&le;",
105
+ 0x2265: "&ge;",
106
+ 0x2282: "&sub;",
107
+ 0x2283: "&sup;",
108
+ 0x2286: "&sube;",
109
+ 0x2287: "&supe;",
110
+ 0x25CA: "&loz;",
111
+ 0x2660: "&spades;",
112
+ 0x2663: "&clubs;",
113
+ 0x2665: "&hearts;",
114
+ 0x2666: "&diams;",
115
+ }
116
+
117
+ # Reverse mapping: entity string → character
118
+ HTML_ENTITY_TO_CHAR: dict[str, str] = {v: chr(k) for k, v in HTML_ENTITIES.items()}
119
+
120
+
121
+ # ─── Data types ──────────────────────────────────────────────────────────────
122
+
123
+
124
+ class EncodingInfo(NamedTuple):
125
+ """11 encoding representations for a character."""
126
+
127
+ unicode: str
128
+ html_decimal: str
129
+ html_hex: str
130
+ html_entity: str
131
+ css: str
132
+ javascript: str
133
+ python: str
134
+ java: str
135
+ utf8_bytes: str
136
+ utf16_bytes: str
137
+ url_encoded: str
138
+
139
+
140
+ class SymbolInfo(NamedTuple):
141
+ """Full Unicode properties + encodings for a character."""
142
+
143
+ codepoint: int
144
+ character: str
145
+ name: str
146
+ category: str
147
+ category_name: str
148
+ block: str
149
+ script: str
150
+ bidirectional: str
151
+ combining: int
152
+ mirrored: bool
153
+ decomposition: str
154
+ encodings: EncodingInfo
155
+
156
+
157
+ # ─── Core functions ──────────────────────────────────────────────────────────
158
+
159
+
160
+ def get_encodings(char: str) -> EncodingInfo:
161
+ """Compute 11 encoding representations for a single character.
162
+
163
+ >>> enc = get_encodings("♠")
164
+ >>> enc.unicode
165
+ 'U+2660'
166
+ >>> enc.html_entity
167
+ '&spades;'
168
+ >>> enc.utf8_bytes
169
+ 'e2 99 a0'
170
+ """
171
+ cp = ord(char)
172
+ if cp <= 0xFFFF:
173
+ python_repr = f"\\u{cp:04x}"
174
+ java_repr = f"\\u{cp:04X}"
175
+ else:
176
+ python_repr = f"\\U{cp:08x}"
177
+ high = 0xD800 + ((cp - 0x10000) >> 10)
178
+ low = 0xDC00 + ((cp - 0x10000) & 0x3FF)
179
+ java_repr = f"\\u{high:04X}\\u{low:04X}"
180
+
181
+ return EncodingInfo(
182
+ unicode=f"U+{cp:04X}",
183
+ html_decimal=f"&#{cp};",
184
+ html_hex=f"&#x{cp:X};",
185
+ html_entity=HTML_ENTITIES.get(cp, ""),
186
+ css=f"\\{cp:04X}",
187
+ javascript=f"\\u{{{cp:X}}}",
188
+ python=python_repr,
189
+ java=java_repr,
190
+ utf8_bytes=char.encode("utf-8").hex(" "),
191
+ utf16_bytes=char.encode("utf-16-be").hex(" "),
192
+ url_encoded=quote(char),
193
+ )
194
+
195
+
196
+ def get_info(char: str) -> SymbolInfo | None:
197
+ """Get full Unicode properties and encodings for a character.
198
+
199
+ Returns ``None`` if the character has no Unicode name (control chars, etc.).
200
+
201
+ >>> info = get_info("→")
202
+ >>> info.name if info else None
203
+ 'RIGHTWARDS ARROW'
204
+ >>> info.block if info else None # requires fonttools
205
+ 'Arrows'
206
+ """
207
+ try:
208
+ cp = ord(char)
209
+ name = unicodedata.name(char, None)
210
+ if name is None:
211
+ return None
212
+ cat = unicodedata.category(char)
213
+
214
+ if _HAS_FONTTOOLS:
215
+ block = ft_block(cp)
216
+ script = ft_script(cp)
217
+ else:
218
+ block = ""
219
+ script = ""
220
+
221
+ return SymbolInfo(
222
+ codepoint=cp,
223
+ character=char,
224
+ name=name,
225
+ category=cat,
226
+ category_name=GENERAL_CATEGORIES.get(cat, cat),
227
+ block=block,
228
+ script=script,
229
+ bidirectional=unicodedata.bidirectional(char),
230
+ combining=unicodedata.combining(char),
231
+ mirrored=bool(unicodedata.mirrored(char)),
232
+ decomposition=unicodedata.decomposition(char),
233
+ encodings=get_encodings(char),
234
+ )
235
+ except (ValueError, OverflowError):
236
+ return None
237
+
238
+
239
+ def get_category_name(category_code: str) -> str:
240
+ """Get the full name for a Unicode general category code.
241
+
242
+ >>> get_category_name("Sm")
243
+ 'Math Symbol'
244
+ """
245
+ return GENERAL_CATEGORIES.get(category_code, category_code)
246
+
247
+
248
+ def lookup_html_entity(entity: str) -> str | None:
249
+ """Look up the character for an HTML entity string.
250
+
251
+ >>> lookup_html_entity("&amp;")
252
+ '&'
253
+ >>> lookup_html_entity("&hearts;")
254
+ '♥'
255
+ """
256
+ return HTML_ENTITY_TO_CHAR.get(entity)
File without changes