The post LineServices appeared first on Math in Office.

]]>This post is an update of an earlier post that tells some of how LineServices came to be and developed over time. It all started in 1994 with one of Microsoft’s most talented engineers, Eliyezer Kohen, a Turkish computer scientist who obtained his PhD at the Technische Hochshule in Zürich with Nicolas Wirth (author of Pascal, among other things). Eliyezer had led the two-man teams (the other person was Dean Ballard) that developed the Microsoft TrueType rasterizer as well as the original OpenType specification. Peter Pathe was heading Word at the time and wanted to improve Word’s line layout. He figured that Eliyezer could get a team going to do this in time for Word 97.

Eliyezer was convinced he could factor out Word’s line layout, but because of Word’s mind-boggling backward compatibility requirements, he refused to agree to the Office 97 time frame. I was working on RichEdit 2.0 next door to Eliyezer back then and you should have heard the prolonged arguments between Eliyezer and Peter! In that time frame, Eliyezer had a native American working with him named Lennox Brassel. Then he hired his first St. Petersburg mathematician, Sergey Genkin. Sergey’s first job after arriving in the USA in 1990 was back East working on a TeX compatible system. The team developed LineServices 1.0, which shipped first with a little program call Greeting Cards.

Eliyezer needed more developer cycles, so he asked Sergey if knew any more smart software engineers back in St. Petersburg. Sure enough Igor Zverev could come and RichEdit was fortunate enough to have Igor’s services for a while in developing RichEdit 2.0. (RichEdit also had another St. Petersburg mathematician Andrei Burago for some of that time; more about Andrei in a bit…). Not long after, yet another St. Petersburg mathematician Victor Kozyrev joined the team.

LineServices 2.0 was developed and shipped with Word 2000, Internet Explorer 4.0, RichEdit 3.0, PowerPoint 2000, and Publisher 2000. In addition to Western text, LineServices supported several special layout objects: the reverse object for BiDi text, the ruby object for East Asian phonetic annotations, Tatenakayoko (Japanese for “horizontal in vertical”, but sounds better than HIV), and warichu (two lines in one). From my point of view ruby was just a fraction in disguise, so naturally I was very excited to see that LineServices could do such a beautiful job displaying ruby. The initial ruby handler was developed by Rick Sailor.

LineServices handles lots of tricky problems with text layout and calls the client back for all the information it needs. LineServices never makes any operating system calls directly and it can run on any operating system that has a C++ compiler. The team had the strange habit of seriously designing a product before ever writing one line of code. What’s even stranger is that when they finally wrote the code, it had very few bugs in it. My own approach is to design partially and then dive into writing code using the well-known physicist approach to evaluating things called successive approximations. I can’t figure out everything in advance, so I try something and then gradually improve on it. Those guys figured out most of the design without writing any code.

After Office 2000, Eliyezer & Co. embarked on Page/TableServices, which was natural. He had started with characters in implementing TrueType, then progressed to lines with LineServices, and so pages and table were the next items on the layout hierarchy. To pull that off he needed the help of another St. Petersburg mathematician, Anton Sukanov, who had been a whiz kid in Russia winning various computer-science puzzle competitions. So, the team developed PTS as it’s called and revised LineServices to work well with it.

About that time, I simply couldn’t stand not having some native math layout in our products, so in February 2001 I wrote a math handler for LineServices patterned after the ruby handler. While I was at it, I installed the ruby object in a recursive way, so that you could have ruby objects nested like continued fractions. This upset the authors of the HTML ruby specification, since they said ruby was not supposed to be nested. Nevertheless, the easiest way to display complex ruby is using one level of nesting. My simple math handler showed that LineServices could do mathematics, although my spacing was mediocre. More precisely, spacing was delegated to the user, who unfortunately seldom knows what correct math spacing is.

A valuable thing about my old LineServices math handler was that it convinced people that we had the infrastructure to layout math. Fortunately, I didn’t appreciate at the time how hard laying out TeX-quality math would prove to be. Else I might not have been able to persuade people to work on it. It seems that most things that are worthwhile are way harder than you think they’ll be when you start working on them.

Of course, Eliyezer didn’t need any convincing; he and his team had designed LineServices so that it could be used to layout math. They just didn’t tell anyone! So after Office 2003 shipped, Eliyezer convinced Bill Gates and Steven Sinofsky that we should handle math layout and he started studying mathematical typography in earnest. He got his hands on every math typography book he could find, but by far the most influential and useful was Donald Knuth’s *The TeXbook*. After a few months Eliyezer enlisted the help of Victor and Andrei to design a math handler. Andrei had been working in the Windows font group, a background that would prove to be incredibly helpful on the math project.

They’d often come into my office announcing they were planning to do this and that and I would sometimes protest that what they had in mind wasn’t workable from a client’s, e.g., RichEdit’s, point of view. So they’d revise the plan and eventually they had a math handler design that was compatible with my general approach and offered really high quality mathematical typography. While this was going on, I was developing the formula autobuildup input method (see OfficeMath UI) using my old math handler, since they didn’t have any code written.

Since TeX was so valuable in the design process, Eliyezer wanted to talk with Donald Knuth, who happened to be an old friend of Eliyezer’s PhD advisor, Nicolas Wirth. A visit was arranged in November 2003 and the four of us had the good fortune to spend an extraordinary afternoon with Knuth at his home on the Stanford University campus. Among many things, Donald showed us how he uses TeX to typeset his papers and books exactly the way he wants them to look. He applies special tweaks to achieve perfection, such as “smashing the descender” on one radicand to make a sum of square roots line up in a pleasing way and shimming characters to place them more beautifully in a formula. This interaction inspired us to think that we could automate some of Donald’s tweaks using what evolved into the OpenType math tables and associated code, such as “cut-ins” to kern superscripts and subscripts with their bases.

Eliyezer’s health gradually declined, and he decided to retire after the initial math-handler design. Sergey Genkin took over leadership of the math project. One day in the summer of 2004 they came into my office all excited and announced that they had been able to display the mathematical expression 𝑎 + 𝑏! It was a real achievement, since the spacing around the + was the desired 4/18^{th} em and a lot of code had checked out correctly. One of the things they soon discovered was that LineServices alone was not adequate to layout high quality mathematics: you need PTS too!

The problem is that on computer screens, unlike the printed page, the layout width varies substantially from one invocation to another. Hence you must be able to break equations to accommodate different window widths. TeX delegates most equation breaking to the user, but that’s not a good option for browsers, slide shows and other screen usages. Also, you need PTS to handle placement of equation numbers. Yet another brilliant St. Petersburg mathematician had joined the PTS team, namely Alexander Vaschillo. So, he and Anton implemented equation breaking and numbering.

At this point one can understand better how we came to use OMML (Office MathML) as a file format for mathematics rather than MathML. OMML is a close representation of the LineServices/PTS math objects. These math objects were created after extensive study of mathematical typography, rather than by study of MathML. It’s natural to have a file format that mirrors the internal format. In addition, we needed to be able to put any inline text and objects inside math zones. MathML cannot embed other XML namespaces except indirectly via parallel markup of some kind.

The post LineServices appeared first on Math in Office.

]]>The post Unicode Math Braille Sequences appeared first on Math in Office.

]]>Section 2.2 of Unicode Technical Report #25 discusses the math alphanumerics and why they’re important for math. OfficeMath uses math alphabetics for most variables and supports the math digit sets as well. Accordingly, we need mappings between Unicode and Nemeth braille math alphanumerics. No attempt is made to give UEB sequences for the Unicode math alphanumerics.

For the most part, the mappings are straightforward as illustrated in the table below. But due to its generative use of type-form and alphabetic indicators, Nemeth braille encodes some math alphabets not in Unicode, e.g., Greek Script and Russian Script. Meanwhile, Unicode has math double-struck and monospace English alphanumerics, which don’t exist in Nemeth braille. Unicode also has six alphabets that aren’t mentioned in the Nemeth specification but that can be defined unambiguously with Nemeth indicators, namely bold Fraktur (Nemeth calls Fraktur “German”), bold Script, and Sans Serif bold and/or italic. The table below includes unambiguous prefixes for these alphabets chosen such that the Nemeth bold indicator precedes the italic or script indicators, and the Sans Serif indicator precedes the bold indicator. These choices correspond to the orders in which the Unicode math alphabets are named. Changes in this ordering result in alternative prefixes that are also unambiguous, but it seems simpler for implementations and users to standardize on the Unicode name ordering. Note that for simplicity English letters in math expressions often aren’t preceded by the braille italic indicator even though they are understood to be math-italic characters. Both LaTeX and MathML also use this convention.

Letter/style |
Nemeth |
E.g. |
Unicode |
Nemeth |

English letter | ⠰ | A | U+0041 | ⠰⠠⠁ |

Fraktur letter | ⠸ | 𝔄 | U+1D504 | ⠸⠠⠁ |

Greek letter | ⠨ | Γ | U+0393 | ⠨⠠⠛ |

Greek letter alternatives | ⠨⠈ | 𝜀 | U+03B5 | ⠨⠈⠑ |

Russian letter | ⠈⠈ | Д | U+0414 | ⠈⠈⠠⠙ |

Hebrew letter | ⠠⠠ | ℵ | U+2135 | ⠠⠠⠁ |

Bold | ⠸ | 𝐀 | U+1D400 | ⠸⠰⠠⠁ |

Bold Fraktur | ⠸⠸ | 𝕬 | U+1D56C | ⠸⠸⠠⠁ |

Bold Italic | ⠸⠨ | 𝑨 | U+1D468 | ⠸⠨⠰⠠⠁ |

Bold Script | ⠸⠈ | 𝓐 | U+1D4D0 | ⠸⠈⠰⠠⠁ |

Italic | ⠨ | 𝐴 | U+1D434 | ⠨⠰⠠⠁ |

Italic Greek | ⠨⠨ | 𝛾 | U+1D6FE | ⠨⠨⠛ |

Script | ⠈ | 𝒜 | U+1D49C | ⠈⠰⠠⠁ |

Sans Serif | ⠠⠨ | 𝖠 | U+1D5A0 | ⠠⠨⠰⠠⠁ |

Sans Serif Bold | ⠠⠨⠸ | 𝗔 | U+1D5D4 | ⠠⠨⠸⠰⠠⠁ |

Sans Serif Bold Italic | ⠠⠨⠸⠨ | 𝘼 | U+1D63C | ⠠⠨⠸⠨⠰⠠⠁ |

Sans Serif Italic | ⠠⠨⠨ | 𝘈 | U+1D608 | ⠠⠨⠨⠰⠠⠁ |

Upper case | ⠠ | A | U+0041 | ⠠⠁ |

The Nemeth specification has Script Greek (in §22) as well as “alternative” Greek letters (in §23). Some of the latter may be referred to as “script”. Specifically, the Unicode math Greek italic letters 𝜃𝜙𝜖𝜌𝜋𝜅 have the alternative counterparts 𝜗𝜑𝜀𝜚𝜛𝜘, respectively. The symbol 𝜗 can be called “script theta”. Since Unicode doesn’t have a math script Greek alphabet, it makes sense to map Nemeth math script Greek letters to the alternative Greek letters, if they exist, on input and to use the Nemeth alternative notation on output. In addition, in Unicode the upper-case Θ has the alternative ϴ. In TeX and OfficeMath, the alternative letters are identified by control words with a “var” prefix, as in \varepsilon for 𝜀, while ϵ is given by \epsilon. Interestingly, modern Greek uses 𝜑 and 𝜀 instead of 𝜙 and 𝜖, but math notation considers the script versions to be the alternatives. The table below lists the Greek symbols explicitly.

Nemeth braille has several Russian alphabets (see §22 of the Nemeth spec). These alphabets map to characters in the Cyrillic range U+0410..U+044F. Unicode has no math Russian alphabets, but italic and bold Russian alphabets can be emulated using the appropriate Cyrillic characters along with the desired italic and bold formatting. The Unicode Technical Committee, which is responsible for the Unicode Standard, has not received any proposals for adding Russian math alphabets. At least in my experience, technical papers in Russian use English and Greek letters in math zones. In Russian technical documents, this has the nice advantage of easily distinguishing mathematical variables from normal text. Accordingly the OfficeMath math braille facility uses the Russian letter notation for Unicode math double-struck letters.

Unicode has four predefined Hebrew characters in the Letterlike Symbols range U+2135..U+2138: ℵ, ℶ, ℷ, ℸ, respectively. In math contexts, it makes sense to map those Hebrew letters in Nemeth braille to the Letterlike Symbols and to map the other Nemeth Hebrew letters to characters in the Unicode Hebrew range U+05D0..U+05EA. The Unicode Technical Committee has not received any proposals for adding more Hebrew math letters so they probably won’t appear in math zones, except, perhaps, as embedded normal text.

Most Unicode math digits can be represented by the appropriate type-form indicator sequences in the table above followed by the numeric indicator ⠼ (if necessary) and the corresponding ASCII digits. For example, a math bold 2 (𝟐—U+1D7D0) can be represented by ⠸⠼⠆or “_#2”. This works for the bold and/or sans-serif digits, but not for the double-struck and monospace digits, which have no Nemeth counterparts. Meanwhile Nemeth notation supports italic and bold italic digits, which aren’t in Unicode.

Digits in most math contexts don’t need a numeric indicator in Nemeth notation, e.g., most digits in fractions, subscripts, or superscripts. To optimize common numeric subscript expressions like a_{1}, the numeric indicator *and* the subscript indicator are omitted. In Nemeth ASCII braille, a_{1} is “A1” and in Nemeth braille it’s ⠁⠂. The ASCII braille representation is tantalizing since variables like A1, B2, etc., are used to index spreadsheets and it would be more natural if spreadsheet indices were a_{1}, b_{2}, etc., at least for people with a mathematical background.

Code |
Char |
Unicode Name |
Nemeth |
UEB |

0021 | ! | Exclamation mark | ⠸⠖ | ⠖ |

0021 | ! | Factorial | ⠯ | ⠖ |

0022 | “ | Quotation mark | ⠠⠶ | |

0023 | # | Number sign | ⠨⠼ | ⠸⠹ |

0024 | $ | Dollar sign | ⠈⠎ | ⠈⠎ |

0025 | % | Percent sign | ⠈⠴ | ⠨⠴ |

0026 | & | Ampersand | ⠸⠯ | ⠈⠯ |

0027 | ‘ | Apostrophe | ⠄ | ⠄ |

0028 | ( | Left parenthesis | ⠷ | ⠐⠣ |

0029 | ) | Right parenthesis | ⠾ | ⠐⠜ |

002A | * | Asterisk | ⠈⠼ | ⠐⠔ |

002B | + | Plus sign | ⠬ | ⠐⠖ |

002C | , | Comma | ⠠ | ⠂ |

002D | – | Hyphen | ⠸⠤ | ⠤ |

002E | . | Full stop | ⠸⠲ | ⠼⠲ |

002F | / | Solidus | ⠸⠌ | ⠸⠌ |

003A | : | Colon | ⠸⠒ | ⠒ |

003B | ; | Semicolon | ⠸⠆ | ⠆ |

003C | < | Less-than sign | ⠀⠐⠅⠀ | ⠈⠣ |

003D | = | Equals sign | ⠀⠨⠅⠀ | ⠐⠶ |

003E | > | Greater-than sign | ⠀⠨⠂⠀ | ⠈⠜ |

003F | ? | Question mark | ⠸⠦ | ⠦ |

0040 | @ | Commercial at | ⠈⠁ | ⠈⠁ |

005B | [ | Left square bracket | ⠈⠷ | ⠨⠣ |

005C | \ | Reverse solidus | ⠸⠡ | ⠸⠡ |

005D | ] | Right square bracket | ⠈⠾ | ⠨⠜ |

005E | ^ | Circumflex accent | ⠸⠣ | ⠈⠢ |

005F | _ | Low line | ⠨⠤ | |

007B | { | Left curly bracket | ⠨⠷ | ⠸⠣ |

007C | | | Vertical line | ⠡ | ⠸⠳ |

007D | } | Right curly bracket | ⠨⠾ | ⠸⠜ |

007E | ~ | Tilde | ⠈⠱ | ⠈⠔ |

00A2 | ¢ | Cent sign | ⠈⠉ | ⠈⠉ |

00A3 | £ | Pound sterling | ⠈⠇ | ⠈⠇ |

00A7 | § | Section sign | ⠈⠠⠎ | ⠘⠎ |

00A9 | © | Copyright sign | ⠷⠠⠉⠾ | ⠘⠉ |

00AC | ¬ | Not sign | ⠈⠹ | |

00AE | ® | Registered sign | ⠷⠠r⠾ | ⠘⠗ |

00B0 | ° | Degree sign | ⠘⠨⠡ | ⠘⠚ |

00B1 | ± | Plus-minus sign | ⠬⠤ | ⠸⠖ |

00B6 | ¶ | Pilcrow sign | ⠈⠠⠏ | ⠘⠏ |

00B7 | · | Middle dot | ⠡ | |

00D7 | × | Multiplication sign | ⠈⠡ | ⠐⠦ |

00F7 | ÷ | Division sign | ⠨⠌ | ⠐⠌ |

0391 | Α | Greek capital letter alpha | ⠨⠠⠁ | ⠠⠨⠁ |

0392 | Β | Greek capital letter beta | ⠨⠠⠃ | ⠠⠨⠃ |

0393 | Γ | Greek capital letter gamma | ⠨⠠⠛ | ⠠⠨⠛ |

0394 | Δ | Greek capital letter delta | ⠨⠠⠙ | ⠠⠨⠙ |

0395 | Ε | Greek capital letter epsilon | ⠨⠠⠑ | ⠠⠨⠑ |

0396 | Ζ | Greek capital letter zeta | ⠨⠠⠵ | ⠠⠨⠵ |

0397 | Η | Greek capital letter eta | ⠨⠠⠱ | ⠠⠨⠱ |

0398 | Θ | Greek capital letter theta | ⠨⠠⠹ | ⠠⠨⠹ |

0399 | Ι | Greek capital letter iota | ⠨⠠⠊ | ⠠⠨⠊ |

039A | Κ | Greek capital letter kappa | ⠨⠠⠅ | ⠠⠨⠅ |

039B | Λ | Greek capital letter lambda | ⠨⠠⠇ | ⠠⠨⠇ |

039C | Μ | Greek capital letter mu | ⠨⠠⠍ | ⠠⠨⠍ |

039D | Ν | Greek capital letter nu | ⠨⠠⠝ | ⠠⠨⠝ |

039E | Ξ | Greek capital letter xi | ⠨⠠⠭ | ⠠⠨⠭ |

039F | Ο | Greek capital letter omicron | ⠨⠠⠕ | ⠠⠨⠕ |

03A0 | Π | Greek capital letter pi | ⠨⠠⠏ | ⠠⠨⠏ |

03A1 | Ρ | Greek capital letter rho | ⠨⠠⠗ | ⠠⠨⠗ |

03A3 | Σ | Greek capital letter sigma | ⠨⠠⠎ | ⠠⠨⠎ |

03A4 | Τ | Greek capital letter tau | ⠨⠠⠞ | ⠠⠨⠞ |

03A5 | Υ | Greek capital letter upsilon | ⠨⠠⠥ | ⠠⠨⠥ |

03A6 | Φ | Greek capital letter phi | ⠨⠠⠋ | ⠠⠨⠋ |

03A7 | Χ | Greek capital letter chi | ⠨⠠⠯ | ⠠⠨⠯ |

03A8 | Ψ | Greek capital letter psi | ⠨⠠⠽ | ⠠⠨⠽ |

03A9 | Ω | Greek capital letter omega | ⠨⠠⠺ | ⠠⠨⠺ |

03B1 | α | Greek small letter alpha | ⠨⠁ | ⠨⠁ |

03B2 | β | Greek small letter beta | ⠨⠃ | ⠨⠃ |

03B3 | γ | Greek small letter gamma | ⠨⠛ | ⠨⠛ |

03B4 | δ | Greek small letter delta | ⠨⠙ | ⠨⠙ |

03B5 | ε | Greek small letter epsilon
(alternative epsilon) |
⠨⠈⠑ | ⠨⠑ |

03B6 | ζ | Greek small letter zeta | ⠨⠵ | ⠨⠵ |

03B7 | η | Greek small letter eta | ⠨⠱ | ⠨⠱ |

03B8 | θ | Greek small letter theta | ⠨⠹ | ⠨⠹ |

03B9 | ι | Greek small letter iota | ⠨⠊ | ⠨⠊ |

03BA | κ | Greek small letter kappa | ⠨⠅ | ⠨⠅ |

03BB | λ | Greek small letter lambda | ⠨⠇ | ⠨⠇ |

03BC | μ | Greek small letter mu | ⠨⠍ | ⠨⠍ |

03BD | ν | Greek small letter nu | ⠨⠝ | ⠨⠝ |

03BE | ξ | Greek small letter xi | ⠨⠭ | ⠨⠭ |

03BF | ο | Greek small letter omicron | ⠨⠕ | ⠨⠕ |

03C0 | π | Greek small letter pi | ⠨⠏ | ⠨⠏ |

03C1 | ρ | Greek small letter rho | ⠨⠗ | ⠨⠗ |

03C2 | ς | Greek small letter final sigma | ⠨⠒ | ⠨⠎ |

03C3 | σ | Greek small letter sigma | ⠨⠎ | ⠨⠎ |

03C4 | τ | Greek small letter tau | ⠨⠞ | ⠨⠞ |

03C5 | υ | Greek small letter upsilon | ⠨⠥ | ⠨⠥ |

03C6 | φ | Greek small letter phi
(alternative phi) |
⠨⠈⠋ | ⠨⠋ |

03C7 | χ | Greek small letter chi | ⠨⠯ | ⠨⠯ |

03C8 | ψ | Greek small letter psi | ⠨⠽ | ⠨⠽ |

03C9 | ω | Greek small letter omega | ⠨⠺ | ⠨⠺ |

03D1 | ϑ | Greek theta symbol | ⠨⠈⠹ | |

03D5 | ϕ | Greek phi symbol | ⠨⠋ | |

03D6 | ϖ | Greek pi symbol | ⠨⠈⠏ | |

03F0 | ϰ | Greek kappa symbol | ⠨⠈⠅ | |

03F5 | ϵ | Greek lunate epsilon symbol | ⠨⠑ | |

2014 | — | Em dash | ⠤⠤ | ⠠⠤ |

2015 | ― | Horizontal bar | ⠤⠤⠤⠤ | ⠐⠠⠤ |

2018 | ‘ | Left single quotation mark | ⠠⠦ | ⠠⠦ |

2019 | ’ | Right single quotation mark | ⠴⠠ | ⠠⠴ |

201C | “ | Left double quotation mark | ⠦ | ⠘⠦ |

201D | ” | Right double quotation mark | ⠴ | ⠘⠴ |

2020 | † | Dagger | ⠸⠻ | ⠈⠠⠹ |

2021 | ‡ | Double dagger | ⠸⠸⠻ | ⠈⠠⠻ |

2022 | • | Bullet | ⠔⠔ | ⠸⠲ |

2026 | … | Ellipsis | ⠄⠄⠄ | |

2030 | ‰ | Per mille sign | ⠈⠴⠴ | |

2031 | ‱ | Per ten thousand sign | ⠈⠴⠴⠴ | |

2032 | ′ | Prime | ⠄ | ⠶ |

2033 | ″ | Double prime | ⠄⠄ | ⠶⠶ |

210F | ℏ | Planck constant over two pi | ⠈⠓ | |

2113 | ℓ | Script small l
(differs from 1d4c1: 4-56-123) |
⠈⠇ | |

211D | ℝ | Double-struck capital R
(no nemeth double struck) |
||

212B | Å | Angstrom sign | ⠈⠠⠁ | |

2146 | ⅆ | Double-struck italic small d | ||

2147 | ⅇ | Double-struck italic small e | ||

2190 | ← | Leftwards arrow | ⠀⠫⠪⠒⠒⠀ | ⠳⠪ |

2191 | ↑ | Upwards arrow | ⠀⠫⠣⠒⠒⠕⠀ | ⠳⠬ |

2192 | → | Rightwards arrow | ⠀⠫⠕⠀ | ⠳⠕ |

2192 | → | Rightwards arrow | ⠀⠫⠒⠒⠕⠀ | |

2193 | ↓ | Downwards arrow | ⠀⠫⠩⠒⠒⠕⠀ | ⠳⠩ |

2194 | Left right arrow | ⠀⠫⠪⠒⠒⠕⠀ | ⠰⠳⠺⠗⠕ | |

2195 | Up down arrow | ⠀⠫⠣⠪⠒⠒⠕⠀ | ||

2196 | North west arrow | ⠀⠫⠘⠪⠒⠒⠀ | ⠳⠱ | |

2197 | North east arrow | ⠀⠫⠘⠒⠒⠕⠀ | ⠳⠎ | |

2198 | South east arrow | ⠀⠫⠰⠒⠒⠕⠀ | ⠳⠣ | |

2199 | South west arrow | ⠀⠫⠰⠪⠒⠒⠀ | ⠳⠜ | |

219A | ↚ | Leftwards arrow w stroke | ⠀⠳⠈⠫⠪⠒⠒⠻⠀ | |

219B | ↛ | Rightwards arrow w stroke | ⠀⠳⠈⠫⠒⠒⠕⠻⠀ | |

219C | ↜ | Leftwards wave arrow | ⠀⠫⠪⠔⠒⠢⠀ | |

219D | ↝ | Rightwards wave arrow | ⠀⠫⠔⠒⠢⠕⠀ | |

219E | ↞ | Leftwards two headed arrow | ⠀⠫⠪⠪⠒⠒⠀ | |

219F | ↟ | Upwards two headed arrow | ⠀⠫⠣⠒⠒⠕⠕⠀ | |

21A0 | ↠ | Rightwards two headed arrow | ⠀⠫⠒⠒⠕⠕⠀ | |

21A1 | ↡ | Downwards two headed arrow | ⠀⠫⠩⠒⠒⠕⠕⠀ | |

21A2 | ↢ | Leftwards arrow w tail | ⠀⠫⠪⠒⠒⠠⠽⠀ | |

21A3 | ↣ | Rightwards arrow w tail | ⠀⠫⠠⠯⠒⠒⠕⠀ | |

21A4 | ↤ | Leftwards arrow from bar | ⠀⠫⠪⠒⠒⠳⠀ | |

21A5 | ↥ | Upwards arrow from bar | ⠀⠫⠣⠳⠒⠒⠕⠀ | |

21A6 | ↦ | Rightwards arrow from bar | ⠀⠫⠳⠒⠒⠕⠀ | |

21A7 | ↧ | Downwards arrow from bar | ⠀⠫⠩⠳⠒⠒⠕⠀ | |

21A8 | ↨ | Up down arrow w base | ⠀⠫⠣⠪⠒⠒⠕⠳⠀ | |

21A9 | Leftwards arrow w hook | ⠀⠫⠪⠒⠒⠈⠽⠀ | ||

21AA | Rightwards arrow w hook | ⠀⠫⠈⠯⠒⠒⠕⠀ | ||

21AB | ↫ | Leftwards arrow w loop | ||

21AC | ↬ | Rightwards arrow w loop | ||

21AD | ↭ | Left right wave arrow | ⠀⠫⠪⠔⠒⠢⠕⠀ | |

21AE | ↮ | Left right arrow w stroke | ⠀⠳⠈⠫⠪⠒⠒⠕⠻⠀ | |

21AF | ↯ | Downwards zigzag arrow | ⠀⠫⠩⠔⠢⠔⠕⠀ | |

21B4 | ↴ | Rightwards arrow w corner downwards | ⠀⠫⠩⠠⠳⠒⠕⠀ | |

21B5 | ↵ | Downwards arrow w corner leftwards | ⠀⠫⠪⠒⠈⠳⠀ | |

21B6 | ↶ | Anticlockwise top semicircle arrow | ||

21B7 | ↷ | Clockwise top semicircle arrow | ||

21BA | ↺ | Anticlockwise open circle arrow | ⠀⠫⠢⠔⠕⠀ | |

21BB | ↻ | Clockwise open circle arrow | ⠀⠫⠪⠢⠔⠀ | |

21BC | ↼ | Leftwards harpoon w barb upwards | ⠀⠫⠈⠪⠒⠒⠀ | |

21BD | ↽ | Leftwards harpoon w barb downwards | ⠀⠫⠠⠪⠒⠒⠀ | |

21BE | ↾ | Upwards harpoon w barb rightwards | ⠀⠫⠣⠒⠒⠠⠕⠀ | |

21BF | ↿ | Upwards harpoon w barb leftwards | ⠀⠫⠣⠒⠒⠈⠕⠀ | |

21C0 | ⇀ | Rightwards harpoon w barb upwards | ⠀⠫⠒⠒⠈⠕⠀ | |

21C1 | ⇁ | Rightwards harpoon w barb downwards | ⠀⠫⠒⠒⠠⠕⠀ | |

21C2 | ⇂ | Downwards harpoon w barb rightwards | ⠀⠫⠩⠒⠒⠈⠕⠀ | |

21C3 | ⇃ | Downwards harpoon w barb leftwards | ⠀⠫⠩⠒⠒⠠⠕⠀ | |

21C4 | ⇄ | Rightwards arrow over leftwards arrow | ⠀⠫⠒⠒⠕⠫⠪⠒⠒⠀ | |

21C5 | ⇅ | Upwards arrow leftwards
of downwards arrow |
⠀⠫⠣⠒⠒⠕⠐⠫⠩⠒⠒⠕⠀ | |

21C6 | ⇆ | Leftwards arrow over rightwards arrow | ⠀⠫⠪⠒⠒⠫⠒⠒⠕⠀ | |

21C7 | ⇇ | Leftwards paired arrows | ⠀⠫⠪⠒⠒⠫⠪⠒⠒⠀ | |

21C8 | ⇈ | Upwards paired arrows | ⠀⠫⠣⠒⠒⠕⠐⠫⠣⠒⠒⠕⠀ | |

21C9 | ⇉ | Rightwards paired arrows | ⠀⠫⠒⠒⠕⠫⠒⠒⠕⠀ | |

21CA | ⇊ | Downwards paired arrows | ⠀⠫⠩⠒⠒⠕⠐⠫⠩⠒⠒⠕⠀ | |

21CB | ⇋ | Leftwards harpoon over rightwards
harpoon |
⠀⠫⠈⠪⠒⠒⠫⠒⠒⠠⠕⠀ | |

21CC | ⇌ | Rightwards harpoon over leftwards
harpoon |
⠀⠫⠒⠒⠈⠕⠫⠠⠪⠒⠒⠀ | |

21CD | ⇍ | Leftwards double arrow w stroke | ⠀⠳⠈⠫⠪⠶⠶⠻⠀ | |

21CE | ⇎ | Left right double arrow w stroke | ⠀⠳⠈⠫⠪⠶⠶⠕⠻⠀ | |

21CF | ⇏ | Rightwards double arrow w stroke | ⠀⠳⠈⠫⠶⠶⠕⠻⠀ | |

21D0 | ⇐ | Leftwards double arrow | ⠀⠫⠪⠶⠶⠀ | ⠰⠳⠶⠶⠪ |

21D1 | ⇑ | Upwards double arrow | ⠀⠫⠣⠶⠶⠕⠀ | ⠰⠳⠶⠶⠬ |

21D2 | ⇒ | Rightwards double arrow | ⠀⠫⠶⠶⠕⠀ | ⠰⠳⠶⠶⠕ |

21D3 | ⇓ | Downwards double arrow | ⠀⠫⠩⠶⠶⠕⠀ | ⠰⠳⠶⠶⠩ |

21D4 | ⇔ | Left right double arrow | ⠀⠫⠪⠶⠶⠕⠀ | |

21D5 | ⇕ | Up down double arrow | ⠀⠫⠣⠪⠶⠶⠕⠀ | |

21D6 | ⇖ | North west double arrow | ⠀⠫⠘⠪⠶⠶⠀ | |

21D7 | ⇗ | North east double arrow | ⠀⠫⠘⠶⠶⠕⠀ | |

21D8 | ⇘ | South east double arrow | ⠀⠫⠰⠶⠶⠕⠀ | |

21D9 | ⇙ | South west double arrow | ⠀⠫⠰⠪⠶⠶⠀ | |

21DA | ⇚ | Leftwards triple arrow | ⠀⠫⠪⠸⠸⠀ | |

21DB | ⇛ | Rightwards triple arrow | ⠀⠫⠸⠸⠕⠀ | |

21DC | ⇜ | Leftwards squiggle arrow | ⠀⠫⠪⠢⠤⠔⠒⠢⠀ | |

21DD | ⇝ | Rightwards squiggle arrow | ⠀⠫⠢⠤⠔⠒⠢⠕⠀ | |

21DE | ⇞ | Upwards arrow w double stroke | ⠀⠳⠳⠈⠫⠣⠒⠒⠕⠻⠀ | |

21DF | ⇟ | Downwards arrow w double stroke | ⠀⠳⠳⠈⠫⠩⠒⠒⠕⠻⠀ | |

21E0 | ⇠ | Leftwards dashed arrow | ⠀⠫⠪⠒⠀⠒⠀ | |

21E1 | ⇡ | Upwards dashed arrow | ⠀⠫⠣⠒⠀⠒⠕⠀ | |

21E2 | ⇢ | Rightwards dashed arrow | ⠀⠫⠒⠀⠒⠕⠀ | |

21E3 | ⇣ | Downwards dashed arrow | ⠀⠫⠩⠒⠀⠒⠕⠀ | |

21E4 | ⇤ | Leftwards arrow to bar | ⠀⠳⠫⠪⠒⠒⠀ | |

21E5 | ⇥ | Rightwards arrow to bar | ⠀⠫⠒⠒⠕⠳⠀ | |

21E6 | ⇦ | Leftwards white arrow | ||

21E7 | ⇧ | Upwards white arrow | ||

21E8 | ⇨ | Rightwards white arrow | ||

21E9 | ⇩ | Downwards white arrow | ||

21F3 | ⇳ | Up down white arrow | ||

21F4 | ⇴ | Right arrow w small circle | ⠀⠨⠡⠈⠫⠒⠒⠕⠻⠀ | |

21F5 | ⇵ | Downwards arrow leftwards
of upwards arrow |
⠀⠫⠩⠒⠒⠕⠐⠫⠣⠒⠒⠕⠀ | |

21F6 | ⇶ | Three rightwards arrows | ⠀⠫⠒⠒⠕⠫⠒⠒⠕⠫⠒⠒⠕⠀ | |

21F7 | ⇷ | Leftwards arrow w vertical stroke | ⠀⠳⠈⠫⠪⠒⠒⠻⠀ | |

21F8 | ⇸ | Rightwards arrow w vertical stroke | ⠀⠳⠈⠫⠒⠒⠕⠻⠀ | |

21F9 | ⇹ | Left right arrow w vertical stroke | ⠀⠳⠈⠫⠪⠒⠒⠕⠻⠀ | |

21FA | ⇺ | Leftwards arrow w double vertical stroke | ⠀⠳⠳⠈⠫⠪⠒⠒⠻⠀ | |

21FB | ⇻ | Rightwards arrow w double vertical stroke | ⠀⠳⠳⠈⠫⠒⠒⠕⠻⠀ | |

21FC | ⇼ | Left right arrow w double vertical stroke | ⠀⠳⠳⠈⠫⠪⠒⠒⠕⠻⠀ | |

21FD | ⇽ | Leftwards open-headed arrow | ||

21FE | ⇾ | Rightwards open-headed arrow | ||

21FF | ⇿ | Left right open-headed arrow | ||

2200 | ∀ | For all | ⠈⠯ | ⠘⠁ |

2202 | ∂ | Partial differential | ⠈⠙ | ⠈⠙ |

2203 | ∃ | There exists | ⠈⠿ | ⠘⠢ |

2204 | ∄ | There does not exist | ⠌⠈⠿ | |

2205 | ∅ | Empty set | ⠸⠴ | ⠈⠚ |

2207 | ∇ | Nabla | ⠨⠫ | ⠘⠙ |

2208 | ∈ | Element of | ⠀⠈⠑⠀ | ⠘⠑ |

2209 | ∉ | Not an element of | ⠀⠌⠈⠑⠀ | |

220B | ∋ | Contains as member | ⠀⠈⠢⠀ | ⠈⠘⠑ |

220C | ∌ | Does not contain as member | ⠀⠌⠈⠢⠀ | |

220E | ∎ | End of proof | ⠸⠳ | |

2211 | ∑ | N-ary summation | ⠨⠠⠎ | |

2212 | − | Minus sign | ⠤ | ⠐⠤ |

2213 | ∓ | Minus-or-plus sign | ⠤⠬ | ⠸⠤ |

2214 | ∔ | Dot plus | ⠐⠬⠣⠡⠻ | |

2215 | ∕ | Division slash | ⠸⠌ | |

2217 | ∗ | Asterisk operator | ⠈⠼ | |

2218 | ∘ | Ring operator | ⠨⠡ | ⠐⠴ |

221A | √ | Square root | ⠜ | ⠐⠩ |

221B | ∛ | Cube root | ⠣⠒⠜ | |

221C | ∜ | Fourth root | ⠣⠲⠜ | |

221D | ∝ | Proportional to | ⠀⠸⠿⠀ | ⠸⠐⠶ |

221E | ∞ | Infinity | ⠠⠿ | ⠼⠿ |

221F | ∟ | Right angle | ⠫⠪⠨⠗⠻ | |

2220 | ∠ | Angle | ⠫⠪ | ⠸⠪ |

2221 | ∡ | Measured angle | ⠫⠪⠈⠫⠁⠻ | ⠨⠸⠪ |

2223 | ∣ | Divides | ⠀⠳⠀ | |

2224 | ∤ | Does not divide | ⠀⠌⠳⠀ | |

2225 | ∥ | Parallel to | ⠀⠫⠇⠀ | ⠼⠇ |

2226 | ∦ | Not parallel to | ⠀⠌⠫⠇⠀ | |

2227 | ∧ | Logical AND | ⠈⠩ | ⠈⠦ |

2228 | ∨ | Logical OR | ⠈⠬ | ⠈⠖ |

2229 | ∩ | Intersection | ⠨⠩ | ⠨⠦ |

222A | ∪ | Union | ⠨⠬ | ⠨⠖ |

222B | ∫ | Integral | ⠮ | ⠮ |

222C | ∬ | Double integral | ⠮⠮ | ⠮⠮ |

222D | ∭ | Triple integral | ⠮⠮⠮ | ⠮⠮⠮ |

222E | ∮ | Contour integral | ⠮⠈⠫⠉⠻ | ⠈⠮ |

2232 | ∲ | Clockwise contour integral ???
§156 has half arcs |
⠮⠈⠫⠪⠢⠔⠻ | |

2233 | ∳ | Anticlockwise contour integral ??? | ⠮⠈⠫⠢⠔⠕⠻ | |

2234 | ∴ | Therefore | ⠀⠠⠡⠀ | ⠠⠡ |

2235 | ∵ | Because | ⠀⠈⠌⠀ | ⠈⠌ |

2236 | ∶ | Ratio | ⠀⠐⠂⠀ | ⠒ |

2237 | ∷ | Proportion | ⠀⠰⠆⠀ | ⠒⠒ |

2238 | ∸ | Dot minus | ⠨⠤ | |

2239 | ∹ | Excess | ⠀⠤⠐⠂⠀ | |

223A | ∺ | Geometric proportion | ⠀⠐⠤⠩⠡⠡⠣⠡⠡⠻⠀ | |

223B | ∻ | Homothetic | ⠀⠐⠈⠱⠩⠡⠣⠡⠻⠀ | |

223C | ∼ | Tilde operator | ⠀⠈⠱⠀ | |

223D | ∽ | Reversed tilde | ⠀⠠⠱⠀ | |

2242 | ≂ | Minus tilde | ⠀⠱⠈⠱⠀ | |

2243 | ≃ | Asymptotically equal to | ⠀⠈⠱⠱⠀ | ⠸⠔ |

2245 | ≅ | Approximately equal to | ⠀⠈⠱⠨⠅⠀ | ⠐⠸⠔ |

2248 | ≈ | Almost equal to | ⠀⠈⠱⠈⠱⠀ | ⠘⠔ |

224A | ≊ | Almost equal or equal to | ⠀⠈⠱⠈⠱⠱⠀ | |

224B | ≋ | Triple tilde | ⠀⠈⠱⠈⠱⠈⠱⠀ | |

224C | ≌ | All equal to | ⠀⠠⠱⠨⠅⠀ | |

224D | ≍ | Equivalent to | ⠀⠫⠠⠫⠈⠀ | |

224E | ≎ | Geometrically equivalent to | ⠀⠈⠣⠠⠣⠀ | |

224F | ≏ | Difference between | ⠀⠈⠣⠱⠀ | ⠘⠐⠶ |

2250 | ≐ | Approaches the limit | ⠀⠐⠨⠅⠣⠡⠻⠀ | |

2251 | ≑ | Geometrically equal to | ⠀⠐⠨⠅⠩⠡⠣⠡⠻⠀ | ⠨⠐⠶ |

2254 | ≔ | Colon equals | ⠀⠐⠂⠨⠅⠀ | |

2255 | ≕ | Equals colon | ⠀⠨⠅⠐⠂⠀ | |

2256 | ≖ | Ring in equal to | ⠀⠨⠡⠈⠨⠅⠻⠀ | |

2257 | ≗ | Ring equal to | ⠀⠐⠨⠅⠣⠨⠡⠻⠀ | |

2258 | ≘ | Corresponds to | ⠀⠐⠨⠅⠣⠫⠁⠻⠀ | |

2259 | ≙ | Estimates | ⠀⠐⠨⠅⠣⠸⠣⠻⠀ | |

225A | ≚ | Equiangular to | ⠀⠐⠨⠅⠣⠸⠩⠻⠀ | |

225B | ≛ | Star equals | ⠀⠐⠨⠅⠣⠫⠎⠻⠀ | |

225C | ≜ | Delta equal to | ⠀⠐⠨⠅⠣⠫⠞⠻⠀ | |

225D | ≝ | Equal to by definition | ⠀⠐⠨⠅⠣⠙⠑⠋⠻⠀ | |

225E | ≞ | Measured by | ⠀⠐⠨⠅⠣⠍⠻⠀ | |

225F | ≟ | Questioned equal to | ⠀⠐⠨⠅⠣⠸⠢⠻⠀ | |

2260 | ≠ | Not equal to | ⠀⠌⠨⠅⠀ | ⠐⠶⠈⠱ |

2261 | ≡ | Identical to | ⠀⠸⠇⠀ | ⠸⠿ |

2262 | ≢ | Not identical to | ⠀⠌⠸⠇⠀ | |

2264 | ≤ | Less-than or equal to | ⠀⠐⠅⠱⠀ | ⠸⠈⠣ |

2265 | ≥ | Greater-than or equal to | ⠀⠨⠂⠱⠀ | ⠸⠈⠜ |

2266 | ≦ | Less-than over equal to | ⠀⠐⠅⠨⠅⠀ | |

2267 | ≧ | Greater-than over equal to | ⠀⠨⠂⠨⠅⠀ | |

2268 | ≨ | Less-than but not equal to | ⠀⠐⠅⠌⠨⠅⠀ | |

2269 | ≩ | Greater-than but not equal to | ⠀⠨⠂⠌⠨⠅⠀ | |

226A | ≪ | Much less-than | ⠀⠐⠅⠈⠐⠅⠻⠀ | ⠨⠈⠣ |

226B | ≫ | Much greater-than | ⠀⠨⠂⠈⠨⠂⠻⠀ | ⠨⠈⠜ |

226D | ≭ | Not equivalent to | ⠀⠌⠈⠣⠠⠣⠀ | |

226E | ≮ | Not less-than | ⠀⠌⠐⠅⠀ | |

226F | ≯ | Not greater-than | ⠀⠌⠨⠂⠀ | |

2270 | ≰ | Neither less-than nor equal to | ⠀⠌⠐⠅⠱⠀ | |

2271 | ≱ | Neither greater-than nor equal to | ⠀⠌⠨⠂⠱⠀ | |

2272 | ≲ | Less-than or equivalent to | ⠀⠐⠅⠈⠱⠀ | |

2273 | ≳ | Greater-than or equivalent to | ⠀⠨⠂⠈⠱⠀ | |

2274 | ≴ | Neither less-than nor equivalent to | ⠀⠌⠐⠅⠈⠱⠀ | |

2275 | ≵ | Neither greater-than nor equivalent to | ⠀⠌⠨⠂⠈⠱⠀ | |

2276 | ≶ | Less-than or greater-than | ⠀⠐⠅⠨⠂⠀ | |

2277 | ≷ | Greater-than or less-than | ⠀⠨⠂⠐⠅⠀ | |

2278 | ≸ | Neither less-than nor greater-than | ⠀⠌⠐⠅⠨⠂⠀ | |

2279 | ≹ | Neither greater-than nor less-than | ⠀⠌⠨⠂⠐⠅⠀ | |

227A | ≺ | Precedes | ⠀⠨⠐⠅⠀ | |

227B | ≻ | Succeeds | ⠀⠨⠨⠂⠀ | |

227E | ≾ | Precedes or equivalent to | ⠀⠨⠐⠅⠈⠱⠀ | |

227F | ≿ | Succeeds or equivalent to | ⠀⠨⠨⠂⠈⠱⠀ | |

2282 | ⊂ | Subset of | ⠀⠸⠐⠅⠀ | ⠘⠣ |

2283 | ⊃ | Superset of | ⠀⠸⠨⠂⠀ | ⠘⠜ |

2284 | ⊄ | Not a subset of | ⠀⠌⠸⠐⠅⠀ | |

2285 | ⊅ | Not a superset of | ⠀⠌⠸⠨⠂⠀ | |

2286 | ⊆ | Subset of or equal to | ⠀⠸⠐⠅⠱⠀ | ⠸⠘⠣ |

2287 | ⊇ | Superset of or equal to | ⠀⠸⠨⠂⠱⠀ | ⠸⠘⠜ |

2288 | ⊈ | Neither a subset of nor equal to | ⠀⠌⠸⠐⠅⠱⠀ | |

2289 | ⊉ | Neither a superset of nor equal to | ⠀⠌⠸⠨⠂⠱⠀ | |

228A | ⊊ | Subset of w not equal to | ⠀⠸⠐⠅⠌⠱⠀ | ⠨⠘⠣ |

228B | ⊋ | Superset of w not equal to | ⠀⠸⠨⠂⠌⠱⠀ | ⠨⠘⠜ |

228C | ⊌ | Multiset | ⠨⠬⠈⠫⠪⠒⠻ | |

228D | ⊍ | Multiset multiplication | ⠡⠈⠨⠬⠻ | |

228E | ⊎ | Multiset union | ⠬⠈⠨⠬⠻ | |

2295 | ⊕ | Circled plus | ⠫⠉⠸⠫⠬⠻ | ⠰⠫⠿⠪⠐⠖⠱ |

2296 | ⊖ | Circled minus | ⠫⠉⠸⠫⠤⠻ | |

2297 | ⊗ | Circled times | ⠫⠉⠸⠫⠈⠡⠻ | |

2298 | ⊘ | Circled division slash | ⠫⠉⠸⠫⠸⠌⠻ | |

2299 | ⊙ | Circled dot operator | ⠫⠉⠸⠫⠡⠻ | |

229B | ⊛ | Circled asterisk operator | ⠫⠉⠸⠫⠈⠼⠻ | |

229C | ⊜ | Circled equals | ⠫⠉⠸⠫⠨⠅⠻ | |

229D | ⊝ | Circled dash | ⠫⠉⠸⠫⠤⠤⠻ | |

229E | ⊞ | Squared plus | ⠫⠲⠸⠫⠬⠻ | |

229F | ⊟ | Squared minus | ⠫⠲⠸⠫⠤⠻ | |

22A0 | ⊠ | Squared times | ⠫⠲⠸⠫⠈⠡⠻ | |

22A1 | ⊡ | Squared dot operator | ⠫⠲⠸⠫⠡⠻ | |

22A2 | ⊢ | Right tack | ⠀⠫⠳⠒⠀ | |

22A3 | ⊣ | Left tack | ⠀⠫⠒⠳⠀ | ⠈⠸⠒ |

22A4 | ⊤ | Down tack | ⠀⠫⠩⠳⠒⠀ | |

22A5 | ⊥ | Up tack (See also 27C2) | ⠀⠫⠏⠀ or ⠀⠫⠣⠳⠒⠀ | ⠼⠤ |

22A6 | ⊦ | Assertion | ⠸⠒ | |

22A8 | ⊨ | True | ⠘⠸⠒ | |

22B2 | ⊲ | Normal subgroup of | ⠈⠸⠣ | |

22B3 | ⊳ | Contains as normal subgroup | ⠈⠸⠜ | |

22B4 | ⊴ | Normal subgroup of or equal to | ⠸⠸⠣ | |

22B5 | ⊵ | Contains as normal subgroup or equal to | ⠸⠸⠜ | |

22B6 | ⊶ | Original of | ⠀⠫⠨⠡⠒⠡⠀ | |

22B7 | ⊷ | Image of | ⠀⠫⠡⠒⠨⠡⠀ | |

22B8 | ⊸ | Multimap | ⠀⠫⠒⠨⠡⠀ | |

22BE | ⊾ | Right angle w arc | ⠼⠸⠪ | |

22BF | ⊿ | Right triangle | ⠫⠞⠨⠗⠻ | |

22C5 | ⋅ | Dot operator | ⠡ | ⠐⠲ |

22C6 | ⋆ | Star operator | ⠫⠎ | |

22CD | ⋍ | Reversed tilde equals | ⠀⠠⠱⠱⠀ | |

22D6 | ⋖ | Less-than w dot | ⠀⠡⠈⠐⠅⠻⠀ | |

22D7 | ⋗ | Greater-than w dot | ⠀⠡⠈⠨⠂⠻⠀ | |

22D8 | ⋘ | Much less-than | ⠀⠐⠅⠈⠐⠅⠈⠐⠅⠻⠀ | |

22D9 | ⋙ | Much greater-than | ⠀⠨⠂⠈⠨⠂⠈⠨⠂⠻⠀ | |

22DC | ⋜ | Equal to or less-than | ⠀⠱⠐⠅⠀ | |

22DD | ⋝ | Equal to or greater-than | ⠀⠱⠨⠂⠀ | |

22EE | ⋮ | Vertical ellipsis | ⠀⠩⠒⠒⠒⠀ | |

22EF | ⋯ | Midline horizontal ellipsis | ⠀⠒⠒⠒ | |

22F0 | ⋰ | Up right diagonal ellipsis | ⠀⠘⠒⠒⠒⠀ | |

22F1 | ⋱ | Down right diagonal ellipsis | ⠀⠰⠒⠒⠒⠀ | |

22F2 | ⋲ | Element of w long horizontal stroke | ⠀⠱⠈⠈⠑⠻⠀ | |

22F5 | ⋵ | Element of w dot above | ⠀⠐⠈⠑⠣⠡⠻⠀ | |

22F6 | ⋶ | Element of w overbar | ⠀⠱⠈⠑⠀ | |

22FA | ⋺ | Contains w long horizontal stroke | ⠀⠱⠈⠈⠢⠻⠀ | |

22FD | ⋽ | Contains w overbar | ⠀⠱⠈⠢⠀ | |

2308 | ⌈ | Left ceiling | ⠈⠘⠷ | |

2309 | ⌉ | Right ceiling | ⠈⠘⠾ | |

230A | ⌊ | Left floor | ⠈⠰⠷ | |

230B | ⌋ | Right floor | ⠈⠰⠾ | |

2322 | ⌢ | Frown | ⠀⠫⠁⠀ | |

2323 | ⌣ | Smile | ⠀⠫⠄⠀ | |

25A0 | ■ | Filled square | ⠫⠸⠲ | |

25A1 | □ | Square | ⠫⠲ | |

25AC | ▬ | Filled rectangle | ⠫⠸⠗ | |

25AD | ▭ | Rectangle | ⠫⠗ | |

25B2 | ▲ | Black up-pointing triangle | ⠫⠸⠞ | |

25B3 | △ | White up-pointing triangle | ⠫⠞ | |

25BC | ▼ | Black down-pointing triangle | ⠸⠨⠫ | |

25CB | ○ | White circle | ⠫⠉ | ⠿ |

25CF | ● | Black circle | ⠫⠸⠉ | |

25EB | ◫ | White square w vertical bisecting line | ⠫⠲⠸⠫⠳⠻ | |

27C2 | ⊥ | Perpendicular | ⠀⠫⠏⠀ | |

27C3 | ⟃ | Open subset | ⠀⠨⠡⠈⠸⠐⠅⠻⠀ | |

27C4 | ⟄ | Open superset | ⠀⠨⠡⠈⠸⠨⠂⠻⠀ | |

27DC | ⟜ | Left multimap | ⠀⠫⠨⠡⠒⠒⠀ | |

27DD | ⟝ | Long right tack | ⠀⠫⠳⠒⠒⠀ | |

27DE | ⟞ | Long left tack | ⠀⠫⠒⠒⠳⠀ | |

27DF | ⟟ | Up tack w circle above | ⠫⠣⠳⠒⠒⠨⠡ | |

27E6 | ⟦ | Mathematical left white square bracket | ⠈⠸⠷ | |

27E7 | ⟧ | Mathematical right white square bracket | ⠈⠸⠾ | |

27E8 | ⟨ | Mathematical left angle bracket | ⠨⠨⠷ | |

27E9 | ⟩ | Mathematical right angle bracket | ⠨⠨⠾ | |

27F5 | ⟵ | Long leftwards arrow | ⠀⠫⠪⠒⠒⠒⠀ | |

27F6 | ⟶ | Long rightwards arrow | ⠀⠫⠒⠒⠒⠕⠀ | |

27F7 | ⟷ | Long left right arrow | ⠀⠫⠪⠒⠒⠒⠕⠀ | |

27F8 | ⟸ | Long leftwards arrow | ⠀⠫⠪⠶⠶⠶⠀ | |

27F9 | ⟹ | Long rightwards arrow | ⠀⠫⠶⠶⠶⠕⠀ | |

27FA | ⟺ | Long left right arrow | ⠀⠫⠪⠶⠶⠶⠕⠀ | |

27FB | ⟻ | Long leftwards arrow from bar | ⠀⠫⠪⠒⠒⠒⠳⠀ | |

27FC | ⟼ | Long rightwards arrow from bar | ⠀⠫⠳⠒⠒⠒⠕⠀ | |

27FD | ⟽ | Long leftwards double arrow from bar | ⠀⠫⠪⠶⠶⠶⠳⠀ | |

27FE | ⟾ | Long rightwards double arrow from bar | ⠀⠫⠳⠶⠶⠶⠕⠀ | |

27FF | ⟿ | Long rightwards squiggle arrow | ⠀⠫⠢⠤⠔⠒⠢⠤⠔⠒⠢⠕⠀ | |

2921 | ⤡ | North west and south east arrow | ⠀⠫⠘⠪⠒⠒⠕⠀ | |

2922 | ⤢ | North east and south west arrow | ⠀⠫⠰⠪⠒⠒⠕⠀ | |

2983 | ⦃ | Left white curly bracket | ⠨⠸⠷ | |

2984 | ⦄ | Right white curly bracket | ⠨⠸⠾ | |

2991 | ⦑ | Left angle bracket w dot | ⠡⠈⠨⠨⠷⠻ | |

2992 | ⦒ | Right angle bracket w dot | ⠡⠈⠨⠨⠾⠻ | |

29C4 | ⧄ | Square rising diagonal slash | ⠫⠲⠸⠫⠔⠻ | |

29C5 | ⧅ | Square falling diagonal slash | ⠫⠲⠸⠫⠢⠻ | |

29C6 | ⧆ | Squared asterisk | ⠫⠲⠸⠫⠈⠼⠻ | |

29CA | ⧊ | Triangle w dot above | ⠐⠫⠞⠣⠡⠻ | |

29CB | ⧋ | Triangle w underbar | ⠫⠞⠱ | |

29CC | ⧌ | s in triangle §114 | ⠫⠞⠎ | |

29E6 | ⧦ | Gleich stark | ⠫⠳⠶⠶⠳ | |

2A0C | ⨌ | Quadruple integral operator | ⠮⠮⠮⠮ | ⠮⠮⠮⠮ |

2A0D | ⨍ | Finite part integral | ⠮⠈⠱⠻ | |

2A0E | ⨎ | Integral w double stroke | ⠮⠈⠱⠱⠻ | |

2A16 | ⨖ | Quaternion integral operator | ⠮⠈⠫⠲⠻ | |

2A18 | ⨘ | Integral w times sign | ⠮⠈⠈⠡⠻ | |

2A19 | ⨙ | Integral w intersection | ⠮⠈⠨⠩⠻ | |

2A1A | ⨚ | Integral w union | ⠮⠈⠨⠬⠻ | |

2A1B | ⨛ | Integral w overbar (upper) | ⠣⠮ | |

2A1C | ⨜ | Integral w underbar (lower) | ⠩⠮ | |

2A22 | ⨢ | Plus sign w small circle above | ⠐⠬⠣⠨⠡⠻ | |

2A23 | ⨣ | Plus sign w circumflex accent above | ⠐⠬⠣⠸⠣⠻ | |

2A24 | ⨤ | Plus sign w tilde above | ⠐⠬⠣⠈⠱⠻ | |

2A25 | ⨥ | Plus sign w dot below | ⠐⠬⠩⠡⠻ | |

2A2A | ⨪ | Minus sign w dot below | ⠐⠱⠩⠡⠻ | |

2A30 | ⨰ | Multiplication sign w dot above | ⠐⠈⠡⠣⠡⠻ | |

2A31 | ⨱ | Multiplication sign w underbar | ⠈⠡⠱ | |

2A38 | ⨸ | Circled division sign | ⠫⠉⠸⠫⠨⠌⠻ | |

2A39 | ⨹ | Plus sign in triangle | ⠫⠞⠸⠫⠬⠻ | |

2A3A | ⨺ | Minus sign in triangle | ⠫⠞⠸⠫⠤⠻ | |

2A3B | ⨻ | Multiplication sign in triangle | ⠫⠞⠸⠫⠈⠡⠻ | |

2A40 | ⩀ | Intersection w dot | ⠡⠈⠨⠩⠻ | |

2A41 | ⩁ | Union w minus sign | ⠤⠈⠨⠬⠻ | |

2A42 | ⩂ | Union w overbar | ⠱⠨⠬ | |

2A43 | ⩃ | Intersection w overbar | ⠱⠨⠩ | |

2A51 | ⩑ | Logical AND w dot above | ⠐⠈⠩⠣⠡⠻ | |

2A52 | ⩒ | Logical OR w dot above | ⠐⠈⠬⠣⠡⠻ | |

2A5C | ⩜ | Logical AND with horizontal dash | ⠱⠈⠈⠩⠻ | |

2A5D | ⩝ | Logical OR with horizontal dash | ⠱⠈⠈⠬⠻ | |

2A5E | ⩞ | Logical AND w double overbar | ⠱⠱⠈⠩ | |

2A5F | ⩟ | Logical AND w underbar | ⠈⠩⠱ | |

2A60 | ⩠ | Logical AND w double underbar | ⠈⠩⠱⠱ | |

2A62 | ⩢ | Logical OR w double overbar | ⠱⠱⠈⠬ | |

2A63 | ⩣ | Logical OR w double underbar | ⠈⠬⠱⠱ | |

2A66 | ⩦ | Equals sign w dot below | ⠀⠐⠨⠅⠩⠡⠻⠀ | |

2A67 | ⩧ | Identical w dot above | ⠀⠐⠸⠇⠣⠡⠻⠀ | |

2A6A | ⩪ | Tilde operator w dot above | ⠀⠐⠈⠱⠣⠡⠻⠀ | |

2A6C | ⩬ | Similar minus similar | ⠀⠈⠱⠱⠈⠱⠀ | |

2A6D | ⩭ | Congruent w dot above | ⠀⠐⠈⠱⠨⠅⠣⠡⠻⠀ | |

2A6E | ⩮ | Equals w asterisk | ⠀⠐⠨⠅⠣⠈⠼⠻⠀ | |

2A6F | ⩯ | Almost equal to w circumflex | ⠀⠐⠈⠱⠈⠱⠣⠸⠣⠻⠀ | |

2A70 | ⩰ | Approximately equal or equal to | ⠀⠈⠱⠈⠱⠨⠅⠀ | |

2A71 | ⩱ | Equals sign above plus sign | ⠀⠨⠅⠬⠀ | |

2A72 | ⩲ | Plus sign above equals sign | ⠀⠬⠨⠅⠀ | |

2A73 | ⩳ | Equals sign above tilde operator | ⠀⠨⠅⠈⠱⠀ | |

2A74 | ⩴ | Double colon equal | ⠀⠐⠂⠐⠂⠨⠅⠀ | |

2A75 | ⩵ | Two consecutive equals signs | ⠀⠨⠅⠨⠅⠀ | |

2A76 | ⩶ | Three consecutive equals signs | ⠀⠨⠅⠨⠅⠨⠅⠀ | |

2A77 | ⩷ | Equals sign w two dots above and two dots below | ⠀⠐⠨⠅⠩⠡⠡⠣⠡⠡⠻⠀ | |

2A78 | ⩸ | Equivalent w four dots above | ⠀⠐⠸⠇⠣⠡⠡⠡⠡⠻⠀ | |

2A79 | ⩹ | Less than w circle inside | ⠀⠐⠅⠈⠨⠡⠻⠀ | |

2A7A | ⩺ | Greater than w circle inside | ⠀⠨⠂⠈⠨⠡⠻⠀ | |

2A7B | ⩻ | Less-than w question mark above | ⠀⠐⠐⠅⠣⠸⠦⠻⠀ | |

2A7C | ⩼ | Greater-than w question mark above | ⠀⠐⠨⠂⠣⠸⠦⠻⠀ | |

2A85 | ⪅ | Less-than or approximate | ⠀⠐⠅⠈⠱⠈⠱⠀ | |

2A86 | ⪆ | Greater-than or approximate | ⠀⠨⠂⠈⠱⠈⠱⠀ | |

2A8B | ⪋ | Less-than above double-line equal above greater-than | ⠀⠐⠅⠨⠅⠨⠂⠀ | |

2A8C | ⪌ | Greater-than above double-line equal above less-than | ⠀⠨⠂⠨⠅⠐⠅⠀ | |

2A8D | ⪍ | Less-than above similar or equal to | ⠀⠐⠅⠈⠱⠱⠀ | |

2A8E | ⪎ | Greater-than above similar or equal to | ⠀⠨⠂⠈⠱⠱⠀ | |

2A8F | ⪏ | Less-than above similar above greater-than | ⠀⠐⠅⠈⠱⠨⠂⠀ | |

2A90 | ⪐ | Greater-than above similar above less-than | ⠀⠨⠂⠈⠱⠐⠅⠀ | |

2A91 | ⪑ | Less-than above greater-than above double-line equal | ⠀⠐⠅⠨⠂⠨⠅⠀ | |

2A92 | ⪒ | Greater-than above less-than above double-line equal | ⠀⠨⠂⠐⠅⠨⠅⠀ | |

2A99 | ⪙ | Double-line equal to or less-than | ⠀⠨⠅⠐⠅⠀ | |

2A9A | ⪚ | Double-line equal to or greater-than | ⠀⠨⠅⠨⠂⠀ | |

2A9D | ⪝ | Similar or less-than | ⠀⠈⠱⠐⠅⠀ | |

2A9E | ⪞ | Similar or greater-than | ⠀⠈⠱⠨⠂⠀ | |

2A9F | ⪟ | Similar above less-than above equals sign | ⠀⠈⠱⠐⠅⠨⠅⠀ | |

2AA0 | ⪠ | Similar above greater-than above equals sign | ⠀⠈⠱⠨⠂⠨⠅⠀ | |

2AAE | ⪮ | Equals sign with bumpy above | ⠀⠈⠣⠨⠅⠀ | |

2AAF | ⪯ | Precedes above single-line equals sign | ⠀⠨⠐⠅⠱⠀ | |

2AB0 | ⪰ | Succeeds above single-line equals sign | ⠀⠨⠨⠂⠱⠀ | |

2AB1 | ⪱ | Precedes above single-line not equal to | ⠀⠨⠐⠅⠌⠱⠀ | |

2AB2 | ⪲ | Succeeds above single-line not equal to | ⠀⠨⠨⠂⠌⠱⠀ | |

2AB3 | ⪳ | Precedes above equals sign | ⠀⠨⠐⠅⠨⠅⠀ | |

2AB4 | ⪴ | Succeeds above equals sign | ⠀⠨⠨⠂⠨⠅⠀ | |

2AB5 | ⪵ | Precedes above not equal to | ⠀⠨⠐⠅⠌⠨⠅⠀ | |

2AB6 | ⪶ | Succeeds above not equal to | ⠀⠨⠨⠂⠌⠨⠅⠀ | |

2AB7 | ⪷ | Precedes above almost equals to | ⠀⠨⠐⠅⠈⠱⠈⠱⠀ | |

2AB8 | ⪸ | Succeeds above almost equals to | ⠀⠨⠨⠂⠈⠱⠈⠱⠀ | |

2AB9 | ⪹ | Precedes above not almost equals to | ⠀⠨⠐⠅⠌⠈⠱⠈⠱⠀ | |

2ABA | ⪺ | Succeeds above not almost equals to | ⠀⠨⠨⠂⠌⠈⠱⠈⠱⠀ | |

2ABB | ⪻ | Double precedes | ⠀⠨⠐⠅⠈⠨⠐⠅⠻⠀ | |

2ABC | ⪼ | Double succeeds | ⠀⠨⠨⠂⠈⠨⠨⠂⠻⠀ | |

2ABD | ⪽ | Subset w dot | ⠀⠡⠈⠸⠐⠅⠻⠀ | |

2ABE | ⪾ | Superset w dot | ⠀⠡⠈⠸⠨⠂⠻⠀ | |

2ABF | ⪿ | Subset with plus sign below | ⠀⠐⠸⠐⠅⠩⠬⠻⠀ | |

2AC0 | ⫀ | Superset with plus sign below | ⠀⠐⠸⠨⠂⠩⠬⠻⠀ | |

2AC1 | ⫁ | Subset with multiplication sign below | ⠀⠐⠸⠐⠅⠩⠈⠡⠻⠀ | |

2AC2 | ⫂ | Superset with multiplication sign below | ⠀⠐⠸⠨⠂⠩⠈⠡⠻⠀ | |

2AC5 | ⫅ | Subset of above equals sign | ⠀⠸⠐⠅⠨⠅⠀ | |

2AC6 | ⫆ | Superset of above equals sign | ⠀⠸⠨⠂⠨⠅⠀ | |

2AC7 | ⫇ | Subset of above tilde operator | ⠀⠸⠐⠅⠈⠱⠀ | |

2AC8 | ⫈ | Superset of above tilde operator | ⠀⠸⠨⠂⠈⠱⠀ | |

2AC9 | ⫉ | Subset of above almost equal to | ⠀⠸⠐⠅⠈⠱⠈⠱⠀ | |

2ACA | ⫊ | Superset of above almost equal to | ⠀⠸⠨⠂⠈⠱⠈⠱⠀ | |

2ACB | ⫋ | Subset of above not equals sign | ⠀⠸⠐⠅⠌⠨⠅⠀ | |

2ACC | ⫌ | Superset of above not equals sign | ⠀⠸⠨⠂⠌⠨⠅⠀ | |

2AD3 | ⫓ | Subset above superset | ⠀⠸⠐⠅⠸⠨⠂⠀ | |

2AD4 | ⫔ | Superset above subset | ⠀⠸⠨⠂⠸⠐⠅⠀ | |

2AD5 | ⫕ | Subset above subset | ⠀⠸⠐⠅⠸⠐⠅⠀ | |

2AD6 | ⫖ | Superset above superset | ⠀⠸⠨⠂⠸⠨⠂⠀ | |

2AD7 | ⫗ | Superset beside subset | ⠀⠸⠨⠂⠐⠸⠐⠅⠀ | |

2AEF | ⫯ | Vertical line w circle above | ⠀⠫⠩⠨⠡⠒⠒⠀ | |

2AF0 | ⫰ | Vertical line w circle below | ⠀⠫⠣⠨⠡⠒⠒⠀ | |

2AF1 | ⫱ | Down tack w circle below | ⠀⠫⠣⠨⠡⠒⠒⠳⠀ | |

2AF2 | ⫲ | Parallel w horizontal stroke | ⠀⠱⠈⠫⠇⠻⠀ | |

2AF3 | ⫳ | Parallel w tilde operator | ⠀⠈⠱⠈⠫⠇⠻⠀ | |

2AF4 | ⫴ | Triple vertical bar binary relation | ⠀⠳⠳⠳⠀ | |

2B1F | ⬟ | Black pentagon | ⠫⠸⠢ | |

2B20 | ⬠ | White pentagon | ⠫⠢ | |

2B21 | ⬡ | White hexagon | ⠫⠖ | |

2B22 | ⬢ | Black hexagon | ⠫⠸⠖ | |

2B2C | ⬬ | Black ellipse | ⠫⠸⠑ | |

2B2D | ⬭ | White ellipse | ⠫⠑ | |

2B30 | ⬰ | Left arrow w small circle | ⠀⠨⠡⠈⠫⠪⠒⠒⠻⠀ | |

2B31 | ⬱ | Three leftwards arrows | ⠀⠫⠪⠒⠒⠫⠪⠒⠒⠫⠪⠒⠒⠀ | |

2B32 | ⬲ | Left arrow w circled plus | ⠀⠫⠪⠒⠒⠈⠫⠉⠸⠫⠬⠻⠀ | |

2BC3 | ⯃ | Horizontal black octagon | ⠫⠸⠦ |

In general, Unicode’s math characters are simpler to work with than the braille sequences since they are assigned separate character codes instead of being composed as sequences of 64 braille codes. Unicode has about 2310 math characters (see Math property in DerivedCoreProperties.txt) and to distinguish all of those without indicators would require 12-dot braille! Such a system would be hard to learn. LaTeX describes characters using control words consisting of a backslash followed by combinations of the 64 ASCII letters. That approach has mnemonic value, but it’s not as concise as the Nemeth braille character code sequences. When you get a feel for the Nemeth approach, a character’s Nemeth sequence gives a good idea of what a character is even if you haven’t encountered it before. UnicodeMath and Nemeth braille are intended to be read by human beings, whereas LaTeX and MathML are intended to be read by computer programs, notwithstanding that some TeXies can read LaTeX fluently! Nemeth math alphabets not in Unicode probably don’t have to be considered unless they show up in published documents.

The post Unicode Math Braille Sequences appeared first on Math in Office.

]]>The post Cascadia Code Font appeared first on Math in Office.

]]>The Cascadia Code font is an open-source font developed to improve the readability of program text in plain-text editors such as in the Windows Terminal, Microsoft Visual Studio, and Visual Studio Code. A major restriction in these contexts is fixed-width character spacing. So, in displaying “<=” as ‘≤’, some extra leading and trailing space is added, and the glyph is widened. The font also works as designed in Notepad. It uses 104 ligatures as well as extendable glyph sequences to render character combinations such as shown in the table

characters |
display |
mechanism |

<= | ≤ | ligature |

>= | ≥ | ligature |

!= | ≠ | ligature |

==> | ⇒ | sequence |

<== | ⇐ | sequence |

===> | ⟹ | sequence |

<=== | ⟺ | sequence |

:= | ≔ | ligature |

When you concatenate many equal signs together, you see a continuous horizontal double bar, which is a great way to divide up sections of code. And you can insert ‘<’ and ‘>’ along the way to make super long arrows with or without tails.

Let’s examine how Cascadia Code displays “<=” as ‘≤’. Consider the string “a<b<=c=d”. It is rendered using the glyphs

a | < | b | ≤ | c | = | d | |

00e1 | 0809 | 00fc | 0a72 | 0c2d | 00fd | 0806 | 0103 |

Here the glyph 0a72 is named less_equal.liga and is the complete ≤ ligature. The glyph 0c2d is named LIG and has no ink. LIG is included to preserve the two-character advance width and the two-character count. Many other glyph pairs have LIG as the second “glyph”. The advance widths and left side bearings of the symbols are

glyph ID |
advance width |
left side bearing |
name |
comment |

0806 | 1200 | 100 | equal | |

0809 | 1200 | 96 | less | |

0a72 | 1200 | 506 | less_equal.liga | large left side bearing |

0c2d | 1200 | 0 | LIG | 0 left side bearing |

The sequence ==> is displayed as ⇒ by the glyph sequence 0a93 0a91 0a99, where 0a93 starts the horizontal double bar, 0a91 continues it and 0a93 finishes it with an arrowhead.

Cascadia Code PL includes italic, variable-font weights from 200 to 700, Hebrew, Arabic, braille cells, line drawing characters, and lots more cool transformations. If the font isn’t installed on your computer, you can download it from here. Happy programming!

The post Cascadia Code Font appeared first on Math in Office.

]]>The post RichEdit Font Binding appeared first on Math in Office.

]]>The first section describes RichEdit character repertoires. The second section explains how a character is assigned to a character repertoire. The third section describes how to find out what character repertoires are supported by a font. The fourth section shows how these two kinds of information can be combined to bind fonts to characters in a context-dependent way. The fifth section describes the alternative font binding technology (IProvideFontInfo) used by the XAML RichEditBox and TextBox controls as well as Office applications that run RichEdit in the D2D/DirectWrite mode.

RichEdit’s built-in font binding facility is an extension of the GDI CreateFont() functionality that ensures the created font matches a given charset. If the font named in the call supports the charset, then the font is used, but if not, GDI instantiates a font that does. Before Unicode became popular, charsets defined character encodings for character repertoires typically associated with language systems, like Western European languages and Japanese. As such they were used for two purposes: 1) to define the encodings, and 2) to define character repertoires supported by fonts. The GDI CreateFont charset functionality addresses the latter purpose. This facility, which is a kind of “font fallback”, is very handy, since it’s usually easy to choose the charsets for characters that have charsets. In contrast it’s harder to choose the correct languages for characters in general.

Charsets correspond to code pages. The Windows code pages are described here. For reference, the Windows charsets supported by RichEdit are

ANSI_CHARSET | EASTEUROPE_CHARSET | RUSSIAN_CHARSET |

GREEK_CHARSET | TURKISH_CHARSET | HEBREW_CHARSET |

ARABIC_CHARSET | BALTIC_CHARSET | VIETNAMESE_CHARSET |

DEFAULT_CHARSET | SYMBOL_CHARSET | THAI_CHARSET |

SHIFTJIS_CHARSET | GB2312_CHARSET | HANGUL_CHARSET |

CHINESEBIG5_CHARSET | PC437_CHARSET | OEM_CHARSET |

MAC_CHARSET |

When Windows 2000 added support for Indic and several other Southeast Asian scripts, the decision was made not to add charsets for new scripts since it was clear that Unicode was the best way to represent characters on computers. Unfortunately, that decision limited GDI’s convenient font “fallback” mechanism to character repertoires that have charsets. RichEdit needed to generalize this usage of charset. Accordingly, we defined the charrep, a character repertoire index. It usually corresponds to an ISO script, but there are charreps with no corresponding ISO script and vice versa. In addition to the charrep for each Windows charset, there are charreps for

Armenian | Syriac | Thaana | Devanagari | Bengali |

Gurmukhi | Gujarati | Oriya | Tamil | Telugu |

Kannada | Malayalam | Sinhala | Lao | Tibetan |

Myanmar | Georgian | Jamo | Ethiopic | Cherokee |

Aboriginal | Ogham | Runic | Khmer | Mongolian |

Braille | Yi | Math General | Math Alphanumeric | Limbu |

Taile | Newtailu | Sylotinagr | Kharoshthi | Kayahli |

Unicode symbol | Emoji | Glagolitic | Lisu | Vai |

N’Ko | Osmanya | Phagspa | Gothic | Deseret |

Tifinagh | Old italic | Old Turkic | Bopomofo | Cyrillic xb |

Javanese | Olchiki | Sorasompeng | Buginese | Coptic |

Meroitic | Enc. alpha-num | Brahmi | Carian | Cuneiform |

Cypriot | Egyp. hieroglyph | Aramaic | Pahlavi | Parthian |

Lycian | Lydian | Old Persian | Old Sarabian | Phoenician |

Shavian | Ugaritic | Adlam | Osage |

Most of these are described in The Unicode Standard. The charreps can be used for font binding and they are also used to improve performance by avoiding unnecessary text analysis. Ideally there would be charreps for all ISO scripts that Windows supports. The IProvideFontInfo font binding described in the last section of this post attempts to do just that.

RichEdit does a kind of binary range search to find out which charrep a character nominally belongs to. ASCII is treated specially, since almost all fonts support “low ASCII”, the “neutral” range U+0020..U+003F. High ASCII, the range U+0040..U+007F is supported by most fonts as well. The ANSI_CHARSET includes ASCII and the Western European ANSI set contained in Windows code page 1252. For the range U+00A0..U+00FF, there’s a charrep named “high Latin 1”.

East Asian (CJK—Chinese Japanese Korean) fonts all support ASCII, but typically don’t support high Latin 1, since at least some of those code positions are used for lead bytes of double-byte character sets or for kana characters. Chinese characters are used in Japanese, in both simplified and traditional Chinese, and in Korean. The CJK fonts often have a lot of Unicode symbol characters (not SYMBOL_CHARSET discussed shortly), so a CJK charrep may be returned for those. An exception occurs in math zones, where a math charrep is preferred.

The default charrep is assigned to the Unicode Private Use Area characters, U+E000..U+F8FF, since these characters have no standardized scripts. Special attention is given to SYMBOL_CHARSET fonts, which don’t use Unicode. But characters in the range U+F020..U+F0FF are assigned the SYMBOL_CHARSET charrep, since Microsoft TrueType SYMBOL_CHARSET fonts use those locations as aliases for U+0020..U+00FF. The charrep assignments are similar to some assignment models based on scripts. But note that natural language isn’t used. This is because in general it’s easier and more reliable to figure out a reasonable charrep for a character than a natural language for a character. A RichEdit client can find out what charrep is assigned to a range of text by calling ITextFont2::GetCharRep();

Windows GDI has a handy structure known as the FONTSIGNATURE, which has bits claiming support for various code pages and Unicode ranges. Some fonts don’t have reliable values, so buyers beware. Nevertheless, it’s fast and useful, so RichEdit uses it to fill in a bit mask for supported character repertoires and has some back-up code to handle errant fonts. Some fonts claim to support a given character repertoire, but only support it partially. For example Japanese fonts claim to support Greek and Cyrillic, but they only have glyphs for basic Greek and Cyrillic characters. RichEdit classifies other characters in these repertoires as “extended”, which means that they need “cmap” verification. The cmap is a TrueType font’s character-to-glyph map. If it returns 0 for a character, the character is missing and will display a missing-character glyph, usually an empty box. The cmap approach is valuable for other cases in which the FONTSIGNATURE may be inadequate. For example, a font may not claim to support Latin 1, but it nevertheless supports low and/or high ASCII. By checking the cmap for ‘0’ and ‘a’, respectively, one can find out the amount of ASCII support available. This approach can also be useful for finding out about new Unicode ranges not represented in the FONTSIGNATURE, e.g., emoji.

Given the information in the two preceding sections, we need to ensure appropriate fonts are bound to characters. Let’s start with the basic algorithm and then consider some of many fix-ups.

The simple algorithm is: assign a character flag (bit) to each character repertoire (charrep) and AND the resulting bit mask for a character against the bit mask for the current font. If a nonzero value results, the font claims to support the character’s charrep and the font can continue to be used. If the result is zero, font binding is needed.

To keep the current user font choices when font binding, RichEdit scans the text runs backward from the insertion point looking for a font that supports the desired charrep. If one is found, it is used unless it was introduced by font binding. Otherwise, the default font for the charrep is used. The RichEdit client can change the default font for a charrep by using the EM_SETCHARFORMAT message with the SCF_ASSOCIATEFONT flag and an LCID (locale ID) that corresponds to the desired charrep.

Special considerations apply to math zones and Chinese characters (among other scenarios). In math zones, a math font is used whenever it can handle the characters. This includes not only Unicode math symbols and math alphanumerics, but also Latin, Greek and Cyrillic text. Many Chinese characters are used in Japanese, but a Chinese font may not look pleasing to a Japanese person. In particular, the simplified Chinese fonts look quite different from the more traditional look of the same characters rendered with a Japanese font. So to bind appropriately, we scan forward and backward around an inserted Chinese character to see if any Hiragana or Katakana characters are present. If so, it’s most likely to be Japanese text and a Japanese font should be used. Similarly, if Hangul characters are found, a Korean font should be used. Other heuristics involve noting what the user locale is.

If even with its many heuristics RichEdit still cannot find a reasonable font and a Microsoft Office application is running, RichEdit queries the Office mso.dll if it’s loaded. Also, various kinds of “font fallback” may kick in at display time to save a character from being rendered as a missing-character glyph. Font binding is an area of active research since new character scripts continue to be added to Windows and Unicode continues to add new characters. In general, RichEdit’s built-in font binding does a good job of it, but it could be better.

Alternatively, RichEdit controls can call methods on the IProvideFontInfo interface to assign fonts to text runs. During RichEdit control initialization, the client may supply the IProvideFontInfo pointer via a callback to ITextHost::QueryInterface() as done by the XAML RichEditBox and TextBox controls. Or if the client has loaded the Microsoft Office shared library mso.dll, a D2D/DirectWrite RichEdit control will try to create an enhanced IProvideFontInfo object. The latter is a wrapper around the DirectWrite IDWriteFontFallback interface. In principle, this font binding handles all ISO scripts that Windows supports. But it doesn’t handle math-zone font binding.

The methods of IProvideFontInfo are:

- Get default font (the BSTR returned will be freed by the caller of this function)

virtual BSTR GetDefaultFont() = 0;

- Get font face ID to be used for new characters

virtual DWORD GetRunFontFaceId( _In_z_ const wchar_t* pCurrentFontName, // Current font _In_ DWRITE_FONT_WEIGHT weight, // Bold, Extra Bold, ... _In_ DWRITE_FONT_STRETCH stretch, // Condensed, expanded, ... _In_ DWRITE_FONT_STYLE style, // Italic, Oblique, Normal _In_ LCID lcid, // Locale id _In_opt_count_(charCount) const wchar_t* pText, // Input characters _In_ unsigned int charCount, // Character count of pText _In_ DWORD fontFaceIdCurrent, // Current font face Id _Out_ unsigned int& runCount)=0; // Character count for subset of pText covered

- Check if a different font should be used for new characters

virtual IDWriteFontFace* GetFontFace( _In_ DWORD fontFaceId) = 0; // Font ID

- Get name of a font face belonging to a font ID

virtual BSTR GetSerializableFontName( _In_ DWORD fontFaceId) = 0;

The GUID for IProvideFontInfo is 7502135B-17C1-4A25-BDC9-55E6BCB8598A.

The Office IProvideFontInfo instantiation includes two extra methods that belong to IProvideFontInfo2 (which inherits from IProvideFontInfo):

- Get Default Font face without saving a fontID

virtual HRESULT GetDefaultFontFace( IDWriteFontFace** pDwriteFontFace) = 0;

- Refresh font-face cache

virtual HRESULT RefreshFontFaceCache( const std::wstring& gdiName) = 0;

The GUID for IProvideFontInfo2 is F71EE023-E909-4F63-B569-EA08956D0004.

The post RichEdit Font Binding appeared first on Math in Office.

]]>The post Switching from LaTeX to UnicodeMath Input Mode appeared first on Math in Office.

]]>One might conclude that when switching from LaTeX to UnicodeMath input mode, Word should remove the nobuildup effect from all ‘/’ in the current math zone. But the intent in LaTeX is not to build up a fraction with a ‘/’ since built-up fractions are entered in TeX and LaTeX using the special constructs \over and \frac, respectively. The only way the user can build up a nobuildup ‘/’ is to delete the ‘/’ and reenter it. ‘/’ is the only operator that’s marked as nobuildup automatically in LaTeX input mode. A ‘/’ that’s not marked as nobuildup in LaTeX mode is actually used in building up the TeX {<numerator>\over <denominator>} construct. The build-up engine supports TeX as well as LaTeX constructs, since users might use either.

In UnicodeMath input mode, you can mark an operator as “nobuildup” by preceding it with a \. So “a\/b” produces 𝑎/𝑏 and you can try to build it up with a space, but, by design, it won’t build up. It’s fairly common to want to have a simple linear fraction and that’s how it’s done. You can “quote” other operators to prevent them from building up. For example, you might want to quote delimiters, e.g., \{ and \}, which won’t then build up to fit their content.

Perhaps the math ribbons should display the “nobuildup” attribute. Then the user could see a difference. It’d also be handy for the math ribbon to display the bold and italic attributes, since these are commonly used in math zones for math-bold and math-italic characters.

The post Switching from LaTeX to UnicodeMath Input Mode appeared first on Math in Office.

]]>The post RichEdit HTML Support appeared first on Math in Office.

]]>Contents

The “HTML format” clipboard format includes header and comment data in addition to the HTML to be copied (see https://docs.microsoft.com/en-us/windows/win32/dataxchg/html-clipboard-format#description). This info needs to be added to copy HTML between RichEdit, Word, PPT, OneNote, Teams, and other apps. Frankly having to add this info seems like overkill. RTF can be copied and pasted without such overhead. We illustrate the format as written by RichEdit with the HTML for Einstein’s energy equation 𝐸 = 𝑚𝑐². In the HTML, OMML is the math format used by default since that’s what Word and PowerPoint expect. Here’s the HTML

Version:1.0 StartHTML:0000000105 EndHTML:0000000844 StartFragment:0000000417 EndFragment:0000000811 <html xml:lang="en" lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml"> <head><style>body{font-family:Arial,sans-serif;font-size:10pt;}</style> <style>.cf0{font-style:italic;font-family:Cambria Math;font-size:24pt;}</style></head> <body><!--StartFragment --><p><m:oMathPara><m:oMath class="cf0"> <span class="cf0"><m:r><i>𝐸</i></m:r></span> <span class="cf0"><m:r><i>=</i></m:r></span><span class="cf0"> <m:r><i>𝑚</i></m:r></span> <m:sSup><m:sSupPr><m:ctrlPr></m:ctrlPr></m:sSupPr><m:e><span class="cf0"> <m:r><i>𝑐</i></m:r></span></m:e><m:sup><span class="cf0"><m:r><i>2</i> </m:r></span></m:sup></m:sSup></m:oMath></m:oMathPara></p> <!--EndFragment --></body></html>

Here the StartHTML entry in the header gives the character position (cp) offset of the HTML <body> and EndHTML gives the cp at the end of the HTML <body>. The StartFragment gives the cp of the text that the user selected and the EndFragment gives the cp at the end of the selection. In this example, the equation 𝐸 = 𝑚𝑐² is selected and displayed on its own line (display mode rather than inline mode). The start of the displayed equation is given by the OMML <m:oMathPara>. The corresponding MathML including an mml: prefix is

<mml:math xmlns:mml="http://www.w3.org/1998/Math/MathML" display="block"> <mml:mi>E</mml:mi> <mml:mo>=</mml:mo> <mml:mi>m</mml:mi> <mml:msup> <mml:mi>c</mml:mi> <mml:mn>2</mml:mn></mml:msup></mml:math>

The Programming details section describes how to write HTML with OMML or MathML with and without the mml: prefix. The HTML5 standard includes MathML without a prefix. RichEdit can write and read HTML with all three math formats.

Character formatting includes font and family, height, text and back color, weight, spacing, bold, italic, underline, strikeout, subscript, superscript, small caps, all caps and hyperlinks. Paragraph formatting includes numbered and bulleted lists, left, right, and centered alignments, and paragraph margins.

RichEdit can read and write the HTML <img> element with a src attribute that has a base64 encoding of the binary image data. This is a technique used widely in Microsoft Office for HTML copy/paste. For example, the tag might begin with “<img src=\”data:image/png;base64,”.

HTML content can be read in and out via messages, hot keys (Ctrl+c, Ctrl+v, Ctrl+x), and TOM methods.

A client can get HTML content by sending the EM_STREAMOUT message with wParam = SF_HTML | SF_BINARY. The SF_BINARY (0x0008) is needed to write the data in the RichEdit binary format to temporary memory and then the SF_HTML (0x00100000) writes that data out as HTML. If clipboard HTML is desired, OR the SF_CLIPBOARD (0x80000000) flag into wParam.

A client can stream in HTML content by sending the EM_ISTREAMIN message (WM_USER + 252), which streams in using the IStream interface pointed to by the lParam instead of using the usual EDITSTREAM struct. This choice is due to use of the Office HTML parser for input and the mso.dll must be loaded for that to work. Set wParam equal to 1, which signifies HTML. Currently only HTML can be streamed in using the EM_ISTREAMIN message.

Other messages that can be used are WM_COPY, WM_PASTE, WM_CUT, and EM_PASTESPECIAL which are all described on the web.

In addition to the ITextRange::Copy() and ITextRange::Paste() methods, you can input HTML content into a range by calling ITextRange2::SetText2(tomConvertHtml, bstr), where tomConvertHtml is given by 0x00900000. Similarly, you can get the HTML content from a range by calling ITextRange2:GetText2(tomConvertHtml, pbstr).

By default, RichEdit writes equations in HTML in the OMML format since that format is what Office apps like Word and PowerPoint expect. But it can write equations in MathML with or without an mml: prefix. The function to call to set which math format to use is ITextDocument2::SetMathProperties() with tomHtmlOMML, tomHtmlMathML, or tomHtmlMath

tomHtmlMathFormatMask = 0x00300000, // Mask for math-format flags tomHtmlOMML = 0, // m: tomHtmlMathML = 0x00100000, // mml: tomHtmlMath = 0x00200000, // No prefix MathML (HTML5)

The post RichEdit HTML Support appeared first on Math in Office.

]]>The post Cool Windows Math Hot Key appeared first on Math in Office.

]]>

Another cool Windows hot key is “Windows+.” or “Windows+;”. Using Windows+Shift+s, I get the image

You can see related character displays by clicking on the characters in the bottom row. You can scroll these displays to see more characters. Clicking on a character not in the top or bottom row inserts that character into your active app.

Now click on the Ω in the top row of characters. You get

Here I’ve selected the ∞ page. This has many fractions, numeric subscripts and superscripts, ∞ of course, and, if you scroll down you can access myriad math symbols such as ∰. For example, you can see

I wish C++ would use some of those relational operators instead of being stuck in the 1960’s with ASCII sequences like “!=” instead of ‘≠’! Clicking on the ⨀ in the bottom row reveals still more math symbols.

The Assistive Technology (AT) program Narrator describes some of the features of these displays and knows how to speak the emoji characters. But it doesn’t know how to speak most of the advanced math symbols. In fact, I have a hard time speaking some of those symbols myself, like ⋈ (bowtie?)

The post Cool Windows Math Hot Key appeared first on Math in Office.

]]>The post Math Accessibility Trees appeared first on Math in Office.

]]>More than one kind of tree is possible and this post compares two trees for the equation

Each tree node is labeled with its math text in UnicodeMath along with the type of node. UnicodeMath lends itself to being spoken especially if processed a bit to speak things like 𝑎² as “a squared” in the current natural language as described in Speaking of math…. The first kind of tree corresponds to the traditional math layout used in documents, while the second kind corresponds to the mathematical semantics. Accordingly we call the first kind a *display tree* and the second a *semantic tree*.

More specifically, the display tree corresponds to the way TeX and OfficeMath display mathematical text and approximates the way Presentation MathML represents mathematical text. Mathematical layout entities such as fractions, integrals, roots, subscripts and superscripts are represented by nodes in trees. Binary and relational operators that don’t require special typography other than appropriate spacing are included in text nodes. The display tree for the equation above is

└─Math zone └─ “1/2π ∫_0^2π ⅆ𝜃/(𝑎+𝑏 sin 𝜃) = 1/√(𝑎²−𝑏²)” ├─ “1/2π” fraction │ ├─ “1” numerator │ └─ “2π” denominator ├─ “∫_0^2π ⅆθ/(𝑎+𝑏 sin 𝜃)” integral │ ├─ “0” lower limit │ ├─ “2π” upper limit │ └─ “ⅆθ/(𝑎+𝑏 sin 𝜃)” integrand │ └─ “ⅆθ/(𝑎+𝑏 sin 𝜃)” fraction │ ├─ “ⅆθ” numerator │ └─ “𝑎+𝑏 sinθ” denominator │ ├─ “𝑎+𝑏” text │ └─ “sin𝜃” function apply │ ├─ “sin” function name │ └─ 𝜃” argument ├─ “=” text └─ “1/√(𝑎²−𝑏²)” fraction ├─ “1” numerator └─ “√(𝑎²−𝑏²)” denominator └─ “√(𝑎²−𝑏²)” radical ├─ “⬚” degree └─ “𝑎²−𝑏²” radicand ├─ “𝑎²” superscript │ ├─ “𝑎” base | └─ “2” script ├─ “−” text └─ “𝑏²” superscript ├─ “𝑏” base └─ “2” script

Note that the invisible times implicit between the leading fraction and the integral isn’t displayed and the expression 𝑎 + 𝑏 sin*θ* is displayed as a text node 𝑎 + 𝑏 followed by a function-apply node sin*θ*, without explicit nodes for the + and an implied invisible times.

To navigate through the 𝑎 + 𝑏 and into the fractions and integral, one can use the usual text left and right arrow keys or their braille equivalents. In OfficeMath, one can navigate through the whole equation with these arrow keys, but it’s helpful also to have coarser grained navigation keys to go between sibling nodes and up to parent nodes. For the sake of discussion, let’s suppose the tree navigation hot keys are those defined in the table

Ctrl+→ | Go to next sibling |

Ctrl+← | Go to previous sibling |

Home | Go to parent ahead of current child |

End | Go to parent after current child |

For example starting at the beginning of the equation, Ctrl+→ moves past the leading fraction to the integral, whereas → moves to the start of the numerator of the leading fraction. Starting at the beginning of the upper limit, Home goes to the insertion point between the leading fraction and the integral, while End goes to the insertion point in front of the equal sign. Ctrl+→ and Ctrl+← allow a user to scan an equation rapidly at any level in the hierarchy. After one of these hot keys is pressed, the linear format for the object at the new position can be spoken in a fashion quite similar to ClearSpeak. When the user finds a position of interest, s/he can use the usual input methods to delete and/or insert new math text.

Now consider the semantic tree, which allocates nodes to all binary and relational operators as well as to fractions, integrals, etc.

└─Math zone └─ “1/2𝜋 ∫_0^2𝜋 ⅆ𝜃/(𝑎+𝑏 sin𝜃)=1/√(𝑎²− 𝑏²)” └─ “=” text ├─ “⊠” implied times │ ├─ “1/2𝜋” fraction │ │ ├─ “1” numerator │ │ └─ “2π” denominator │ └─ “∫_0^2𝜋 ⅆ𝜃/(𝑎+𝑏 sin𝜃)” integral │ ├─ “0” lower limit │ ├─ “2π” upper limit │ └─ “ⅆ𝜃/(𝑎+𝑏 sin𝜃)” integrand │ └─ “ⅆ𝜃/(𝑎+𝑏 sin𝜃)” fraction │ ├─ “ⅆ𝜃” numerator │ │ └─ “⊠” implied times │ │ ├─ “ⅆ” text │ │ └─ “𝜃” text │ └─ “𝑎+𝑏 sin𝜃” denominator │ └─ “+” text │ ├─ “𝑎” text │ └─ “𝑏 sin𝜃” function apply │ └─ “⊠” implied times │ ├─ “𝑏” text │ └─ “sin𝜃” function │ └─ “” function apply │ ├─ “sin” function name │ └─ “𝜃” argument └─ “1/√(𝑎²− 𝑏²)” fraction ├─ “1” numerator └─ “√(𝑎²− 𝑏²)” denominator └─ “√(𝑎²− 𝑏²)” radical ├─ “⬚” degree └─ “𝑎²− 𝑏²” radicand └─ “−” text ├─ “𝑎²” superscript │ ├─ “𝑎” base │ └─ “2” script └─ “𝑏²” superscript ├─ “𝑏” base └─ “2” script

The semantic tree corresponds to Content MathML. It has drawbacks: 1) it’s bigger and requires more key strokes to navigate, 2) it doesn’t correspond to speech order, and 3) it requires a Polish-prefix mentality. Some people have developed such a mentality, perhaps having used HP calculators, and prefer it. But it’s definitely an acquired taste and it doesn’t correspond to the way that mathematics is conventionally displayed, edited, and spoken. Accordingly the first kind of tree seems significantly better for speech and editing, at least for the math encountered in grades K-12.

The choice for higher-level math is complicated by the fact that the usual meanings for superscripts, vertical bars, and other notation may be incorrect. For example, exponents are usually powers and it’s appropriate to speak 𝑎² as “a squared”. But in tensor analysis, exponents can be indices and saying them as powers is incorrect. One way around this is to say 𝑎² as “a superscript 2” or “a sup 2”, but it would be better to know the author’s intent and generate more descriptive speech. Another example is |𝑥|. In math up through calculus, this is the absolute value of 𝑥. However, in higher-level math it could mean the cardinality of the set 𝑥, or something else. In these cases and many others in advanced math, the semantic tree might reveal the author’s intent better than the display tree.

The MathML working group is studying ways to make Presentation MathML support accurate speech for ambiguous mathematical notations.

Both kinds of trees include nodes defined by the OMML entities listed in the following table along with the corresponding MathML entities

Built-up Office Math Object | OMML tag | MathML |

Accent |
acc | mover/munder |

Bar |
bar | mover/munder |

Box |
box | menclose (approx) |

BoxedFormula |
borderBox | menclose |

Delimiters |
d | mfenced or mrow with mo’s |

EquationArray |
eqArr | mtable (with alignment groups) |

Fraction |
f | mfrac |

FunctionApply |
func | mrow with &FunctionApply; |

LeftSubSup |
sPre | mmultiscripts (special case of) |

LowerLimit |
limLow | munder |

Matrix |
m | mtable |

Nary |
nary | mrow followed by msubsup w n-ary mo |

Phantom |
phant | mphantom and/or mpadded |

Radical |
rad | msqrt/mroot |

GroupChar |
groupChr | mover/munder |

Subscript |
sSub | msub |

SubSup |
sSubSup | msubsup |

Superscript |
sSup | msup |

UpperLimit |
limUpp | mover |

Ordinary text |
r | mtext |

MathML has additional nodes, some of which involve infix parsing to recognize, e.g., integrals. The OMML entities were defined for typographic reasons since they require special display handling. Interestingly the OMML entities also include useful semantics, such as identifying integrals and trigonometric functions without special parsing.

In summary, math zones can be made accessible using display trees for which the node contents are spoken in the localized linear format and navigation is accomplished using simple arrow keys, Ctrl arrow keys, and the Home and End keys, or their Braille equivalents. Arriving at any particular insertion point, the user can hear or feel the math text and can edit the text in standard ways.

The post Math Accessibility Trees appeared first on Math in Office.

]]>The post Some UnicodeMath Enhancements appeared first on Math in Office.

]]>With all three formats, the *n*-aryand, e.g., integrand or summand, may not be identified by surrounding delimiters. But OfficeMath and MathType have *n*-aryand arguments as described in the post Integrands, Summands, and Math Function Arguments. UnicodeMath has the binary operator U+2592 (▒) to treat the expression that follows the ▒ as the *n*-aryand (see Section 3.4 of UnicodeMath 3.1). In generalizing the conversion code for LaTeX and braille, it became clear that a space alone is adequate for starting *n*-aryands and we don’t need the ▒, which doesn’t look like mathematics. So, the converter now makes the first expression that follows the *n*-ary operator and limits into the *n*-aryand. For example, the integral

can be given by the UnicodeMath 1/2π ∫_0^2π ⅆθ/(a+b sin θ)=1/√(a^2-b^2) since the first expression that follows the ∫_0^2π is the fraction ⅆθ/(a+b sin θ). This works for many integrands. More complicated integrands are usually enclosed in brackets, braces, or parentheses.

A “bare” matrix, that is, one with no enclosing brackets can be entered by typing the TeX control word \matrix. In addition, there are five matrix constructs with enclosing brackets that can be entered as summarized in the following table in which … stands for the matrix contents.

LaTeX |
Char |
Code |
Form |

\matrix | ■ | U+25A0 | … |

\bmatrix | ⓢ | U+24E2 | […] |

\pmatrix | ⒨ | U+24A8 | (…) |

\vmatrix | ⒱ | U+24B1 | |…| |

\Bmatrix | Ⓢ | U+24C8 | {…} |

\Vmatrix | ⒩ | U+24A9 | ‖…‖ |

The UnicodeMath syntax for a parenthesized 2×2 matrix is \pmatrix(a&b@c&d), which builds up as

Sometimes you just want to enter a sample matrix quickly. If any of the six matrix control words are followed by a digit *d*, they insert a *d *× *d* identity matrix. For example, typing \pmatrix 3 enters

This is easier to type than \pmatrix(1&0&0@0&1&0@0&0&1), which displays the same identity matrix. Some of the matrix control words are missing in the default math autocorrect file. You can add them as described in the last section of this post.

This trigonometric expression is ambiguous: is it sin(𝑥²) or (sin 𝑥)²? Without the parentheses, the UnicodeMath for the former is “sin x^2” and for the latter is “sin x ^2”. In the latter, the space following the x builds up the sin x into a math function object and then the ^2 squares the object. But the results are very different formulas. The converter avoids the ambiguity by building up “sin x ^2” to be the same math function object as “sin^2 x”, that is, sin² 𝑥.

You can enter the common LaTeX expressions \frac{a}{b} and \binom{n}{m} in UnicodeMath input mode provided you have added math autocorrect entries to convert \frac to ⍁ (U+2341) and \binom to ⒝ (U+249D). To add math autocorrect entries, click on the lower-right box in the Equations/Conversions ribbon option to display the dialog box

Then click on the Math AutoCorrect… button to see and add math autocorrect entries. For example, to add \frac with U+2341, type as in the dialog box

And then enter Alt+x to convert the 2341 to ⍁. Probably when you type LaTeX in UnicodeMath input mode, a dialog ought to appear asking you if you’d like to switch to LaTeX input mode.

The post Some UnicodeMath Enhancements appeared first on Math in Office.

]]>The post RichEdit Emoticon Shortcuts appeared first on Math in Office.

]]>The build-in emoticon shortcuts are defined in the table

Type |
Get |
Unicode |

`%)` |
U+1F615 | |

`0:)` |
U+1F607 | |

`:'(` |
U+1F622 | |

`:')` |
U+1F602 | |

`:'-(` |
U+1F622 | |

`:'-)` |
U+1F602 | |

`:(` |
U+02639 | |

`:)` |
U+0263A | |

`:+1:` |
U+1F44D | |

`:-(` |
U+02639 | |

`:-)` |
U+1F60A | |

`:-D` |
U+1F603 | |

`:-o` |
U+1F632 | |

`:-p` |
U+1F61D | |

`:-|` |
U+1F610 | |

`:D` |
U+1F603 | |

`:fire:` |
U+1F525 | |

`:grin:` |
U+1F601 | |

`:o` |
U+1F632 | |

`:p` |
U+1F61D | |

`:smile:` |
U+1F604 | |

`:yum:` |
U+1F60B | |

`:|` |
U+1F610 | |

`;)` |
U+1F609 | |

`;-)` |
U+1F609 | |

`</3` |
U+1F494 | |

`<3` |
U+02764 | |

`>:)` |
U+1F608 | |

`B-)` |
U+1F60E |

The emoticon shortcut facility is incorporated into the RichEdit autocorrect facility. To enable the autocorrect facility, send the message EM_SETAUTOCORRECTPROC with wparam = an AutoCorrectProc callback pointer. If you don’t want to implement an autocorrect callback, set wparam = 1. This activates the built-in math autocorrect facility in math zones. It also activates emoticon shortcuts if they’re enabled. To enable the emoticon shortcuts, get the current language-option flags by sending EM_GETLANGOPTIONS, OR in IMF_EMOTICONSHORTCUTS (0x8000), and send EM_SETLANGOPTIONS with lparam equal to the result. The emoticon-shortcut option is disabled by default. Have fun

The post RichEdit Emoticon Shortcuts appeared first on Math in Office.

]]>