From 76debe0071fef6865bd0fb79199f53932bf063c0 Mon Sep 17 00:00:00 2001 From: Radu Date: Sat, 26 Aug 2023 17:29:35 -0400 Subject: Write a working version and include licences Support some symbols, arrows, bold, subscript and superscript. --- README.md | 45 + UnicodeData.txt | 34924 +++++++++++++++++++++++++++++++++++++++ bold.py | 82 + demo.html | 33 + init-unicode-maps.js | 3 + licenses/GPL-2.0 | 339 + licenses/UNICODE-3 | 39 + manifest.json | 21 + page.js | 186 + subscript.py | 47 + superscript.py | 93 + unicode-maps-to-bold.js | 1 + unicode-maps-to-subscript.js | 1 + unicode-maps-to-superscript.js | 1 + 14 files changed, 35815 insertions(+) create mode 100644 README.md create mode 100644 UnicodeData.txt create mode 100755 bold.py create mode 100644 demo.html create mode 100644 init-unicode-maps.js create mode 100644 licenses/GPL-2.0 create mode 100644 licenses/UNICODE-3 create mode 100644 manifest.json create mode 100644 page.js create mode 100755 subscript.py create mode 100755 superscript.py create mode 100644 unicode-maps-to-bold.js create mode 100644 unicode-maps-to-subscript.js create mode 100644 unicode-maps-to-superscript.js diff --git a/README.md b/README.md new file mode 100644 index 0000000..e586622 --- /dev/null +++ b/README.md @@ -0,0 +1,45 @@ + + +# TeX Type + +A browser extension that converts commands (some TeX) in textboxes to unicode as +one types. It is intended particularly for inserting simple mathematics in +chats without native support. Ignore the cheesy name. + +## 'Supported' Websites + +The extension should work with ``, ` + + + + + + + diff --git a/init-unicode-maps.js b/init-unicode-maps.js new file mode 100644 index 0000000..818d0c4 --- /dev/null +++ b/init-unicode-maps.js @@ -0,0 +1,3 @@ +// SPDX-License-Identifier: GPL-2.0-only + +window.unicodeMaps = {} diff --git a/licenses/GPL-2.0 b/licenses/GPL-2.0 new file mode 100644 index 0000000..d159169 --- /dev/null +++ b/licenses/GPL-2.0 @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/licenses/UNICODE-3 b/licenses/UNICODE-3 new file mode 100644 index 0000000..11f2842 --- /dev/null +++ b/licenses/UNICODE-3 @@ -0,0 +1,39 @@ +UNICODE LICENSE V3 + +COPYRIGHT AND PERMISSION NOTICE + +Copyright © 1991-2023 Unicode, Inc. + +NOTICE TO USER: Carefully read the following legal agreement. BY +DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING DATA FILES, AND/OR +SOFTWARE, YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE +TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE, DO NOT +DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWARE. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of data files and any associated documentation (the "Data Files") or +software and any associated documentation (the "Software") to deal in the +Data Files or Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, and/or sell +copies of the Data Files or Software, and to permit persons to whom the +Data Files or Software are furnished to do so, provided that either (a) +this copyright and permission notice appear with all copies of the Data +Files or Software, or (b) this copyright and permission notice appear in +associated Documentation. + +THE DATA FILES AND SOFTWARE ARE 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 OF +THIRD PARTY RIGHTS. + +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE +BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, +OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE DATA +FILES OR SOFTWARE. + +Except as contained in this notice, the name of a copyright holder shall +not be used in advertising or otherwise to promote the sale, use or other +dealings in these Data Files or Software without prior written +authorization of the copyright holder. diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..4dbdacb --- /dev/null +++ b/manifest.json @@ -0,0 +1,21 @@ +{ + "manifest_version": 3, + "name": "TeX Type", + "version": "0.1.0", + "description": "Converts commands (some TeX) in textboxes to unicode as one types.", + "content_scripts": [{ + "matches": ["*://*/*"], + "js": [ + "init-unicode-maps.js", + "unicode-maps-to-bold.js", + "unicode-maps-to-subscript.js", + "unicode-maps-to-superscript.js", + "page.js" + ] + }], + "browser_specific_settings": { + "gecko": { + "id": "tex-type@pml4t.net" + } + } +} diff --git a/page.js b/page.js new file mode 100644 index 0000000..cfc31c1 --- /dev/null +++ b/page.js @@ -0,0 +1,186 @@ +// SPDX-License-Identifier: GPL-2.0-only + +"use strict"; + +(() => { + console.log("TeX Type started."); + + function cmdToUnicode(name, args) { + if (name === "^") + return Array.from(args[0]).reduce( + (acc, c) => acc + (window.unicodeMaps.toSuperscript[c] ?? "^" + c), + "" + ); + if (name === "_") + return Array.from(args[0]).reduce( + (acc, c) => acc + (window.unicodeMaps.toSubscript[c] ?? "_" + c), + "" + ); + + let sym = { + "\\x": "×", + "\\times": "×", + "\\.": "⋅", + "\\cdot": "⋅", + "\\pm": "±", + "\\mp": "∓", + "\\in": "∈", + "\\/in": "∉", + "\\\\": "\u200b\\", + "\\{": "\u200b{", + "\\}": "\u200b}", + "\\^": "\u200b^", + "\\_": "\u200b_", + "<===": "⇐", + "==>": "⇒", + "<=>": "⇔", + "<==": "⟸", + "=>": "⟹", + "\\implies": "⟹", + "<>": "⟺", + "\\iff": "⟺", + "<=": "⩽", + "\\le": "⩽", + ">=": "⩾", + "\\ge": "⩾", + }[name]; + if (sym) return sym; + + if (["\\bf", "\\mathbf"].includes(name)) + return Array.from(args[0]).reduce( + (acc, chr) => acc + (window.unicodeMaps.toBold[chr] ?? chr), + "" + ); + + console.error("unreachable"); + } + + function getArgs(input, i, count) { + const args = []; + for (let argI = 0; argI < count; argI++) { + while (input.value[i] === " ") i++; + + if (!input.value[i]) break; + + if (input.value[i] === "\\") { + const start = i; + i = handleCmd(input, i); + if (failed) break; + args.push(input.value.slice(start, i)); + } else if (input.value[i] === "{") { + const argStart = ++i; + i = subCmds(input, i); + if (i === input.value.length) break; + const arg = input.value.slice(argStart, i++); + args.push(arg); + } else { + args.push(input.value[i++]); + } + } + return { args, argsEnd: i }; + } + + function trySubCmd(input, nameStart) { + let nameEnd; + if (input.value[nameStart] === "\\") { + const offset = input.value.slice(nameStart + 2).search(/\W/); + nameEnd = nameStart + 2 + (offset < 0 ? 0 : offset); + } else if ("^_".includes(input.value[nameStart])) nameEnd = nameStart + 1; + else if ( + "<>=".includes(input.value[nameStart]) && + ">=".includes(input.value[nameStart + 1]) + ) + if ("<>=".includes(input.value[nameStart + 2])) + if ("<>=".includes(input.value[nameStart + 3])) nameEnd = nameStart + 4; + else if (/\s/.test(input.value[nameStart + 3])) nameEnd = nameStart + 3; + else return { end: nameStart + 1, success: false }; + else if (/\s/.test(input.value[nameStart + 2])) nameEnd = nameStart + 2; + else return { end: nameStart + 1, success: false }; + else if (input.value[nameStart] === "\u200b") + return { end: nameStart + 2, success: true }; + else return { end: nameStart + 1, success: false }; + const name = input.value.slice(nameStart, nameEnd); + + const argsCount = { + "\\x": 0, + "\\times": 0, + "\\.": 0, + "\\cdot": 0, + "\\pm": 0, + "\\mp": 0, + "\\in": 0, + "\\/in": 0, + "\\\\": 0, + "\\{": 0, + "\\}": 0, + "\\^": 0, + "\\_": 0, + "<==": 0, + "=>": 0, + "<=>": 0, + "<===": 0, + "==>": 0, + "\\implies": 0, + "<>": 0, + "\\iff": 0, + "<=": 0, + "\\le": 0, + ">=": 0, + "\\ge": 0, + "\\bf": 1, + "\\mathbf": 1, + "^": 1, + _: 1, + }[name]; + if (argsCount == null) return { end: nameEnd, success: false }; + + const argsRet = getArgs(input, nameEnd, argsCount); + const args = argsRet.args; + const argsEnd = argsRet.argsEnd; + if (args.length < argsCount) return { end: argsEnd, success: false }; + + const unicode = cmdToUnicode(name, args); + input.value = + input.value.slice(0, nameStart) + unicode + input.value.slice(argsEnd); + + const caret = input.caret; + if (caret > nameStart) + input.caret = caret + nameStart - argsEnd + unicode.length; + + return { end: nameStart + unicode.length, success: true }; + } + + function subCmds(input, i) { + const starts = []; + const ends = []; + if (i == null) i = 0; + while (i < input.value.length) { + if (input.value[i] === "}") return i; + else i = trySubCmd(input, i).end; + } + return input.value.length; + } + + window.addEventListener("input", (event) => { + if (event.target.selectionStart != null) { + const input = { + value: event.target.value, + caret: event.target.selectionStart, + }; + subCmds(input); + event.target.value = input.value; + event.target.selectionStart = event.target.selectionEnd = input.caret; + } else if (event.target.contentEditable === "true") { + const textNode = window.getSelection().anchorNode; + const input = { + value: textNode.textContent, + caret: window.getSelection().getRangeAt(0).startOffset, + }; + subCmds(input); + textNode.textContent = input.value; + window + .getSelection() + .setBaseAndExtent(textNode, input.caret, textNode, input.caret); + } + }); +})(); diff --git a/subscript.py b/subscript.py new file mode 100755 index 0000000..1abd38f --- /dev/null +++ b/subscript.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0-only + +from sys import stderr + +with open("UnicodeData.txt") as f: + data = f.read() +data = data.split("\n") + +subscripts = {} + + +def line_to_char(line): + return chr(int(line.split(";", 1)[0], 16)) + + +for line in data: + if "SUBSCRIPT" in line: + normal_name = ''.join(line.split(";", 2)[1].split("SUBSCRIPT ", 1)) + if normal_name == "MINUS": + normal_name = "MINUS SIGN" + if normal_name == "ARABIC ALEF": + normal_name = "ARABIC LETTER ALEF" + normal_line = None + for line2 in data: + if ( + (";" + normal_name + ";" in line2 or ";DIGIT " + normal_name + ";" in line2) + and line != line2 + and "" not in line2 + ): + normal_line = line2 + break + if not normal_line: + print("not found:", line, file=stderr) + continue + char = line_to_char(line) + normal = line_to_char(normal_line) + if normal not in subscripts: + subscripts[normal] = char + +subscripts["-"] = subscripts["−"] +subscripts[" "] = " " + +import json + +print("window.unicodeMaps.toSubscript =", json.dumps(subscripts), ";") +print(subscripts, file=stderr) diff --git a/superscript.py b/superscript.py new file mode 100755 index 0000000..f755de0 --- /dev/null +++ b/superscript.py @@ -0,0 +1,93 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0-only + +# TODO: Approximate {sub,super}script using other characters? + +from sys import stderr + +with open("UnicodeData.txt") as f: + data = f.read() +data = data.split("\n") + +superscripts = {} + + +def line_to_char(line): + return chr(int(line.split(";", 1)[0], 16)) + + +for line in data: + if "SUPERSCRIPT" in line: + normal_name = line.split("SUPERSCRIPT ", 1)[1].split(";", 1)[0] + prefix = line.split(";", 1)[1].split("SUPERSCRIPT", 1)[0] + normal_line = None + for line2 in data: + if ( + normal_name in line2 + and prefix in line2 + and line != line2 + and "" not in line2 + ): + normal_line = line2 + break + if not normal_line: + print("not found:", line, file=stderr) + continue + char = line_to_char(line) + normal = line_to_char(normal_line) + if normal not in superscripts: + superscripts[normal] = char + elif "MODIFIER LETTER" in line: + name = line.split("MODIFIER LETTER ", 1)[1].split(";", 1)[0] + try_names = [name] + if "SMALL GREEK" in name: + try_names.append("GREEK SMALL LETTER" + name.split("SMALL GREEK", 1)[1]) + elif "SMALL CYRILLIC" in name: + try_names.append( + "CYRILLIC SMALL LETTER" + name.split("SMALL CYRILLIC", 1)[1] + ) + elif "CYRILLIC SMALL" in name: + try_names.append( + "CYRILLIC SMALL LETTER" + name.split("CYRILLIC SMALL", 1)[1] + ) + elif "SMALL CAPITAL" in name: + try_names.append( + "LATIN LETTER SMALL CAPITAL" + name.split("SMALL CAPITAL", 1)[1] + ) + elif "SMALL" in name: + s = name.split("SMALL", 1)[1] + if "LIGATURE OE" in name: + try_names.append("LATIN SMALL" + s) + else: + try_names.append("LATIN SMALL LETTER" + s) + elif "CAPITAL" in name: + s = name.split("CAPITAL", 1)[1] + if "BARRED B" in name: + try_names.append("LATIN LETTER SMALL CAPITAL" + s) + elif "REVERSED N" in name: + try_names.append("LATIN LETTER SMALL CAPITAL" + s) + else: + try_names.append("LATIN CAPITAL LETTER" + s) + normal_line = None + for line2 in data: + if ( + any(map(lambda x: ";" + x + ";" in line2, try_names)) + and line != line2 + and "" not in line2 + ): + normal_line = line2 + break + if not normal_line: + print("not found:", line, file=stderr) + continue + char = line_to_char(line) + normal = line_to_char(normal_line) + if normal not in superscripts: + superscripts[normal] = char + +superscripts[" "] = " " + +import json + +print("window.unicodeMaps.toSuperscript =", json.dumps(superscripts), ";") +print(superscripts, file=stderr) diff --git a/unicode-maps-to-bold.js b/unicode-maps-to-bold.js new file mode 100644 index 0000000..d277de3 --- /dev/null +++ b/unicode-maps-to-bold.js @@ -0,0 +1 @@ +window.unicodeMaps.toBold = {"A": "\ud835\udc00", "B": "\ud835\udc01", "C": "\ud835\udc02", "D": "\ud835\udc03", "E": "\ud835\udc04", "F": "\ud835\udc05", "G": "\ud835\udc06", "H": "\ud835\udc07", "I": "\ud835\udc08", "J": "\ud835\udc09", "K": "\ud835\udc0a", "L": "\ud835\udc0b", "M": "\ud835\udc0c", "N": "\ud835\udc0d", "O": "\ud835\udc0e", "P": "\ud835\udc0f", "Q": "\ud835\udc10", "R": "\ud835\udc11", "S": "\ud835\udc12", "T": "\ud835\udc13", "U": "\ud835\udc14", "V": "\ud835\udc15", "W": "\ud835\udc16", "X": "\ud835\udc17", "Y": "\ud835\udc18", "Z": "\ud835\udc19", "a": "\ud835\udc1a", "b": "\ud835\udc1b", "c": "\ud835\udc1c", "d": "\ud835\udc1d", "e": "\ud835\udc1e", "f": "\ud835\udc1f", "g": "\ud835\udc20", "h": "\ud835\udc21", "i": "\ud835\udc22", "j": "\ud835\udc23", "k": "\ud835\udc24", "l": "\ud835\udc25", "m": "\ud835\udc26", "n": "\ud835\udc27", "o": "\ud835\udc28", "p": "\ud835\udc29", "q": "\ud835\udc2a", "r": "\ud835\udc2b", "s": "\ud835\udc2c", "t": "\ud835\udc2d", "u": "\ud835\udc2e", "v": "\ud835\udc2f", "w": "\ud835\udc30", "x": "\ud835\udc31", "y": "\ud835\udc32", "z": "\ud835\udc33", "\ud835\ude08": "\ud835\udc68", "\ud835\ude09": "\ud835\udc69", "\ud835\ude0a": "\ud835\udc6a", "\ud835\ude0b": "\ud835\udc6b", "\ud835\ude0c": "\ud835\udc6c", "\ud835\ude0d": "\ud835\udc6d", "\ud835\ude0e": "\ud835\udc6e", "\ud835\ude0f": "\ud835\udc6f", "\ud835\ude10": "\ud835\udc70", "\ud835\ude11": "\ud835\udc71", "\ud835\ude12": "\ud835\udc72", "\ud835\ude13": "\ud835\udc73", "\ud835\ude14": "\ud835\udc74", "\ud835\ude15": "\ud835\udc75", "\ud835\ude16": "\ud835\udc76", "\ud835\ude17": "\ud835\udc77", "\ud835\ude18": "\ud835\udc78", "\ud835\ude19": "\ud835\udc79", "\ud835\ude1a": "\ud835\udc7a", "\ud835\ude1b": "\ud835\udc7b", "\ud835\ude1c": "\ud835\udc7c", "\ud835\ude1d": "\ud835\udc7d", "\ud835\ude1e": "\ud835\udc7e", "\ud835\ude1f": "\ud835\udc7f", "\ud835\ude20": "\ud835\udc80", "\ud835\ude21": "\ud835\udc81", "\ud835\ude22": "\ud835\udc82", "\ud835\ude23": "\ud835\udc83", "\ud835\ude24": "\ud835\udc84", "\ud835\ude25": "\ud835\udc85", "\ud835\ude26": "\ud835\udc86", "\ud835\ude27": "\ud835\udc87", "\ud835\ude28": "\ud835\udc88", "\ud835\ude29": "\ud835\udc89", "\ud835\ude2a": "\ud835\udc8a", "\ud835\ude2b": "\ud835\udc8b", "\ud835\ude2c": "\ud835\udc8c", "\ud835\ude2d": "\ud835\udc8d", "\ud835\ude2e": "\ud835\udc8e", "\ud835\ude2f": "\ud835\udc8f", "\ud835\ude30": "\ud835\udc90", "\ud835\ude31": "\ud835\udc91", "\ud835\ude32": "\ud835\udc92", "\ud835\ude33": "\ud835\udc93", "\ud835\ude34": "\ud835\udc94", "\ud835\ude35": "\ud835\udc95", "\ud835\ude36": "\ud835\udc96", "\ud835\ude37": "\ud835\udc97", "\ud835\ude38": "\ud835\udc98", "\ud835\ude39": "\ud835\udc99", "\ud835\ude3a": "\ud835\udc9a", "\ud835\ude3b": "\ud835\udc9b", "\ud835\udc9c": "\ud835\udcd0", "\u212c": "\ud835\udcd1", "\ud835\udc9e": "\ud835\udcd2", "\ud835\udc9f": "\ud835\udcd3", "\u2130": "\ud835\udcd4", "\u2131": "\ud835\udcd5", "\ud835\udca2": "\ud835\udcd6", "\u210b": "\ud835\udcd7", "\u2110": "\ud835\udcd8", "\ud835\udca5": "\ud835\udcd9", "\ud835\udca6": "\ud835\udcda", "\u2112": "\ud835\udcdb", "\u2133": "\ud835\udcdc", "\ud835\udca9": "\ud835\udcdd", "\ud835\udcaa": "\ud835\udcde", "\u2118": "\ud835\udcdf", "\ud835\udcac": "\ud835\udce0", "\u211b": "\ud835\udce1", "\ud835\udcae": "\ud835\udce2", "\ud835\udcaf": "\ud835\udce3", "\ud835\udcb0": "\ud835\udce4", "\ud835\udcb1": "\ud835\udce5", "\ud835\udcb2": "\ud835\udce6", "\ud835\udcb3": "\ud835\udce7", "\ud835\udcb4": "\ud835\udce8", "\ud835\udcb5": "\ud835\udce9", "\ud835\udcb6": "\ud835\udcea", "\ud835\udcb7": "\ud835\udceb", "\ud835\udcb8": "\ud835\udcec", "\ud835\udcb9": "\ud835\udced", "\u212f": "\ud835\udcee", "\ud835\udcbb": "\ud835\udcef", "\u210a": "\ud835\udcf0", "\ud835\udcbd": "\ud835\udcf1", "\ud835\udcbe": "\ud835\udcf2", "\ud835\udcbf": "\ud835\udcf3", "\ud835\udcc0": "\ud835\udcf4", "\u2113": "\ud835\udcf5", "\ud835\udcc2": "\ud835\udcf6", "\ud835\udcc3": "\ud835\udcf7", "\u2134": "\ud835\udcf8", "\ud835\udcc5": "\ud835\udcf9", "\ud835\udcc6": "\ud835\udcfa", "\ud835\udcc7": "\ud835\udcfb", "\ud835\udcc8": "\ud835\udcfc", "\ud835\udcc9": "\ud835\udcfd", "\ud835\udcca": "\ud835\udcfe", "\ud835\udccb": "\ud835\udcff", "\ud835\udccc": "\ud835\udd00", "\ud835\udccd": "\ud835\udd01", "\ud835\udcce": "\ud835\udd02", "\ud835\udccf": "\ud835\udd03", "\ud835\udd37": "\ud835\uddd4", "\u0391": "\ud835\udea8", "\u0392": "\ud835\udea9", "\u0393": "\ud835\udeaa", "\u0394": "\ud835\udeab", "\u0395": "\ud835\udeac", "\u0396": "\ud835\udead", "\u0397": "\ud835\udeae", "\u0398": "\ud835\udeaf", "\u0399": "\ud835\udeb0", "\u039a": "\ud835\udeb1", "\u039b": "\ud835\udeb2", "\u039c": "\ud835\udeb3", "\u039d": "\ud835\udeb4", "\u039e": "\ud835\udeb5", "\u039f": "\ud835\udeb6", "\u03a0": "\ud835\udeb7", "\u03a1": "\ud835\udeb8", "\u03f4": "\ud835\udeb9", "\u03a3": "\ud835\udeba", "\u03a4": "\ud835\udebb", "\u03a5": "\ud835\udebc", "\u03a6": "\ud835\udebd", "\u03a7": "\ud835\udebe", "\u03a8": "\ud835\udebf", "\u03a9": "\ud835\udec0", "\u2207": "\ud835\udec1", "\u03b1": "\ud835\udec2", "\u03b2": "\ud835\udec3", "\u03b3": "\ud835\udec4", "\u03b4": "\ud835\udec5", "\u03b5": "\ud835\udec6", "\u03b6": "\ud835\udec7", "\u03b7": "\ud835\udec8", "\u03b8": "\ud835\udec9", "\u03b9": "\ud835\udeca", "\u03ba": "\ud835\udecb", "\u03bb": "\ud835\udecc", "\u03bc": "\ud835\udecd", "\u03bd": "\ud835\udece", "\u03be": "\ud835\udecf", "\u03bf": "\ud835\uded0", "\u03c0": "\ud835\uded1", "\u03c1": "\ud835\uded2", "\u03c2": "\ud835\uded3", "\u03c3": "\ud835\uded4", "\u03c4": "\ud835\uded5", "\u03c5": "\ud835\uded6", "\u03c6": "\ud835\uded7", "\u03c7": "\ud835\uded8", "\u03c8": "\ud835\uded9", "\u03c9": "\ud835\udeda", "\u2202": "\ud835\udedb", "\u03f5": "\ud835\udedc", "\u03d1": "\ud835\udedd", "\u03f0": "\ud835\udede", "\u03d5": "\ud835\udedf", "\u03f1": "\ud835\udee0", "\u03d6": "\ud835\udee1", "\ud835\udee2": "\ud835\udf1c", "\ud835\udee3": "\ud835\udf1d", "\ud835\udee4": "\ud835\udf1e", "\ud835\udee5": "\ud835\udf1f", "\ud835\udee6": "\ud835\udf20", "\ud835\udee7": "\ud835\udf21", "\ud835\udee8": "\ud835\udf22", "\ud835\udee9": "\ud835\udf23", "\ud835\udeea": "\ud835\udf24", "\ud835\udeeb": "\ud835\udf25", "\ud835\udeec": "\ud835\udf26", "\ud835\udeed": "\ud835\udf27", "\ud835\udeee": "\ud835\udf28", "\ud835\udeef": "\ud835\udf29", "\ud835\udef0": "\ud835\udf2a", "\ud835\udef1": "\ud835\udf2b", "\ud835\udef2": "\ud835\udf2c", "\ud835\udef3": "\ud835\udf2d", "\ud835\udef4": "\ud835\udf2e", "\ud835\udef5": "\ud835\udf2f", "\ud835\udef6": "\ud835\udf30", "\ud835\udef7": "\ud835\udf31", "\ud835\udef8": "\ud835\udf32", "\ud835\udef9": "\ud835\udf33", "\ud835\udefa": "\ud835\udf34", "\ud835\udefb": "\ud835\udf35", "\ud835\udefc": "\ud835\udf36", "\ud835\udefd": "\ud835\udf37", "\ud835\udefe": "\ud835\udf38", "\ud835\udeff": "\ud835\udf39", "\ud835\udf00": "\ud835\udf3a", "\ud835\udf01": "\ud835\udf3b", "\ud835\udf02": "\ud835\udf3c", "\ud835\udf03": "\ud835\udf3d", "\ud835\udf04": "\ud835\udf3e", "\ud835\udf05": "\ud835\udf3f", "\ud835\udf06": "\ud835\udf40", "\ud835\udf07": "\ud835\udf41", "\ud835\udf08": "\ud835\udf42", "\ud835\udf09": "\ud835\udf43", "\ud835\udf0a": "\ud835\udf44", "\ud835\udf0b": "\ud835\udf45", "\ud835\udf0c": "\ud835\udf46", "\ud835\udf0d": "\ud835\udf47", "\ud835\udf0e": "\ud835\udf48", "\ud835\udf0f": "\ud835\udf49", "\ud835\udf10": "\ud835\udf4a", "\ud835\udf11": "\ud835\udf4b", "\ud835\udf12": "\ud835\udf4c", "\ud835\udf13": "\ud835\udf4d", "\ud835\udf14": "\ud835\udf4e", "\ud835\udf15": "\ud835\udf4f", "\ud835\udf16": "\ud835\udf50", "\ud835\udf17": "\ud835\udf51", "\ud835\udf18": "\ud835\udf52", "\ud835\udf19": "\ud835\udf53", "\ud835\udf1a": "\ud835\udf54", "\ud835\udf1b": "\ud835\udf55", "\u03dc": "\ud835\udfca", "\u03dd": "\ud835\udfcb", "0": "\ud835\udfce", "1": "\ud835\udfcf", "2": "\ud835\udfd0", "3": "\ud835\udfd1", "4": "\ud835\udfd2", "5": "\ud835\udfd3", "6": "\ud835\udfd4", "7": "\ud835\udfd5", "8": "\ud835\udfd6", "9": "\ud835\udfd7"} ; diff --git a/unicode-maps-to-subscript.js b/unicode-maps-to-subscript.js new file mode 100644 index 0000000..9b0c9f2 --- /dev/null +++ b/unicode-maps-to-subscript.js @@ -0,0 +1 @@ +window.unicodeMaps.toSubscript = {"\u0627": "\u0656", "i": "\u1d62", "r": "\u1d63", "u": "\u1d64", "v": "\u1d65", "\u03b2": "\u1d66", "\u03b3": "\u1d67", "\u03c1": "\u1d68", "\u03c6": "\u1d69", "\u03c7": "\u1d6a", "0": "\u2080", "1": "\u2081", "2": "\u2082", "3": "\u2083", "4": "\u2084", "5": "\u2085", "6": "\u2086", "7": "\u2087", "8": "\u2088", "9": "\u2089", "+": "\u208a", "\u2212": "\u208b", "=": "\u208c", "(": "\u208d", ")": "\u208e", "a": "\u2090", "e": "\u2091", "o": "\u2092", "x": "\u2093", "\u0259": "\u2094", "h": "\u2095", "k": "\u2096", "l": "\u2097", "m": "\u2098", "n": "\u2099", "p": "\u209a", "s": "\u209b", "t": "\u209c", "j": "\u2c7c", "\u0430": "\ud838\udc51", "\u0431": "\ud838\udc52", "\u0432": "\ud838\udc53", "\u0433": "\ud838\udc54", "\u0434": "\ud838\udc55", "\u0435": "\ud838\udc56", "\u0436": "\ud838\udc57", "\u0437": "\ud838\udc58", "\u0438": "\ud838\udc59", "\u043a": "\ud838\udc5a", "\u043b": "\ud838\udc5b", "\u043e": "\ud838\udc5c", "\u043f": "\ud838\udc5d", "\u0441": "\ud838\udc5e", "\u0443": "\ud838\udc5f", "\u0444": "\ud838\udc60", "\u0445": "\ud838\udc61", "\u0446": "\ud838\udc62", "\u0447": "\ud838\udc63", "\u0448": "\ud838\udc64", "\u044a": "\ud838\udc65", "\u044b": "\ud838\udc66", "\u0491": "\ud838\udc67", "\u0456": "\ud838\udc68", "\u0455": "\ud838\udc69", "\u045f": "\ud838\udc6a", "-": "\u208b", " ": " "} ; diff --git a/unicode-maps-to-superscript.js b/unicode-maps-to-superscript.js new file mode 100644 index 0000000..4b8fb7d --- /dev/null +++ b/unicode-maps-to-superscript.js @@ -0,0 +1 @@ +window.unicodeMaps.toSuperscript = {"2": "\u00b2", "3": "\u00b3", "1": "\u00b9", "h": "\u02b0", "\u0266": "\u02b1", "j": "\u02b2", "r": "\u02b3", "\u0279": "\u02b4", "\u027b": "\u02b5", "\u0281": "\u02b6", "w": "\u02b7", "y": "\u02b8", "\u2032": "\u02b9", "\u2033": "\u02ba", "\u2e32": "\u02bb", "'": "\u02bc", "\u2e41": "\u02bd", "\u2303": "\u02c4", "\u2304": "\u02c5", "^": "\u02c6", "|": "\u02c8", "\u00af": "\u02c9", "\u00b4": "\u02ca", "`": "\u02cb", "\u22a5": "\u02d4", "\u22a4": "\u02d5", "+": "\u02d6", "\u2212": "\u02d7", "\u0263": "\u02e0", "l": "\u02e1", "s": "\u02e2", "x": "\u02e3", "\u0622": "\u0670", "\u0710": "\u0711", "A": "\u1d2c", "\u00c6": "\u1d2d", "B": "\u1d2e", "\u1d03": "\u1d2f", "D": "\u1d30", "E": "\u1d31", "\u018e": "\u1d32", "G": "\u1d33", "H": "\u1d34", "I": "\u1d35", "J": "\u1d36", "K": "\u1d37", "L": "\u1d38", "M": "\u1d39", "N": "\u1d3a", "\u1d0e": "\u1d3b", "O": "\u1d3c", "\u0222": "\u1d3d", "P": "\u1d3e", "R": "\u1d3f", "T": "\u1d40", "U": "\u1d41", "W": "\u1d42", "a": "\u1d43", "\u0250": "\u1d44", "\u0251": "\u1d45", "\u1d02": "\u1d46", "b": "\u1d47", "d": "\u1d48", "e": "\u1d49", "\u0259": "\u1d4a", "\u025b": "\u1d4b", "\u1d08": "\u1d4c", "g": "\u1d4d", "\u1d09": "\u1d4e", "k": "\u1d4f", "m": "\u1d50", "\u014b": "\u1d51", "o": "\u1d52", "\u0254": "\u1d53", "\u1d16": "\u1d54", "\u1d17": "\u1d55", "p": "\u1d56", "t": "\u1d57", "u": "\u1d58", "\u1d1d": "\u1d59", "\u026f": "\u1d5a", "v": "\u1d5b", "\ua7b5": "\u1d5d", "\u03b3": "\u1d5e", "\u1e9f": "\u1d5f", "\u03c6": "\u1d60", "\uab53": "\u1d61", "\u0252": "\u1d9b", "c": "\u1d9c", "\u0255": "\u1d9d", "\u00f0": "\u1d9e", "\u025c": "\u1d9f", "f": "\u1da0", "\u025f": "\u1da1", "\u0261": "\u1da2", "\u0265": "\u1da3", "\u0268": "\u1da4", "\u0269": "\u1da5", "\u026a": "\u1da6", "\u029d": "\u1da8", "\u026d": "\u1da9", "\u1d85": "\u1daa", "\u029f": "\u1dab", "\u0271": "\u1dac", "\u0270": "\u1dad", "\u0272": "\u1dae", "\u0273": "\u1daf", "\u0274": "\u1db0", "\u0275": "\u1db1", "\u0278": "\u1db2", "\u0282": "\u1db3", "\u0283": "\u1db4", "\u01ab": "\u1db5", "\u0289": "\u1db6", "\u028a": "\u1db7", "\u1d1c": "\u1db8", "\u028b": "\u1db9", "\u028c": "\u1dba", "z": "\u1dbb", "\u0290": "\u1dbc", "\u0291": "\u1dbd", "\u0292": "\u1dbe", "0": "\u2070", "i": "\u2071", "4": "\u2074", "5": "\u2075", "6": "\u2076", "7": "\u2077", "8": "\u2078", "9": "\u2079", "-": "\u207b", "=": "\u207c", "(": "\u207d", ")": "\u207e", "n": "\u207f", "V": "\u2c7d", ":": "\ua789", "C": "\ua7f2", "F": "\ua7f3", "Q": "\ua7f4", "\u0126": "\ua7f8", "\u0153": "\ua7f9", "\ua727": "\uab5c", "\uab37": "\uab5d", "\u026b": "\uab5e", "\uab52": "\uab5f", "\u028d": "\uab69", "\u22a3": "\uab6a", "\u22a2": "\uab6b", "\u02d0": "\ud801\udf81", "\u02d1": "\ud801\udf82", "\u00e6": "\ud801\udf83", "\u0299": "\ud801\udf84", "\u0253": "\ud801\udf85", "\u02a3": "\ud801\udf87", "\uab66": "\ud801\udf88", "\u02a5": "\ud801\udf89", "\u02a4": "\ud801\udf8a", "\u0256": "\ud801\udf8b", "\u0257": "\ud801\udf8c", "\u1d91": "\ud801\udf8d", "\u0258": "\ud801\udf8e", "\u025e": "\ud801\udf8f", "\u02a9": "\ud801\udf90", "\u0264": "\ud801\udf91", "\u0262": "\ud801\udf92", "\u0260": "\ud801\udf93", "\u029b": "\ud801\udf94", "\u0127": "\ud801\udf95", "\u029c": "\ud801\udf96", "\u0267": "\ud801\udf97", "\u0284": "\ud801\udf98", "\u02aa": "\ud801\udf99", "\u02ab": "\ud801\udf9a", "\u026c": "\ud801\udf9b", "\ud837\udf04": "\ud801\udf9c", "\ua78e": "\ud801\udf9d", "\u026e": "\ud801\udf9e", "\ud837\udf05": "\ud801\udf9f", "\u028e": "\ud801\udfa0", "\ud837\udf06": "\ud801\udfa1", "\u00f8": "\ud801\udfa2", "\u0276": "\ud801\udfa3", "\u0277": "\ud801\udfa4", "q": "\ud801\udfa5", "\u027a": "\ud801\udfa6", "\ud837\udf08": "\ud801\udfa7", "\u027d": "\ud801\udfa8", "\u027e": "\ud801\udfa9", "\u0280": "\ud801\udfaa", "\u02a8": "\ud801\udfab", "\u02a6": "\ud801\udfac", "\uab67": "\ud801\udfad", "\u02a7": "\ud801\udfae", "\u0288": "\ud801\udfaf", "\u2c71": "\ud801\udfb0", "\u028f": "\ud801\udfb2", "\ud837\udf1e": "\ud801\udfba", "\u0430": "\ud838\udc30", "\u0431": "\ud838\udc31", "\u0432": "\ud838\udc32", "\u0433": "\ud838\udc33", "\u0434": "\ud838\udc34", "\u0435": "\ud838\udc35", "\u0436": "\ud838\udc36", "\u0437": "\ud838\udc37", "\u0438": "\ud838\udc38", "\u043a": "\ud838\udc39", "\u043b": "\ud838\udc3a", "\u043c": "\ud838\udc3b", "\u043e": "\ud838\udc3c", "\u043f": "\ud838\udc3d", "\u0440": "\ud838\udc3e", "\u0441": "\ud838\udc3f", "\u0442": "\ud838\udc40", "\u0443": "\ud838\udc41", "\u0444": "\ud838\udc42", "\u0445": "\ud838\udc43", "\u0446": "\ud838\udc44", "\u0447": "\ud838\udc45", "\u0448": "\ud838\udc46", "\u044b": "\ud838\udc47", "\u044d": "\ud838\udc48", "\u044e": "\ud838\udc49", "\ua689": "\ud838\udc4a", "\u04d9": "\ud838\udc4b", "\u0456": "\ud838\udc4c", "\u0458": "\ud838\udc4d", "\u04e9": "\ud838\udc4e", "\u04af": "\ud838\udc4f", "\u04cf": "\ud838\udc50", "\u04ab": "\ud838\udc6b", "\ua651": "\ud838\udc6c", "\u04b1": "\ud838\udc6d", " ": " "} ; -- cgit v1.2.3