├── .gitignore ├── data └── blocks.marshal.gz ├── Gemfile ├── lib └── unicode │ ├── blocks │ ├── string_ext.rb │ ├── constants.rb │ └── index.rb │ └── blocks.rb ├── CHANGELOG.md ├── unicode-blocks.gemspec ├── MIT-LICENSE.txt ├── Rakefile ├── .github └── workflows │ └── test.yml ├── spec └── unicode_blocks_spec.rb ├── CODE_OF_CONDUCT.md └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | Gemfile.lock 2 | /pkg 3 | -------------------------------------------------------------------------------- /data/blocks.marshal.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/janlelis/unicode-blocks/main/data/blocks.marshal.gz -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gemspec 4 | 5 | gem 'minitest' 6 | gem 'rake' 7 | gem 'irb' unless RUBY_ENGINE == "jruby" 8 | -------------------------------------------------------------------------------- /lib/unicode/blocks/string_ext.rb: -------------------------------------------------------------------------------- 1 | require_relative "../blocks" 2 | 3 | class String 4 | # Optional string extension for your convenience 5 | def unicode_blocks 6 | Unicode::Blocks.of(self) 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /lib/unicode/blocks/constants.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | module Unicode 4 | module Blocks 5 | VERSION = "1.11.0" 6 | UNICODE_VERSION = "17.0.0" 7 | DATA_DIRECTORY = File.expand_path(File.dirname(__FILE__) + "/../../../data/").freeze 8 | INDEX_FILENAME = (DATA_DIRECTORY + "/blocks.marshal.gz").freeze 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /lib/unicode/blocks/index.rb: -------------------------------------------------------------------------------- 1 | require "zlib" 2 | require_relative "constants" 3 | 4 | module Unicode 5 | module Blocks 6 | File.open(INDEX_FILENAME, "rb") do |file| 7 | serialized_data = Zlib::GzipReader.new(file).read 8 | serialized_data.force_encoding Encoding::BINARY 9 | INDEX = Marshal.load(serialized_data) 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## CHANGELOG 2 | 3 | ### 1.11.0 4 | 5 | - Unicode 17.0 6 | - Raw block data is now found at INDEX[:BLOCKS] instead of just INDEX 7 | 8 | ### 1.10.0 9 | 10 | - Unicode 16.0 11 | 12 | ### 1.9.0 13 | 14 | - Unicode 15.1 15 | 16 | ### 1.8.0 17 | 18 | - Unicode 15.0 19 | 20 | ### 1.7.0 21 | 22 | - Unicode 14.0 23 | 24 | ### 1.6.0 25 | 26 | * Unicode 13.0 27 | 28 | ### 1.5.0 29 | 30 | * Unicode 12.1 31 | 32 | ### 1.4.0 33 | 34 | * Unicode 12 35 | 36 | ### 1.3.0 37 | 38 | * Unicode 11 39 | * Do not depend on rubygems (only use zlib stdlib for unzipping) 40 | 41 | ### 1.2.2 42 | 43 | * Explicitly load rubygems/util, fixes regression in 1.2.1 44 | 45 | ### 1.2.1 46 | 47 | * Use `Gem::Util` for `gunzip`, removes deprecation warning 48 | 49 | ### 1.2.0 50 | 51 | * Unicode 10.0 52 | 53 | ### 1.1.0 54 | 55 | * Support Unicode 9.0 56 | 57 | ### 1.0.0 58 | 59 | * Initial release 60 | 61 | -------------------------------------------------------------------------------- /lib/unicode/blocks.rb: -------------------------------------------------------------------------------- 1 | require_relative "blocks/constants" 2 | 3 | module Unicode 4 | module Blocks 5 | def self.blocks(string) 6 | res = [] 7 | string.each_char{ |char| 8 | block_name = block(char) 9 | res << block_name unless res.include?(block_name) 10 | } 11 | res.sort 12 | end 13 | class << self; alias of blocks; end 14 | 15 | def self.block(char) 16 | require_relative 'blocks/index' unless defined? ::Unicode::Blocks::INDEX 17 | codepoint = char.unpack("U")[0] or raise(ArgumentError, "Unicode::Blocks.block must be given a valid char") 18 | block_info = INDEX[:BLOCKS].bsearch{ |block_info| codepoint <= block_info[1] } 19 | codepoint >= block_info[0] ? block_info[2] : "No_Block" 20 | end 21 | 22 | def self.names 23 | require_relative 'blocks/index' unless defined? ::Unicode::Blocks::INDEX 24 | INDEX[:BLOCKS].map(&:last) 25 | end 26 | end 27 | end 28 | 29 | -------------------------------------------------------------------------------- /unicode-blocks.gemspec: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | 3 | require File.dirname(__FILE__) + "/lib/unicode/blocks/constants" 4 | 5 | Gem::Specification.new do |gem| 6 | gem.name = "unicode-blocks" 7 | gem.version = Unicode::Blocks::VERSION 8 | gem.summary = "Return Unicode blocks of a string." 9 | gem.description = "[Unicode #{Unicode::Blocks::UNICODE_VERSION}] Answers the question: Which Unicode block does a code point belong to?" 10 | gem.authors = ["Jan Lelis"] 11 | gem.email = ["hi@ruby.consulting"] 12 | gem.homepage = "https://github.com/janlelis/unicode-blocks" 13 | gem.license = "MIT" 14 | 15 | gem.files = Dir["{**/}{.*,*}"].select{ |path| File.file?(path) && path !~ /^pkg/ } 16 | gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) } 17 | gem.test_files = gem.files.grep(%r{^(test|spec|features)/}) 18 | gem.require_paths = ["lib"] 19 | gem.metadata = { "rubygems_mfa_required" => "true" } 20 | 21 | gem.required_ruby_version = ">= 2.0" 22 | end 23 | -------------------------------------------------------------------------------- /MIT-LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016-2025 Jan Lelis, https://janlelis.com 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # # # 2 | # Get gemspec info 3 | 4 | gemspec_file = Dir['*.gemspec'].first 5 | gemspec = eval File.read(gemspec_file), binding, gemspec_file 6 | info = "#{gemspec.name} | #{gemspec.version} | " \ 7 | "#{gemspec.runtime_dependencies.size} dependencies | " \ 8 | "#{gemspec.files.size} files" 9 | 10 | # # # 11 | # Gem build and install task 12 | 13 | desc info 14 | task :gem do 15 | puts info + "\n\n" 16 | print " "; sh "gem build #{gemspec_file}" 17 | FileUtils.mkdir_p 'pkg' 18 | FileUtils.mv "#{gemspec.name}-#{gemspec.version}.gem", 'pkg' 19 | puts; sh %{gem install --no-document pkg/#{gemspec.name}-#{gemspec.version}.gem} 20 | end 21 | 22 | # # # 23 | # Start an IRB session with the gem loaded 24 | 25 | desc "#{gemspec.name} | IRB" 26 | task :irb do 27 | sh "irb -I ./lib -r #{gemspec.name.gsub '-','/'}" 28 | end 29 | 30 | # # # 31 | # Run Specs 32 | 33 | desc "#{gemspec.name} | Spec" 34 | task :spec do 35 | if RbConfig::CONFIG['host_os'] =~ /mswin|mingw/ 36 | sh "for %f in (spec/\*.rb) do ruby spec/%f" 37 | else 38 | sh "for file in spec/*.rb; do ruby $file; done" 39 | end 40 | end 41 | task default: :spec 42 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | test: 7 | name: Ruby ${{ matrix.ruby }} (${{ matrix.os }}) 8 | if: "!contains(github.event.head_commit.message, '[skip ci]')" 9 | strategy: 10 | matrix: 11 | ruby: 12 | - '3.4' 13 | - '3.3' 14 | - '3.2' 15 | - '3.1' 16 | - '3.0' 17 | - jruby 18 | - truffleruby 19 | os: 20 | - ubuntu-latest 21 | - macos-latest 22 | runs-on: ${{matrix.os}} 23 | steps: 24 | - uses: actions/checkout@v2 25 | - name: Set up Ruby 26 | uses: ruby/setup-ruby@v1 27 | with: 28 | ruby-version: ${{matrix.ruby}} 29 | bundler-cache: true 30 | - name: Run tests 31 | run: bundle exec rake 32 | 33 | test-windows: 34 | name: Ruby ${{ matrix.ruby }} (windows-latest) 35 | if: "!contains(github.event.head_commit.message, '[skip ci]')" 36 | strategy: 37 | matrix: 38 | ruby: 39 | - '3.4' 40 | - '3.3' 41 | - '3.2' 42 | - '3.1' 43 | - '3.0' 44 | - jruby 45 | runs-on: windows-latest 46 | steps: 47 | - uses: actions/checkout@v2 48 | - name: Set up Ruby 49 | uses: ruby/setup-ruby@v1 50 | with: 51 | ruby-version: ${{matrix.ruby}} 52 | bundler-cache: true 53 | - name: Run tests 54 | run: bundle exec rake 55 | -------------------------------------------------------------------------------- /spec/unicode_blocks_spec.rb: -------------------------------------------------------------------------------- 1 | require_relative "../lib/unicode/blocks" 2 | require "minitest/autorun" 3 | 4 | describe Unicode::Blocks do 5 | describe ".blocks (alias .of)" do 6 | it "will always return an Array" do 7 | assert_equal [], Unicode::Blocks.of("") 8 | end 9 | 10 | it "will return all blocks that characters in the string belong to" do 11 | assert_equal ["Basic Latin", "Cyrillic"], Unicode::Blocks.of("СC") 12 | end 13 | 14 | it "will return all blocks in sorted order" do 15 | assert_equal ["Basic Latin", "Cyrillic"], Unicode::Blocks.of("СA") 16 | assert_equal ["Basic Latin", "Cyrillic"], Unicode::Blocks.of("AС") 17 | end 18 | 19 | it "will call .block for every character" do 20 | mocked_method = Minitest::Mock.new 21 | mocked_method.expect :call, "first block", ["С"] 22 | mocked_method.expect :call, "second block", ["A"] 23 | Unicode::Blocks.stub :block, mocked_method do 24 | Unicode::Blocks.of("СA") 25 | end 26 | mocked_method.verify 27 | end 28 | end 29 | 30 | describe ".block" do 31 | it "will return block for that character" do 32 | assert_equal "Specials", Unicode::Blocks.block("�") 33 | end 34 | 35 | it "will return No_Block for characters not in any block" do 36 | assert_equal "No_Block", Unicode::Blocks.block("\u{10c50}") 37 | end 38 | end 39 | 40 | describe ".names" do 41 | it "will return a list of all block names" do 42 | assert_kind_of Array, Unicode::Blocks.names 43 | assert_includes Unicode::Blocks.names, "Ancient Symbols" 44 | end 45 | end 46 | end 47 | 48 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, gender identity and expression, level of experience, 9 | nationality, personal appearance, race, religion, or sexual identity and 10 | orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at opensource@janlelis.com. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at [http://contributor-covenant.org/version/1/4][version] 72 | 73 | [homepage]: http://contributor-covenant.org 74 | [version]: http://contributor-covenant.org/version/1/4/ 75 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Unicode::Blocks [![[version]](https://badge.fury.io/rb/unicode-blocks.svg)](https://badge.fury.io/rb/unicode-blocks) [![[ci]](https://github.com/janlelis/unicode-blocks/workflows/Test/badge.svg)](https://github.com/janlelis/unicode-blocks/actions?query=workflow%3ATest) 2 | 3 | Each Unicode character belongs to a [block](https://en.wikipedia.org/wiki/Unicode_block). This gem returns the all blocks associated with the given string. 4 | 5 | Unicode version: **17.0.0** (September 2025) 6 | 7 | ## Gemfile 8 | 9 | ```ruby 10 | gem "unicode-blocks" 11 | ``` 12 | 13 | ## Usage 14 | 15 | ```ruby 16 | require "unicode/blocks" 17 | 18 | # All blocks of a string 19 | Unicode::Blocks.blocks("Abc") # => ["Basic Latin"] 20 | Unicode::Blocks.blocks("СC") # => ["Cyrillic", "Basic Latin"] 21 | Unicode::Blocks.blocks("⧉⪥⟤") # => ["Miscellaneous Mathematical Symbols-A", 22 | "Miscellaneous Mathematical Symbols-B", 23 | "Supplemental Mathematical Operators"] 24 | 25 | # Also aliased as .of 26 | Unicode::Blocks.of("🃉🂹") # => ["Playing Cards"] 27 | Unicode::Blocks.of("\u{10c50}") # => ["No_Block"] 28 | 29 | # Single character 30 | Unicode::Blocks.block("☼") # => "Miscellaneous Symbols" 31 | ``` 32 | 33 | The list of blocks is always sorted alphabetically. 34 | 35 | ## Hints 36 | 37 | ### Regex Matching 38 | 39 | If you have a string and want to match a substring/character from a specific Unicode block, you actually won't need this gem. Instead, you can use the [Regexp Unicode Property Syntax `\p{}`](https://ruby-doc.org/core/Regexp.html#class-Regexp-label-Character+Properties) with blocks by prefixing the block name with "In": 40 | 41 | ```ruby 42 | "⧉⪥⟤".scan(/\p{In Miscellaneous Mathematical Symbols-B}/) # => ["⧉"] 43 | ``` 44 | 45 | See [Idiosyncratic Ruby: Proper Unicoding](https://idiosyncratic-ruby.com/41-proper-unicoding.html) for more info. 46 | 47 | ### Block Names 48 | 49 | You can retrieve all block names (except for **No_Block**) like this: 50 | 51 | ```ruby 52 | require "unicode/blocks" 53 | puts Unicode::Blocks.names 54 | 55 | # # # Output # # # 56 | 57 | Basic Latin 58 | Latin-1 Supplement 59 | Latin Extended-A 60 | Latin Extended-B 61 | IPA Extensions 62 | Spacing Modifier Letters 63 | Combining Diacritical Marks 64 | Greek and Coptic 65 | Cyrillic 66 | Cyrillic Supplement 67 | Armenian 68 | Hebrew 69 | Arabic 70 | Syriac 71 | Arabic Supplement 72 | Thaana 73 | NKo 74 | Samaritan 75 | Mandaic 76 | Syriac Supplement 77 | Arabic Extended-B 78 | Arabic Extended-A 79 | Devanagari 80 | Bengali 81 | Gurmukhi 82 | Gujarati 83 | Oriya 84 | Tamil 85 | Telugu 86 | Kannada 87 | Malayalam 88 | Sinhala 89 | Thai 90 | Lao 91 | Tibetan 92 | Myanmar 93 | Georgian 94 | Hangul Jamo 95 | Ethiopic 96 | Ethiopic Supplement 97 | Cherokee 98 | Unified Canadian Aboriginal Syllabics 99 | Ogham 100 | Runic 101 | Tagalog 102 | Hanunoo 103 | Buhid 104 | Tagbanwa 105 | Khmer 106 | Mongolian 107 | Unified Canadian Aboriginal Syllabics Extended 108 | Limbu 109 | Tai Le 110 | New Tai Lue 111 | Khmer Symbols 112 | Buginese 113 | Tai Tham 114 | Combining Diacritical Marks Extended 115 | Balinese 116 | Sundanese 117 | Batak 118 | Lepcha 119 | Ol Chiki 120 | Cyrillic Extended-C 121 | Georgian Extended 122 | Sundanese Supplement 123 | Vedic Extensions 124 | Phonetic Extensions 125 | Phonetic Extensions Supplement 126 | Combining Diacritical Marks Supplement 127 | Latin Extended Additional 128 | Greek Extended 129 | General Punctuation 130 | Superscripts and Subscripts 131 | Currency Symbols 132 | Combining Diacritical Marks for Symbols 133 | Letterlike Symbols 134 | Number Forms 135 | Arrows 136 | Mathematical Operators 137 | Miscellaneous Technical 138 | Control Pictures 139 | Optical Character Recognition 140 | Enclosed Alphanumerics 141 | Box Drawing 142 | Block Elements 143 | Geometric Shapes 144 | Miscellaneous Symbols 145 | Dingbats 146 | Miscellaneous Mathematical Symbols-A 147 | Supplemental Arrows-A 148 | Braille Patterns 149 | Supplemental Arrows-B 150 | Miscellaneous Mathematical Symbols-B 151 | Supplemental Mathematical Operators 152 | Miscellaneous Symbols and Arrows 153 | Glagolitic 154 | Latin Extended-C 155 | Coptic 156 | Georgian Supplement 157 | Tifinagh 158 | Ethiopic Extended 159 | Cyrillic Extended-A 160 | Supplemental Punctuation 161 | CJK Radicals Supplement 162 | Kangxi Radicals 163 | Ideographic Description Characters 164 | CJK Symbols and Punctuation 165 | Hiragana 166 | Katakana 167 | Bopomofo 168 | Hangul Compatibility Jamo 169 | Kanbun 170 | Bopomofo Extended 171 | CJK Strokes 172 | Katakana Phonetic Extensions 173 | Enclosed CJK Letters and Months 174 | CJK Compatibility 175 | CJK Unified Ideographs Extension A 176 | Yijing Hexagram Symbols 177 | CJK Unified Ideographs 178 | Yi Syllables 179 | Yi Radicals 180 | Lisu 181 | Vai 182 | Cyrillic Extended-B 183 | Bamum 184 | Modifier Tone Letters 185 | Latin Extended-D 186 | Syloti Nagri 187 | Common Indic Number Forms 188 | Phags-pa 189 | Saurashtra 190 | Devanagari Extended 191 | Kayah Li 192 | Rejang 193 | Hangul Jamo Extended-A 194 | Javanese 195 | Myanmar Extended-B 196 | Cham 197 | Myanmar Extended-A 198 | Tai Viet 199 | Meetei Mayek Extensions 200 | Ethiopic Extended-A 201 | Latin Extended-E 202 | Cherokee Supplement 203 | Meetei Mayek 204 | Hangul Syllables 205 | Hangul Jamo Extended-B 206 | High Surrogates 207 | High Private Use Surrogates 208 | Low Surrogates 209 | Private Use Area 210 | CJK Compatibility Ideographs 211 | Alphabetic Presentation Forms 212 | Arabic Presentation Forms-A 213 | Variation Selectors 214 | Vertical Forms 215 | Combining Half Marks 216 | CJK Compatibility Forms 217 | Small Form Variants 218 | Arabic Presentation Forms-B 219 | Halfwidth and Fullwidth Forms 220 | Specials 221 | Linear B Syllabary 222 | Linear B Ideograms 223 | Aegean Numbers 224 | Ancient Greek Numbers 225 | Ancient Symbols 226 | Phaistos Disc 227 | Lycian 228 | Carian 229 | Coptic Epact Numbers 230 | Old Italic 231 | Gothic 232 | Old Permic 233 | Ugaritic 234 | Old Persian 235 | Deseret 236 | Shavian 237 | Osmanya 238 | Osage 239 | Elbasan 240 | Caucasian Albanian 241 | Vithkuqi 242 | Todhri 243 | Linear A 244 | Latin Extended-F 245 | Cypriot Syllabary 246 | Imperial Aramaic 247 | Palmyrene 248 | Nabataean 249 | Hatran 250 | Phoenician 251 | Lydian 252 | Sidetic 253 | Meroitic Hieroglyphs 254 | Meroitic Cursive 255 | Kharoshthi 256 | Old South Arabian 257 | Old North Arabian 258 | Manichaean 259 | Avestan 260 | Inscriptional Parthian 261 | Inscriptional Pahlavi 262 | Psalter Pahlavi 263 | Old Turkic 264 | Old Hungarian 265 | Hanifi Rohingya 266 | Garay 267 | Rumi Numeral Symbols 268 | Yezidi 269 | Arabic Extended-C 270 | Old Sogdian 271 | Sogdian 272 | Old Uyghur 273 | Chorasmian 274 | Elymaic 275 | Brahmi 276 | Kaithi 277 | Sora Sompeng 278 | Chakma 279 | Mahajani 280 | Sharada 281 | Sinhala Archaic Numbers 282 | Khojki 283 | Multani 284 | Khudawadi 285 | Grantha 286 | Tulu-Tigalari 287 | Newa 288 | Tirhuta 289 | Siddham 290 | Modi 291 | Mongolian Supplement 292 | Takri 293 | Myanmar Extended-C 294 | Ahom 295 | Dogra 296 | Warang Citi 297 | Dives Akuru 298 | Nandinagari 299 | Zanabazar Square 300 | Soyombo 301 | Unified Canadian Aboriginal Syllabics Extended-A 302 | Pau Cin Hau 303 | Devanagari Extended-A 304 | Sharada Supplement 305 | Sunuwar 306 | Bhaiksuki 307 | Marchen 308 | Masaram Gondi 309 | Gunjala Gondi 310 | Tolong Siki 311 | Makasar 312 | Kawi 313 | Lisu Supplement 314 | Tamil Supplement 315 | Cuneiform 316 | Cuneiform Numbers and Punctuation 317 | Early Dynastic Cuneiform 318 | Cypro-Minoan 319 | Egyptian Hieroglyphs 320 | Egyptian Hieroglyph Format Controls 321 | Egyptian Hieroglyphs Extended-A 322 | Anatolian Hieroglyphs 323 | Gurung Khema 324 | Bamum Supplement 325 | Mro 326 | Tangsa 327 | Bassa Vah 328 | Pahawh Hmong 329 | Kirat Rai 330 | Medefaidrin 331 | Beria Erfe 332 | Miao 333 | Ideographic Symbols and Punctuation 334 | Tangut 335 | Tangut Components 336 | Khitan Small Script 337 | Tangut Supplement 338 | Tangut Components Supplement 339 | Kana Extended-B 340 | Kana Supplement 341 | Kana Extended-A 342 | Small Kana Extension 343 | Nushu 344 | Duployan 345 | Shorthand Format Controls 346 | Symbols for Legacy Computing Supplement 347 | Miscellaneous Symbols Supplement 348 | Znamenny Musical Notation 349 | Byzantine Musical Symbols 350 | Musical Symbols 351 | Ancient Greek Musical Notation 352 | Kaktovik Numerals 353 | Mayan Numerals 354 | Tai Xuan Jing Symbols 355 | Counting Rod Numerals 356 | Mathematical Alphanumeric Symbols 357 | Sutton SignWriting 358 | Latin Extended-G 359 | Glagolitic Supplement 360 | Cyrillic Extended-D 361 | Nyiakeng Puachue Hmong 362 | Toto 363 | Wancho 364 | Nag Mundari 365 | Ol Onal 366 | Tai Yo 367 | Ethiopic Extended-B 368 | Mende Kikakui 369 | Adlam 370 | Indic Siyaq Numbers 371 | Ottoman Siyaq Numbers 372 | Arabic Mathematical Alphabetic Symbols 373 | Mahjong Tiles 374 | Domino Tiles 375 | Playing Cards 376 | Enclosed Alphanumeric Supplement 377 | Enclosed Ideographic Supplement 378 | Miscellaneous Symbols and Pictographs 379 | Emoticons 380 | Ornamental Dingbats 381 | Transport and Map Symbols 382 | Alchemical Symbols 383 | Geometric Shapes Extended 384 | Supplemental Arrows-C 385 | Supplemental Symbols and Pictographs 386 | Chess Symbols 387 | Symbols and Pictographs Extended-A 388 | Symbols for Legacy Computing 389 | CJK Unified Ideographs Extension B 390 | CJK Unified Ideographs Extension C 391 | CJK Unified Ideographs Extension D 392 | CJK Unified Ideographs Extension E 393 | CJK Unified Ideographs Extension F 394 | CJK Unified Ideographs Extension I 395 | CJK Compatibility Ideographs Supplement 396 | CJK Unified Ideographs Extension G 397 | CJK Unified Ideographs Extension H 398 | CJK Unified Ideographs Extension J 399 | Tags 400 | Variation Selectors Supplement 401 | Supplementary Private Use Area-A 402 | Supplementary Private Use Area-B 403 | ``` 404 | 405 | See [unicode-x](https://github.com/janlelis/unicode-x) for more Unicode related micro libraries and [unicode-block.js](https://www.npmjs.com/package/unicode-block) for a JavaScript version of this library. 406 | 407 | ## MIT License 408 | 409 | - Copyright (C) 2016-2025 Jan Lelis . Released under the MIT license. 410 | - Unicode data: https://www.unicode.org/copyright.html#Exhibit1 411 | --------------------------------------------------------------------------------