The post It’s been so fine! appeared first on Math in Office.

]]>It all started in 1988 when I had a summer job getting Microsoft’s CodeView debugger running in protected mode up out of the MS-DOS 640 KB address space. My SST debugger could load and run real-mode DOS programs in protected mode with access to all the memory on Intel 286 and 386 CPUs. It could also execute backwards, quite handy for debugging. CodeView was cool, but Windows 2.1 seemed cooler, so David Weise and I decided Windows needed to run in protected mode too! David used SST to single step through the Windows kernel, fixing exceptions along the way. Pretty soon Windows ran in protected mode as described in the post Saving Windows from the OS/2 Bulldozer. It was a seminal moment for Windows.

In July 1992 I joined Microsoft full-time working in Research for Nathan Myhrvold who reported to Bill Gates. My hope was to spend a couple of years implementing math editing and display in Word along the lines of my PS Technical Word Processor and then resume being a Professor of Optical Sciences at the University of Arizona. Word wasn’t ready at that time for better math handling, and Peter Pathe wanted me to develop RichEdit 2.0 for Office 97. That proved to be a great fit since I had written PS. I joined the Unicode Technical Committee partly because Unicode had so many math symbols and naturally RichEdit 2.0 had to be based on Unicode. At a crucial Word meeting back in 1995, we made the decision to base Word 97 on Unicode. Word 97 was the first major app to use Unicode! Fortunately, Windows NT 3.5 and TrueType were based on Unicode, and David Weise created ExtTextOutW one weekend to display Unicode in Windows 95. Okay, admittedly without complex script support! I chaired the Text Object Model (TOM) committee and implemented TOM in RichEdit. Alex Gounares, José Oglesby, Rick Sailor, Hon-Wah Chan, Christian Fortini, and Jon Matousek all contributed to RichEdit 2.0.

Office 97 was a sensation at the time, and management concluded RichEdit 2.0 could go into maintenance mode. José and I didn’t think it was ready for that and we stayed on. Ayman Aldahleh added Bidi support for RichEdit 2.1 and Chai Chaoweeraprasit added Uniscribe complex script support for RichEdit 3.0, the first globalized version. That version is still available in Windows today for backwards compatibility. Chai, Greg Hitchcock, and Dwayne Robinson have been immensely helpful over the years in explaining how display software works. Greg is probably the only one left at Microsoft who used my SST debugger! I joined the MathML working group in 1999.

Pocket Word and WordPad wanted lots of Word functionality, and eBooks needed pagination and special UI. So, we kept improving RichEdit with the able help of Greg Heino and his test team. I implemented the RichEdit nested table facility, the RichEdit binary file format, UTF-8 RTF (a major improvement on RTF), and created the Alt+x Unicode entry method now available in Word, OneNote, Outlook, WordPad, and Notepad (should be available in any decent text editor!). OneNote raised the bar still further. And then sheer magic happened! I demonstrated that LineServices could render built-up math equations using appropriate callbacks. That didn’t surprise Eliyezer Kohen and his incredible team (Sergei Genkin, Igor Zverev, Victor Kozyrev, Andrei Burago, Alex Vaschillo, Anton Sukhanov) since they had designed LineServices with math display in mind. But an extraordinary team of engineers came together somewhat spontaneously to add elegant math editing and display to Word in a sharable way that we subsequently integrated into OneNote, PowerPoint and other apps. Bill Gates, Steven Sinofsky, and Chris Prately gave the team their support. Jennifer (Michelstein) Halberstam, who had just graduated from Yale (40 years after I did), was the Word Program Manager for math and did an amazing job. The math display quality rivals TeX, which guided the design. Bill Hill’s team sponsored the Cambria font family including Cambria Math, and Sergey Malkin wrote the math-font library facilitating access to what is now the ISO OpenType standard for math typography. I suggested that Word handle formula autobuild up on its own, but Jennifer correctly observed that it should be written in shared code. So, I created the TOM2 interfaces adding math-oriented (and other) methods to the original TOM interfaces that we created for Office 97. I’m forever indebted to Isau Yamauchi for testing my math code. Today that shared code converts UnicodeMath, LaTeX, speech, and braille to/from OfficeMath. The math build-up facility needs a rich-text scratch story, so I implemented the RichEdit multi-story facility.

For Office 2010, Sasha Gil masterminded OfficeArt’s text layout using RichEdit and built the dual GDI/D2D capability, I implemented the shared math context-menu and math ribbon, José integrated the math facility into OfficeArt among many other contributions, Mikhail Baranovsky wrote and/or polished our MathML and OMML converters, and Joe Roni ran the test team. OfficeArt is a shared component used, for example, by PowerPoint.

After Office 2010, Ayman added the text services group to his team. I first met Ayman in the summer of 1991 when I was an expert witness for Microsoft in the Al Alamia lawsuit. It’s been great working with him these many years improving the Unicode Bidi Algorithm and enhancing RichEdit. Windows 8 needed a lot of new RichEdit functionality, particularly for XAML, and fortunately Rick Sailor and Hon-Wah Chan were on board to help with that. Stephen Chua, my boss for several years now, had his first project testing the OS password control option which I implemented using an encrypted backing store.

Later the Excel folks wanted RichEdit to be the new Excel editor and needed specialized functionality. After all that along with lots of other features described in Math in Office, notably math speech and braille for accessibility, I decided to retire at age 75. But my boss at the time Ziad Khalidi convinced me to stay on to add GIF animation and variable-font support. And then the Windows Calculator folks wanted the math facility for the graphing option, Notepad wanted to use RichEdit upgraded in significant ways, e.g., “Show Unicode control characters”, and Modern Comments wanted RichEdit to replace Word in desktop commenting. So, I exposed and improved the RichEdit HTML converters, implemented autoformatting and emoticon shortcuts, and created RichEdit D2D window controls. Imagine: 26 years after Office 97 and RichEdit still isn’t in maintenance mode! Collaborating with Mingxin Wang on Notepad via Teams has worked so well. We’re on opposite sides of the planet and it’s almost as if we’re in the same room together! Recently I implemented math dictation and you can dictate equations into OneNote and PowerPoint! There’s still more math work to do, e.g., add OfficeMath support to our web apps. But hopefully other people can figure out how to do that.

Myriad people have helped me accomplish things over the years, only some of whom are mentioned here, and I’ve always had great management. Many thanks to all!

The post It’s been so fine! appeared first on Math in Office.

]]>The post Math Dictation appeared first on Math in Office.

]]>Examples of math dictation and the resulting OfficeMath are

Math Dictation |
Resulting OfficeMath |

A squared plus b squared equals c squared |
\(a^2+b^2=c^2\) |

Integral from minus infinity to infinity of e to the minus x squared dx equals square root of pi |
\(\displaystyle\int_{-\infty}^\infty e^{-x^2} dx=\sqrt\pi\) |

limit as N goes to infinity of left paren 1 + 1 over n right paren to the N equals e |
\(\displaystyle\lim_{n\rightarrow\infty}{\left(1+\frac{1}{n}\right)^n}=e\) |

sine squared x plus cosine squared x equals one |
\(\sin^2{x}+\cos^2{x}=1\) |

derivative of f of x with respect to x = second derivative of f of x with respect to x = second partial derivative of f of x,y with respect to x = 0 |
\(\displaystyle\frac{df\left(x\right)}{dx}=\frac{d^2f\left(x\right)}{dx^2}=\frac{\partial^2f\left(x,y\right)}{\partial x^2}=0\) |

One over two pi space integral from zero to 2π of D theta over begin a + b sine theta end equals one over square root of begin a squared – b squared end |
\(\displaystyle\frac{1}{2\pi}\int_{0}^{2\pi}\frac{d\theta}{a+b\sin{\theta}}=\frac{1}{\sqrt{a^2-b^2}}\) |

left paren a plus b right paren to the n equals sum from k = 0 to n of left paren n a top k right paren a to the k space b to the begin n – k end |
\(\displaystyle\left(a+b\right)^n=\sum_{k=0}^{n}{\binom{n}{k}a^kb^{n-k}}\) |

X equals begin minus B plus or minus square root of begin b ^2 – 4 A C end end over 2A |
\(\displaystyle x=\frac{-b\pm\sqrt{b^2-4ac}}{2a}\) |

Absolute value of x equals cases if x greater than or equal to 0, ampersand x next if x less than 0, ampersand -x close |
\(\displaystyle|x|=\cases{\mathrm{if}\,x≥0,\,x\cr \mathrm{if}\,x<0,\,-x}\) |

Del cross bold cap e equals minus partial derivative of bold cap b with respect to t |
\(\displaystyle\nabla\times\mathbf{E}=\ -\frac{\partial\mathbf{B}}{\partial t}\) |

i H bar space partial over partial T space cap sigh left paren X, t right paren equals [minus h bar squared over 2M space space partial squared over partial X ^2 plus cap V left paren X, t )] cap psi left paren X, t right paren |
\(\displaystyle i\hbar\frac{\partial}{\partial t}\Psi\left(x,t\right)=\left[-\frac{\hbar^2}{2m}\frac{\partial^2}{\partial x^2}+V\left(x,t\right)\right]\Psi\left(x,t\right)\) |

real part of e to the -i omega t equals cosine omega t |
\(\displaystyle Re{\left(e^{-i\omega t}\right)}=\cos{\omega t}\) |

If you know a TeX control word, you can dictate it by saying “backslash <control word>”.

Just as you may need to include words like “comma” and “question mark” in ordinary dictation, you may need to include words like “space” in math dictation to overrule the operator precedence of UnicodeMath. For example, the speech for the sixth equation above starts with “One over two pi space…”. The “space” is converted to a “ “, which instructs the UnicodeMath build-up engine to build up the 1/2𝜋. Else the integral that follows would end up in the denominator following the 2𝜋. Similarly, the examples contain “begin” and “end” or parentheses to overrule operator precedence. These special words are defined and illustrated in UnicodeMath.

In addition, there are words to choose math styles like script, bold, bold-italic, fraktur, and open-face (or double struck). Examples of such characters are ℋ𝐇𝑯ℌℍ. You get these by saying “script cap h”, “bold cap h”, “bold italic cap h”, “fraktur cap h”, and “double struck cap h”, respectively.

The speech can include common English idioms as in “a doesn’t equal b” or “a isn’t equal to b”, both of which result in “𝑎 ≠ 𝑏”.

To dictate math in OneNote, enter a math zone with Alt+= hot key and dictate. It’s important to enunciate clearly. Also set the feature gate “Microsoft.Office.SharedText.OneNoteMathDictation” to true. To dictate math in PowerPoint, do the same after setting the feature gate “Microsoft.Office.Graphics.EnableMathDictation” to true.

The translator converts incoming math speech into UnicodeMath and builds up the result into OfficeMath in the app backing store. Some additions have been made to the build-up engine, such as the new keyword \abs for converting “absolute value of …” which is more natural than “vertical bar … vertical bar”. Also, the vertical bar notation is ambiguous: it can mean absolute value, cardinality of a set or group, or determinant. The speech “absolute value of …” is unambiguous. The current dictated math speech produced for \(a^2+b^2=c^2\) has some fixups that result in A ^2 + B ^2 = C ^2 , which is close to the UnicodeMath a^2+b^2=c^2. The translator deletes the spaces and converts letters to lower case. The translator also converts “a squared plus b squared equals c squared”. To enable math dictation, include the tomMathSpeech flag (0x10000000) in the call to MathBuildUp().

Three places to make improvements and fixes are:

- Speech recognizer, e.g., it could benefit from a “math mode”
- Speech-to-UnicodeMath translator
- UnicodeMath build-up engine

Math speech recognition works remarkably well considering that we don’t tell the recognizer that math is involved. Nevertheless, there are results that are wrong for math. For example, “n” is often replaced by “end” and “b” by “be”. You can get the correct letter by preceding the letter with “letter” which the translator discards. “Sum” often ends up as “some” and “begin” may end up as “beginning”. You can avoid the “sum” error by saying “summation”. So, some editing may be needed before converting the speech to math. The math translation engine autocorrects “be” to “b”, “some” to “sum”, “sigh” to “𝜓”, and “beginning” to “begin”, since these words aren’t generally used in math zones.

The post Math Dictation appeared first on Math in Office.

]]>The post ITextDocument2 SetProperty and GetProperty appeared first on Math in Office.

]]>Property ID |
Property Value |
ID def |

tomAlignWithTrailSpace | Set/Get: if true, paragraph center alignment includes trailing spaces. | 0x92 |

tomAnimateImages | Set/Get: if true, enable GIF animation. Must be a DWrite control. | 0x96 |

tomCanCopy | Get: true if either the current selection isn’t protected or an EN_PROTECTED query returns S_OK | 0x89 |

tomCanRedo | Get: true if redo entries exist | 0x8A |

tomCanUndo | Get: true if undo entries exist | 0x8B |

tomDocAlignPlainTextBaseLine | Set/Get: if true, align plain-text baselines on lines with fonts of different ascents and descents which may occur, for example, with mixtures of Latin and Asian fonts. Such alignment increases the line height. | 0xA0 |

tomDocAutoLink | Set/Get: same value definitions as for wparam of EM_AUTOURLDETECT | 0x8D |

tomDocColorFlags | Set/Get: if value = tomDocDisableColorCompare (1), disable RichEdit color render fixups when back color and text colors are too similar. Used mostly for transparent controls. | 0xA2 |

tomDocConverterFlags | Set/Get: a set of flags. tomUseTomMmlWriter (1) uses the TOM MathML/OMML writer instead of the HTML writer. tomWriteSelAttributes (2) writes selection attributes in MathML/OMML. tomNoMmlPrefix (4) suppresses the mml: prefix in MathML. tomNoIndent (8) doesn’t indent MathML or OMML. | 0x98 |

tomDocDefaultTabSize | Set/Get: value equals #columns of a default tab, where the column width is given by the width of a space. | 0xA1 |

tomDocImageFlags | Set/Get: if value = tomNoImageHandles (1), don’t display sizing handles on a selected image. If value = tomEnableD2DPreviewZoom (2), enable print-preview zoom for D2D/DWrite controls and RichEditD2D[PT] window controls. | 0x99 |

tomDocNoMfenced | Set/Get: if value = tomNoMfenced (1), MathML writer writes <mrow> element equivalent to <mfenced>. The latter isn’t supported in MathML core. | 0x97 |

tomDocShowUnicodeControls | Set/Get: if value = tomShowUnicodeControls (1), display special zero-width glyphs for Unicode Bidi controls and ZWJ (U+200D used in family emoji). For more detail, see the section “Show Unicode control characters mode and emoji” in the Notepad post. | 0x9A |

tomDocSpaceBefore | Set/Get: value gives vertical space before start of document. For an example, see the section “Find/Replace dialog drop down” in the Notepad post. | 0x9B |

tomDocSpaceBeforeMax | Set/Get: maximum document space before | 0x9D |

tomDocSpaceBeforeMin | Set/Get: minimum document space before | 0x9C |

tomDocViewFlags | Set/Get: if value = tomDocViewNoInsetZoom (1), don’t zoom the window inset when the content is zoomed. | 0x9E |

tomEllipsisMode | Set/Get: value can be ELLIPSIS_NONE (0) ellipsis disabled, ELLIPSIS_END (1) ellipsis at the end (forced break), or ELLIPSIS_WORD (3) ellipsis at the end (word break) | 0x8E |

tomEllipsisState | Get: if true, the display ends with an ellipsis. | 0x8F |

tomEncloseSurroundSpacing | Set/Get: value is extra spacing in twips before and after an Enclose object. | 0x93 |

tomIgnoreTrailSpacing | Set/Get: if true, don’t include added intercharacter spacing for the last character in a line. | 0x95 |

tomRichText | Get: if true, control is a rich-text control. | 0x94 |

tomUndoLimit | Set/Get: same value definitions as for wparam of EM_SETUNDOLIMIT | 0x8C |

tomUnderlineTrailSpace | Set/Get: if true, underline trail spaces. | 0x91 |

The post ITextDocument2 SetProperty and GetProperty appeared first on Math in Office.

]]>The post Displaying Math in WordPress appeared first on Math in Office.

]]>As an example of embedded LaTeX, several of my posts have included what I call the mode-locking integral

\(\displaystyle\frac{1}{2\pi}\int_0^{2\pi}\frac{d\theta}{a+b\sin\theta}=\frac{1}{\sqrt{a^2-b^2}}\)

The text for this equation is LaTeX, not an image! Very exciting!

You might wonder why I named it the “mode-locking integral”. It comes from being the solution to the mode-locking equation

\(\dot{\Psi}(t)=a+b \sin{\Psi(t)}\)

where \(\Psi\) is the relative phase angle between oscillating modes. The modes can be oppositely running waves in a ring laser, the oscillations of two pendulum clocks near one another on a wall, two nearby tuning forks, etc. For more detailed descriptions, see Section 7.5 Mode Locking in the book *Elements of Quantum Optics*, by Pierre Meystre and yours truly. The variable 𝑎 is the frequency difference between the oscillating modes in the absence of coupling, and the variable 𝑏 is the coupling coefficient. If |𝑎| > |𝑏|, the integral is valid. When |𝑎| ≤ |𝑏|, \(\dot{\Psi}=0\), which has the solution \(\Psi=-\sin^{-1}{\frac{a}{b}}\), and the modes are locked to the same frequency.

The post Displaying Math in WordPress appeared first on Math in Office.

]]>The post Math Speech Strings and Localization appeared first on Math in Office.

]]>To localize the speech for Unicode characters, perform a binary search by character code in the math symbol speech table for the desired language. The table for English follows. Notably missing are speech strings for U+002D ‘–‘, U+2329 ‘〈’, and U+232A ‘〉’. Input routines replace these nonmathematical characters by the corresponding math symbols U+2212 ‘−‘, U+27E8 ‘⟨’, and U+27E9 ‘⟩’, respectively. The character names in the table don’t always agree with the names in the Unicode Standard. The latter names cannot be changed for stability reasons even if the names are suboptimal or incorrect for math.

! ( ) + / < = > @ [ ] { | } |
, (space: comma gives a small pause)
factorial open paren close paren plus over less than equals greater than , next row, open bracket close bracket open brace vertical bar close brace |
! ( ) + / < = > @ [ ] { | } |

00A6
00AC 00AF 00B0 00B1 00B7 00F7 0131 0237 |
, atop,
not overbar degrees plus or minus dot divided by dotless i dotless j |
¦
¬ ¯ ° ± · ÷ ı ȷ |

0300
0301 0302 0303 0305 0307 0308 |
grave
acute hat tilde bar dot double dot |
̀
́ ̂ ̃ ̅ ̇ ̈ |

03B1
03B2 03B3 03B4 03B5 03B6 03B7 03B8 03B9 03BA 03BB 03BC 03BD 03BE 03BF 03C0 03C1 03C2 03C3 03C4 03C5 03C6 03C7 03C8 03C9 03D1 03D5 03DC 03DD 03F5 |
alpha
beta gamma delta script epsilon zeta eta theta iota kappa lambda mu nu xi omicron pi rho final sigma sigma tau upsilon script phi chi psi omega script theta phi cap digamma digamma epsilon |
α
β γ δ ε ζ η θ ι κ λ μ ν ξ ο π ρ ς σ τ υ φ χ ψ ω ϑ ϕ Ϝ ϝ ϵ |

200B
2016 2026 2032 2044 2045 2046 2146 |
,
double vertical line dot dot dot prime slash , equation , differential d |
‖ … ′ ⁄ ⁅ ⁆ ⅆ |

2190
2191 2192 2193 2194 21D2 21D4 |
left arrow
up arrow goes to down arrow left right arrow implies if and only if |
←
↑ → ↓ ⇒ ⇔ |

2200
2201 2202 2203 2204 2205 2206 2207 2208 2209 220A 220B 220C 220D 220E 220F |
for all
complement partial there exists there doesn’t exist empty set increment dell element of not element of small element of contains as member doesn’t contain as member small contains as member q e d product |
∀
∁ ∂ ∃ ∄ ∅ ∆ ∇ ∈ ∉ ∊ ∋ ∌ ∍ ∎ ∏ |

2210
2211 2212 2213 2214 2215 2216 2217 2218 2219 221A 221B 221C 221D 221E 221F |
coproduct
sum minus minus or plus dot plus linear divide set minus asterisk operator ring operator bullet square root cube root fourth root proportional to infinity right angle |
∐
∑ − ∓ ∔ ∕ ∖ ∗ ∘ ∙ √ ∛ ∜ ∝ ∞ ∟ |

2220
2221 2222 2223 2224 2225 2226 2227 2228 2229 222A 222B 222C 222D 222E 222F |
angle
measured angle spherical angle divides doesn’t divide parallel to not parallel to logical andd logical or intersection union integral double integral triple integral contour integral surface integral |
∠
∡ ∢ ∣ ∤ ∥ ∦ ∧ ∨ ∩ ∪ ∫ ∬ ∭ ∮ ∯ |

2230
2231 2232 2233 2234 2235 2236 2237 2238 2239 223A 223B 223C 223D 223E 223F |
volume integral
clockwise integral clockwise contour integral anticlockwise contour integral therefore because ratio proportion dot minus excess geometric proportion homothetic tilde operator reverse tilde operator inverted lazy s sine wave |
∰
∱ ∲ ∳ ∴ ∵ ∶ ∷ ∸ ∹ ∺ ∻ ∼ ∽ ∾ ∿ |

2240
2241 2242 2243 2244 2245 2246 2247 2248 2249 224A 224B 224C 224D 224E 224F |
wreath product
not tilde minus tilde asymptotically equal to not asymptotically equal to approximately equal to approximately but not equal to neither approximately nor equal to almost equal to not almost equal to almost equal or equal to triple tilde all equal to equivalent to geometrically equivalent to difference between |
≀
≁ ≂ ≃ ≄ ≅ ≆ ≇ ≈ ≉ ≊ ≋ ≌ ≍ ≎ ≏ |

2250
2251 2252 2253 2254 2255 2256 2257 2258 2259 225A 225B 225C 225D 225E 225F |
approaches the limit
geometrically equal to nearly equals image of or approximately equal to colon equals equals colon, ring in equal to ring equal to corresponds to estimates equiangular to star equals delta equals equals by definition measured by questioned equals |
≐
≑ ≒ ≓ ≔ ≕ ≖ ≗ ≘ ≙ ≚ ≛ ≜ ≝ ≞ ≟ |

2260
2261 2262 2263 2264 2265 2266 2267 2268 2269 226A 226B 226C 226D 226E 226F |
not equal
identical to not identical to strictly equivalent to less than or equal to greater than or equal to less than over equal to greater than over equal to less than but not equal to greater than but not equal to much less than much greater than between not equivalent to not less than not greater than |
≠
≡ ≢ ≣ ≤ ≥ ≦ ≧ ≨ ≩ ≪ ≫ ≬ ≭ ≮ ≯ |

2270
2271 2272 2273 2274 2275 2276 2277 2278 2279 227A 227B 227C 227D 227E 227F |
not less than or equal
not greater than or equal less than or equivalent greater than or equivalent to neither less than nor equivalent to neither greater than nor equivalent to less than or greater than greater than or less than neither less than nor greater than neither greater than nor less than precedes succeeds precedes or equals succeeds or equals precedes or is equivalent to succeeds or is equivalent to |
≰
≱ ≲ ≳ ≴ ≵ ≶ ≷ ≸ ≹ ≺ ≻ ≼ ≽ ≾ ≿ |

2280
2281 2282 2283 2284 2285 2286 2287 2288 2289 228A 228B 228C 228D 228E 228F |
doesn’t precede
doesn’t succeed subset of superset of not subset of not superset of subset or equals superset or equals neither a subset nor equal to neither a superset nor equal to subset of with not equal to superset of with not equal to multiset multiset times multiset union square image of |
⊀
⊁ ⊂ ⊃ ⊄ ⊅ ⊆ ⊇ ⊈ ⊉ ⊊ ⊋ ⊌ ⊍ ⊎ ⊏ |

2290
2291 2292 2293 2294 2295 2296 2297 2298 2299 229A 229B 229C 229D 229E 229F |
square original of
square image of or equal to square original of or equal to square cap square cup circled plus circled minus circled times circled divide circled dot circled ring circled asterisk circled equals circled dash squared plus squared minus |
⊐
⊑ ⊒ ⊓ ⊔ ⊕ ⊖ ⊗ ⊘ ⊙ ⊚ ⊛ ⊜ ⊝ ⊞ ⊟ |

22A0
22A1 22A2 22A3 22A4 22A5 22A6 22A7 22A8 22A9 22AA 22AB 22AC 22AD 22AE 22AF |
squared times
squared dot right tack left tack down tack up tack reduces to models results in forces triple vertical bar right turnstile double vertical bar double right turnstile does not prove doesn’t result in doesn’t force negated double vertical bar double right turnstile |
⊠
⊡ ⊢ ⊣ ⊤ ⊥ ⊦ ⊧ ⊨ ⊩ ⊪ ⊫ ⊬ ⊭ ⊮ ⊯ |

22B0
22B1 22B2 22B3 22B4 22B5 22B6 22B7 22B8 22B9 22BA 22BB 22BC 22BD 22BE 22BF |
precedes under relation
succeeds under relation is a normal subgroup of contains as normal subgroup is a normal subgroup of – or equals contains as normal subgroup of or equals original of image of multimap hermeetian conjugate matrix intercalate xor nand nor right angle with arc right triangle |
⊰
⊱ ⊲ ⊳ ⊴ ⊵ ⊶ ⊷ ⊸ ⊹ ⊺ ⊻ ⊼ ⊽ ⊾ ⊿ |

22C0
22C1 22C2 22C3 22C4 22C5 22C6 22C7 22C8 22C9 22CA 22CB 22CC 22CD 22CE 22CF |
n-ary logical andd
n-ary logical or n-ary intersection n-ary union diamond dot star division times bowtie left normal factor semidirect product right normal factor semidirect product left semidirect product right semidirect product reverse tilde equals curly logical or curly logical andd |
⋀
⋁ ⋂ ⋃ ⋄ ⋅ ⋆ ⋇ ⋈ ⋉ ⋊ ⋋ ⋌ ⋍ ⋎ ⋏ |

22D0
22D1 22D2 22D3 22D4 22D5 22D6 22D7 22D8 22D9 22DA 22DB 22DC 22DD 22DE 22DF |
double subset
double superset double intersection double union pitchfork equal and parallel to dotted less than dotted greater than very much less than very much greater than less than equals or greater than greater than equals or less than equals or less than equals or greater than equals or precedes equals or succeeds |
⋐
⋑ ⋒ ⋓ ⋔ ⋕ ⋖ ⋗ ⋘ ⋙ ⋚ ⋛ ⋜ ⋝ ⋞ ⋟ |

22E0
22E1 22E2 22E3 22E4 22E5 22E6 22E7 22E8 22E9 22EA 22EB 22EC 22ED 22EE 22EF |
doesn’t precede or equal
doesn’t succeed or equal not square image of or equal to not square original of or equal to square image of or not equal to square original of or not equal to less than but not equivalent to greater than but not equivalent to precedes but not equivalent to succeeds but not equivalent to not normal subgroup of does not contain as normal subgroup not normal subgroup of or equal to does not contain as normal subgroup or = vertical ellipsis midline horizontal ellipsis |
⋠
⋡ ⋢ ⋣ ⋤ ⋥ ⋦ ⋧ ⋨ ⋩ ⋪ ⋫ ⋬ ⋭ ⋮ ⋯ |

22F0
22F1 22F2 22F3 22F4 22F5 22F6 22F7 22F8 22F9 22FA 22FB 22FC 22FD 22FE 22FF |
up right diagonal ellipsis
down right diagonal ellipsis element of with long horizontal stroke element of w vertical bar at end of stroke small element of w vertical bar at end of stroke dotted element of overbar element of small overbar element of underbar element of double stroke element of long-stroke contains contains w vertical bar at end of stroke small contains w vertical bar at end of stroke overbar contains small overbar contains z notation bag membership |
⋰
⋱ ⋲ ⋳ ⋴ ⋵ ⋶ ⋷ ⋸ ⋹ ⋺ ⋻ ⋼ ⋽ ⋾ ⋿ |

2308
2309 230A 230B 2329 232A 23B4 23B5 23DC 23DD 23DE 23DF 23E0 23E1 |
open ceiling
close ceiling open floor close floor open angle bracket close angle bracket over bracket under bracket over paren under paren over brace under brace over shell under shell |
⌈
⌉ ⌊ ⌋ 〈 〉 ⎴ ⎵ ⏜ ⏝ ⏞ ⏟ ⏠ ⏡ |

24AD
2502 252C 2534 2581 2588 2592 25A0 25AD 27E6 27E7 27E8 27E9 3016 3017 |
root (UnicodeMath)
vertical bar lower limit upper limit underbar equation array (UnicodeMath) of (UnicodeMath) matrix (UnicodeMath) boxed formula (UnicodeMath) open white square bracket close white square bracket open angle bracket close angle bracket , (UnicodeMath “begin”) , (UnicodeMath “end”) |
⒭
│ ┬ ┴ ▁ █ ▒ ■ ▭ ⟦ ⟧ ⟨ ⟩ 〖 〗 |

The index of a string in the following table can be used as a language token. These speech tokens can be used in a localized table to retrieve the corresponding strings in the localized language. OfficeMath supports about 18 languages this way. This approach doesn’t support speaking math in a different order than in English. The aim is to provide understandable speech even if it isn’t the most elegant.

Speech string |
Meaning |

accent
box boxed formula brackets brackets with separators equation array fraction function left sub superscript lower limit matrix n ary expression (null string place holder: no speech) overbar phantom root slashed fraction stack stretch stack subscript sub superscript superscript underbar upper limit |
First 24 entries are names of LineServices math objects and must be in the order of tomAccent..tomUpperLimit |

half, third, fourth, fifth, sixth, seventh, eighth, ninth, tenth, halves, thirds, fourths, fifths, sixths, sevenths, eighths, ninths, tenths | Ordinals. Used for simple fractions and nested parens |

cosine, cotangent, cosecant, secant, sine, tangent, arccosine, arccotangent, arccosecant, arcsecant, arcsine, arctangent | Trigonometric functions |

open paren, open second paren, open third paren, open fourth paren, open fifth paren, open sixth paren, open seventh paren, open eighth paren, open ninth paren, open tenth paren | Open parentheses |

close paren, close second paren, close third paren, close fourth paren, close fifth paren, close sixth paren, close seventh paren, close eighth paren, close ninth paren, close tenth paren | Close parentheses |

absolute value
argument a. smash base base text bold bold fraktur bold italic bold script by cap column cross cubed |
Lead in for absolute value object
Second arg of function object Kind of phantom object First arg of sub/superscript object Second argument of ruby object Math alphanumeric qualifier Math alphanumeric qualifier Math alphanumeric qualifier Math alphanumeric qualifier <row> “by” <column> matrix Upper-case modifier Part of “end column” x if followed by math bold Simple exponent |

degree
denominator determinant double-struck d smash element empty empty equation end end absolute value end equation equation fraktur from function name |
Radical degree
Lead in for compound denom Determinant object Math alphanumeric qualifier Kind of phantom object Matrix element Empty argument Empty equation (math zone) Verb to end object or argument End compound absolute value End equation (math zone) E.g., in “end equation” Math alphanumeric qualifier Lower limit lead in if upper limit First argument of function object |

h smash
horizontal phantom hyperbolic integral integrand inverse limit as lower element equation monospace numbered equation numerator over , phantom smash product quantity radicand ruby ruby text |
Kind of phantom object
Kind of phantom object Trig modifier Integral n-ary object Third argument for integral Trig modifier Lead words for lim function Name of lower element in stack Lead in for equation (math zone) Math alphanumeric qualifier Numbered equation Start of compound numerator Lower limit lead in; no upper limit Pause Kind of phantom object Product n-ary object End absolute value to a power Radical radicand Object with phonetic annotation Phonetic annotation text |

sans-serif
sans-serif bold sans-serif italic sans-serif bold italic squared script start sub summand summation to to the upper element upright vertical phantom with |
Math alphanumeric qualifier
Math alphanumeric qualifier Math alphanumeric qualifier Math alphanumeric qualifier Simple exponent Math alphanumeric qualifier Verb to start object or argument Subscript lead in Third argument of summation Summation n-ary object Lead in to n-ary upper limit Lead in to general superscript Name of upper element in stack Math alphanumeric qualifier Kind of phantom object As in “base” … “with” “upper limit” |

The post Math Speech Strings and Localization appeared first on Math in Office.

]]>The post Using RichEdit for Text Processing appeared first on Math in Office.

]]>The first thing is to load the RichEdit dll. You can use the system \windows\system32\msftedit.dll unless you need features that have been added more recently to the Office riched20.dll. One such dll is located on my laptop in C:\Program Files\Microsoft Office\root\vfs\ProgramFilesCommonX64\Microsoft Shared\OFFICE16\riched20.dll. Another is a recent Office RichEdit that the Windows 11 Notepad uses. On my laptop, its path is C:\Program Files\WindowsApps\Microsoft.WindowsNotepad_11.2210.5.0_x64__8wekyb3d8bbwe\riched20.dll. You can find the installation location via PowerShell:

**Get-AppxPackage | ?{ $_.Name.Contains(“Notepad”) } | %{ $_.InstallLocation }**

To load the dll, execute

HINSTANCE hRE = LoadLibrary(L"riched20.dll");

You may need to give the full path to the desired RichEdit dll. Note that the \windows\system32\riched20.dll is old and exists for backward compatibility with very old programs: it’s Version 3 from Windows 2000 and has been only updated for security fixes. It has no features added in this century, so it’s missing a lot of functionality!

A RichEdit control is an ITextServices2 object. To create it, query the RichEdit dll for the exported CreateTextServices() function:

PCreateTextServices pfnCreateTextServices = (PCreateTextServices)GetProcAddress(hRE, "CreateTextServices"); CNoShowHost noShowHost; // ITextHost object described below IUnknown *pUnk; HRESULT hr = pfnCreateTextServices(nullptr, &noShowHost, &pUnk); if (hr != NOERROR) return hr; ITextServices2* pserv; hr = pUnk->QueryInterface(IID_ITextServices2, (void **)&pserv); pUnk->Release(); if (hr != NOERROR) return hr; ITextDocument2* pdoc; hr = pserv->QueryInterface(IID_ITextDocument2, (void **)&pdoc) != S_OK); if (hr != NOERROR) return hr;

ITextServices2 inherits from ITextServices. The method ITextServices::TxSendMessage() lets you send messages to the RichEdit control, and the pdoc pointer is the top TOM2 interface that lets you use TOM methods for processing text. For example,

LRESULT lres; pserv->TxSendMessage(WM_SETTEXT, 0, reinterpret_cast<LPARAM>(szTextRtf), &lres);

inserts the RTF string szTextRtf into the control. You can also insert a Unicode string as the LPARAM.

An interesting case illustrating the TOM interfaces is finding a math formula in a document. Read in the RTF or HTML document and then search the document using the ITextRange2::Find() method. First, to get the user selection ITextSelection* from the pdoc pointer, execute

ITextSelection2* psel; pdoc->GetSelection2(&psel);

The math expression you want to find in the document should be in a separate RichEdit control with an ITextDocument2* pdocExpr pointer. Get an ITextRange2* from pdocExpr by executing

pdocExpr->Range2(0, tomForward, &pRangeExpr); pRangeExpr->MoveEnd(tomCharacter, -1, nullptr);

Here the MoveEnd() call unselects the final CR (all rich-text controls end with a final CR (U+000D)). Then to find the math expression selected by pRangeExpr and starting in the document where psel is pointing, call

LONG Delta; psel->Find(pRangeExpr, tomForward, Flags, &Delta);

Here the values for Flags are defined in ITextRange::FindText(), and Delta gets set to the count of characters found (if found). The search is “fuzzy”, that is, it ignores character format attributes like foreground/background color, font face name, and font height. But it distinguishes Unicode characters, so the following kinds of letters are all distinct 𝐻𝑯𝐇ℌℋ. And math objects like fractions, subscripts, superscripts, integrals, matrices, equation arrays, etc., are all distinct. This approach is more general than searching for MathML, LaTeX, RTF, HTML, OMML, UnicodeMath, etc., since it first converts these formats to OfficeMath and then does a fuzzy search on the resulting OfficeMath. For a more detailed description of the algorithm, see Math Find/Replace and Rich Text Searches.

A RichEdit control needs a host given by an implementation of ITextHost or ITextHost2. If no display is needed, ITextHost is adequate. Here’s a skeleton version of such a host. You can use it as is, or enhance it as desired.

class CNoShowHost : public ITextHost { // IUnknown methods STDMETHODIMP QueryInterface(REFIID, void **) noexcept {return E_NOTIMPL;} STDMETHODIMP_(ULONG) STDMETHODCALLTYPE AddRef(void) noexcept {return 1;} STDMETHODIMP_(ULONG) STDMETHODCALLTYPE Release(void) noexcept {return 1;} // ITextHost Methods HDC TxGetDC() {return nullptr;} INT TxReleaseDC(HDC) {return 0;} BOOL TxShowScrollBar(INT, BOOL) {return false;} BOOL TxEnableScrollBar(INT, INT) {return false;} BOOL TxSetScrollRange(INT, LONG, INT, BOOL) {return false;} BOOL TxSetScrollPos(INT, INT, BOOL) {return false;} void TxInvalidateRect(LPCRECT, BOOL) {} void TxViewChange(BOOL) {} BOOL TxCreateCaret(HBITMAP, INT, INT) {return false;} BOOL TxShowCaret(BOOL) {return false;} BOOL TxSetCaretPos(INT, INT) {return false;} BOOL TxSetTimer(UINT, UINT) {return false;} void TxKillTimer(UINT) {} void TxScrollWindowEx(INT, INT, LPCRECT, LPCRECT, HRGN, LPRECT, UINT) {} void TxSetCapture(BOOL) {} void TxSetFocus() {} void TxSetCursor(HCURSOR, BOOL) {} BOOL TxScreenToClient(LPPOINT) {return false;} BOOL TxClientToScreen(LPPOINT) {return false;} HRESULT TxActivate(LONG *) {return E_UNEXPECTED;} HRESULT TxDeactivate(LONG) {return E_UNEXPECTED;} HRESULT TxGetClientRect(LPRECT) {return E_UNEXPECTED;} HRESULT TxGetViewInset(LPRECT) {return E_UNEXPECTED;} HRESULT TxGetCharFormat(const CHARFORMATW **) {return E_UNEXPECTED;} HRESULT TxGetParaFormat(const PARAFORMAT **) {return E_UNEXPECTED;} COLORREF TxGetSysColor(int) {return 0;} HRESULT TxGetBackStyle(TXTBACKSTYLE *) {return E_UNEXPECTED;} HRESULT TxGetMaxLength(DWORD *) {return S_OK;} HRESULT TxGetScrollBars(DWORD *) {return E_UNEXPECTED;} HRESULT TxGetPasswordChar(_Out_ WCHAR *) {return E_UNEXPECTED;} HRESULT TxGetAcceleratorPos(LONG *) {return E_UNEXPECTED;} HRESULT TxGetExtent(LPSIZEL) {return E_UNEXPECTED;} HRESULT OnTxCharFormatChange(const CHARFORMATW *) {return E_UNEXPECTED;} HRESULT OnTxParaFormatChange(const PARAFORMAT *) {return E_UNEXPECTED;} HRESULT TxGetPropertyBits(DWORD /* dwMask */, DWORD *pdwBits) {*pdwBits = TXTBIT_RICHTEXT | TXTBIT_MULTILINE; return S_OK;} HRESULT TxNotify(DWORD, void *) {return E_UNEXPECTED;} HIMC TxImmGetContext() {return nullptr;} void TxImmReleaseContext(HIMC) {} HRESULT TxGetSelectionBarWidth(LONG *) {return E_UNEXPECTED;}

The post Using RichEdit for Text Processing appeared first on Math in Office.

]]>The post Default Math Properties appeared first on Math in Office.

]]>You can change the default settings to suit your tastes or a publisher’s conventions. In the math ribbon (type Alt+= to insert a math zone and select the math ribbon tab), click on the Tools button over toward the left side of the ribbon. A dialog will be displayed that shows a variety of math properties along with buttons to access the math autocorrect and recognized-function dialogs.

The document default math properties in this dialog are described in a somewhat technical way in the math section of the RTF specification. The properties belong to the RTF {\mmathPr…} group. They are also children of the <mathPr> OMML element. In this post, I describe the properties in a less technical way. For easy reference to the RTF specification, the relevant RTF control word is listed in parentheses along with the corresponding ITextDocument property values. The dialog also has some options that are not document default math properties, such as “Copy MathML to the clipboard as plain text” instead of “Copy Linear Format to the clipboard as plain text.” Such options do not affect the layout of a document and hence are stored in the system registry rather than in the document.

The Word Equation/Conversions dialog gives a drop-down list of math fonts that can be used as the default math font for the document. Cambria Math and STIX Two Math MS are examples of math fonts. (RTF: \mmathFont*N*)

Specifies that nested fractions should be displayed such that the numerator and denominator are written in a script or script-script size instead of regular-text size. Specifically, characters in the outermost fraction’s numerator and denominator are displayed using the full text size, characters in a nested fraction are displayed in the script size (about 70% as large as the text size), and fractions nested inside a nested fraction are displayed in scriptscript size (about 60% as large as the text size). TeX uses this “small fraction” choice by default, but Word 2007 does not, basically because in all the physics books I’ve read I don’t remember seeing reduced sizes used in display math. But if you prefer them, you can change them. For in-line math expressions, small fractions are used. (RTF: \msmallFrac*N*; SetMathProperty—tomMathDispFracTeX)

By default, a line break occurs before the binary operator. That is, the binary operator is the first control word on the wrapped line. But you can change it so that a line break occurs after the operator (tomMathBrkBinAfter), or so that the operator is duplicated (tomMathBrkBinDup), that is, it appears at the end of the first line and at the start of the second. (RTF: \mbrkBin*N*; SetMathProperty)

If the minus operator (U+2212) coincides with a line break, by default the minus appears after the line break. But it can appear before and after the break (tomMathBrkBinSubMM) or a plus before the break and a minus after the break (tomMathBrkBinSubPM), or vice versa (tomMathBrkBinSubMP). (RTF: \mbrkBinSub*N*; SetMathProperty)

Limits of integrals in display-mode equations can be either centered above and below the integral or positioned just to the right of the integral. The default setting is to position the limits to the right of the operator (subscript/superscript). (RTF: \mintLim*N*; SetMathProperties—tomMathDispIntUnderOver)

Limits of summations, products, and other *n*-ary operators can be either centered above and below the *n*-ary operator, or positioned just to the right of the operator. The default setting is above and below the operator. (RTF: \mnaryLim*N*; SetMathProperties—tomMathDispNarySubSup)

In the United States, the differential d (ⅆ – U+2146) is almost always displayed as a math italic d, but in Europe, an upright d is standard. The latter choice emphasizes that the differential d is different from regular mathematical variables. Similarly, the Napierian logarithm base ⅇ (U+2147) and the imaginary unit ⅈ (square root of -1, U+2148) are displayed as math italic in the United States and upright in Europe. (RTF: \mdispDef*N*; SetMathProperties—tomMathDocDiffDefault, tomMathDocDiffUpright, tomMathDocDiffItalic, tomMathDocDiffOpenItalic).

Math object arguments may be optional, e.g., integral limits, or essential, e.g., numerator or denominator. To control what is displayed for empty arguments there are three possibilities: tomMathDocEmptyArgAuto, tomMathDocEmptyArgAlways (display ⬚), and tomMathDocEmptyArgNever. The first of these doesn’t display anything for optional arguments unless you use the arrow keys to move into the argument, at which point the ⬚ is displayed and you can enter math text. This setting is controlled by SetMathProperties() and isn’t persisted since it’s a UI property, not a document property. Note that if tomMathDocEmptyArgAlways is active, you can still display nothing by entering a zero-width space (U+200B).

Document properties to use the default math paragraph settings for equations, i.e., use values given by \mlMargin*N*, \mrMargin*N*, \mdefJc*N*, \mwrapIndent*N*, \mwrapRight*N*, etc., defined below. The default is to use the default math settings described below, but you can change it to use the text paragraph settings. (RTF: \mdispDef*N*; SetMathProperties—tomMathDispDef)

Document property for the left margin for math. Math margins are added to the paragraph settings for margins. (RTF: \mlMargin*N*; SetProperty—tomMathLMargin)

Right margin for math. (RTF: \mrMargin*N*; SetProperty—tomMathRMargin))

Document property for the default justification of displayed math zones. Individual equations can overrule the default setting. Displayed math zones can be left justified, right justified, centered, or centered as a group. When a displayed math zone is centered as a group, the equation(s) are ordinarily left aligned within a block, and the entire block is centered with respect to column margins. The user can use a context menu to align equations in more general ways, e.g., on the equal signs. (RTF: \mdefJc*N*; SetMathProperties—tomMathParaAlignCenterGroup, tomMathParaAlignCenter, tomMathParaAlignLeft, tomMathParaAlignRight)

Indent of wrapped line of an equation. The line or lines of a wrapped equation after the line break can either be indented by a specified amount from the left margin, or right-aligned. The default indent is 1”. (RTF: \mwrapIndent*N*; SetProperty—tomMathWrapIndent)

If enabled, right justify wrapped lines of an equation. If disabled, the line or lines of a wrapped equation after the line break are indented by **\mwrapIndent N** from the left margin. (RTF: \mwrapRight

(RTF: \mpreSp*N*; SetProperty—tomMathPreSpace).

(\RTF: mintraSp*N*; SetProperty—tomMathPostSpace).

(RTF: \minterSp*N*; SetProperty—tomMathIntraSpace).

(RTF: \mpostSp*N*; SetProperty—tomMathInterSpace).

The property tomMathZoneSurround (RTF: \mzSurround) inserts the spacing given by Value before and after math zones.

The Value argument for the property tomDocMathBuild can consist of any combination of the flags tomMathAutoCorrect, tomTeX, and tomMathAlphabetics. The flag tomMathAutoCorrect autocorrects using entries in the built-in math autocorrection list, which includes most standard TeX control words. The flag tomTeX uses [La]TeX build-up/down rules instead of UnicodeMath rules. The flag tomMathAlphabetics converts ASCII and lower-case Greek letters to math italic, math bold, and math bold-italic characters according to the UI bold and italic font settings. These values are used by math UI but are not persisted in file formats.

If a line break occurs at the invisible times (U+2063), ordinarily one would use the \times (× U+00D7) for a visible times character, but a raised dot is another possibility. This document property isn’t currently implemented.

MathML 4 introduces a new attribute called “intent”. This attribute allows you to disambiguate math notation. For example, it lets you specify whether a superscript is a power or an index. To reduce the number of places the intent attribute is needed, there is a set of document default intent values. With them, you only need the intent attribute when the instance differs from the default values.

Currently, MathML doesn’t formalize document defaults for math, but MathML math zones can inherit them from the host container, e.g., from HTML5. Such defaults are compatible with MathML and need to be stored outside the individual MathML <math> elements. In principle, MathML could have a new element <mdefaults> that contains the default properties. The container document would need to recognize this element and use the properties it contains. Making this a MathML element seems desirable since MathML is responsible for the needs of mathematics.

The post Default Math Properties appeared first on Math in Office.

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

]]>The first autoURLs appeared in RichEdit 2.0, which shipped with Office 97, and have the usual web form, such as, http://www.msn.com. The permitted URL schemes were http:, file:, mailto:, ftp:, https:, gopher:, nntp:, prosper:, telnet:, news:, wais:, and outlook:. To include spaces in the URL, the whole URL had to be enclosed in an angle bracket pair as in <http://www.xxx.com/fun computing>. RichEdit 3.0, which shipped with Windows 2000 up through Windows 7, added the capability to recognize URLs of the form www.msn.com and ftp.unicode.org. RichEdit 4.1, which shipped with Windows XP up through Windows 7, added friendly name hyperlinks as well as autoURLs of the form \\word\richedit2\murrays. RichEdit 7, which shipped with Office 2010, added recognition for spaces in URLs without needing enclosure in <>. It also added recognition of telephone numbers, drive-letter paths, email addresses, and URLs enclosed in ASCII double quotes “”. It made all of these recognitions optional, since you might not want to recognize, for example, phone numbers, or you might want to recognize telephone numbers exclusively.

The recognition is dynamic, fast, and displayed by default with underline and a blue text color. The autoURL notifications can be sent to the client application by user actions such as typing the Enter key or clicking the left mouse button.

To enable or disable recognition of URLs and file paths in a RichEdit control, send the control the message EM_AUTOURLDETECT with lparam = 0 and wparam = 1 or 0, respectively. When autoURL recognition and link notifications are enabled, mouse movement over a link or clicking on a link sends an EN_LINK notification with the URL start and end character positions to the client.

More generally, wparam can have any combination of the following flags:

AURL_ENABLEURL | 1 | Recognize standard web URLs and file paths |

AURL_ENABLEEMAILADDR | 2 | Recognize email addresses |

AURL_ENABLETELNO | 4 | Recognize telephone numbers |

AURL_ENABLEEAURLS | 8 | Recognize East Asian URLs |

AURL_ENABLEDRIVELETTERS | 16 | Recognize file paths that start with a drive letter |

AURL_DISABLEMIXEDLGC | 32 | Disable mixed Latin Greek Cyrillic IDNs |

AURL_DISABLEAUTOFORMAT | 64 | Disable auto URL formatting |

AURL_URLRTFHTMLSTRICT | 128 | Only encode URLs defined in RTF/HTML source |

AURL_NOINITIALSCAN | 256 | Don’t scan doc when enabling autoURL reco |

AURL_ENABLEGETURL | 512 | Make ITextRange2::GetURL() return autoURLs |

AURL_ENABLEEAURLS is a preferred way to enabling East Asian URL recognition. For compatibility with older software, lparam = 1 also enables East Asian URL recognition. But lparam can be used instead to point to a client null-terminated string specifying URL scheme protocols. The string consists of URI scheme names each terminated by a ‘:’. See https://www.ietf.org/rfc/rfc2396.txt for validation criteria. The default string is “:callto:file:ftp:gopher:http:https:mailto:news:nntp:notes:onenote:outlook:prospero:read:tel:telnet:wais:webcal:”. The message EM_GETAUTOURLDETECT (WM_USER + 92) gets the flags, but not the scheme string.

In memory, autoURLs are identified by the CFE_LINK character formatting attribute. You can retrieve this attribute using the EM_GETCHARFORMAT or ITextFont2::GetEffects(). Alternatively, you can use tomLink unit in the TOM (Text Object Model) ITextRange::StartOf(), EndOf(), Expand(), Move(), MoveEnd(), and MoveStart() methods to navigate and select autoURLs and friendly-name links as well. ITextFont2::SetEffects(Value, Mask) with Value = 0 and Mask = CFM_LINK turns off autoURL detection for the range associated with the ITextFont2 (sets the link type to tomNoAutoLink) provided AURL_URLRTFHTMLSTRICT is active.

A friendly-name hyperlink has a name, which is displayed, and a hidden instruction part that contains the URL. Such hyperlinks are commonly used when an author wants to display an informative name for a link rather than the URL itself. It can be hard to read URLs these days what with all the protection built into them. So, friendly-name URLs are much nicer

A friendly name hyperlink is essentially a field with two parts: an instruction part containing the URL and a result part containing the name. In fact that’s the way it appears in RTF, which has the syntax {\field{\*\fldinst {HYPERLINK “…”}}{\fldresult{…}}} and in HTML with <a href=”*url*”>*name*</a>.

In RichEdit, a hyperlink is represented by character formatting effects, unlike by the delimiters used for math and other in-line objects. As such, hyperlinks cannot be nested, although friendly-name hyperlinks can be located next to one another. In contrast, autoURLs need to be separated by at least one character. The whole friendly-name hyperlink has the character formatting effects of CFE_LINK and CFE_LINKPROTECTED, whereas autoURLs only have the CFE_LINK attribute. The CFE_LINKPROTECTED is included so that the autoURL scanner skips over friendly-name links. The instruction part, i.e., the URL, has the CFE_HIDDEN attribute as well, since it’s not supposed to be displayed. The URL itself is enclosed in ASCII double quotes and preceded by the string “HYPERLINK “. Since CFE_HIDDEN plays an integral role in friendly-name hyperlinks, it cannot be used in the name.

For example, in WordPad, which uses RichEdit, a hyperlink with the name MSN would have the plain text

HYPERLINK “http://www.msn.com”MSN

The whole link would have CFE_LINK and CFE_LINKPROTECTED character formatting attributes and all but the “MSN” would have the CFE_HIDDEN attribute.

You can insert a friendly-name hyperlink by reading in the corresponding RTF or by sending the RTF in a WM_SETTEXT or EM_SETTEXTEX message. For the example above, the RTF could be

{\rtf1{\field{\*\fldinst{ HYPERLINK “http://www.msn.com”}}{\fldresult{MSN}}}}.

Note that if you encode a path name in the fldinst part, each backslash has to be doubled. In a C++ string, this means each backslash has to be quadrupled.

If the friendly name is the same as the URL, the link is converted to an autoURL unless the autoURL recognizer fails to recognize the URL completely. The reason for this conversion is so that the user can edit the URL and have it be the same as what gets launched when the user clicks on the URL. In Word, you can change the friendly name without updating the URL, which can be misleading in this case. The problem is mitigated in Word since Word has an edit-link dialog that shows both the URL and the friendly name. RichEdit is a component and doesn’t have dialogs, so it’s more secure to convert such links to autoURLs.

Using RTF to insert links works well, but there are also programmatic approaches. The ITextRange2:: SetURL (BSTR bstr) method applies the URL in the bstr to the range of text selected by the ITextRange2. The text in the bstr needs to start and end with ASCII double quotes. The SetURL() method inserts the word “HYPERLINK” in front of the URL. You can remove the link status from a friendly name hyperlink by calling SetURL() with a NULL bstr or one that has only the start and end quotes, signifying an empty string.

To retrieve the URL, select it and then call ITextRange2::GetURL(&bstr). That way the bstr doesn’t have HYPERLINK and quotes. To get the friendly name, use ITextRange2::GetText2(tomNoHidden, &bstr). Then the client can insert whatever surround characters it desires. If you call GetURL() for a URL like www.msn.com, it returns http://www.msn.com (assuming you have included the AURL_ENABLEGETURL flag in your EM_AUTOURLDETECT message).

As for autoURLs, the RichEdit client enables hyperlink notifications (EN_LINK) by sending RichEdit the ENM_LINK flag in the mask included with the EM_SETEVENTMASK message. The client can enable tooltips displaying the URLs by sending the EM_SETEDITSTYLE message with the SES_HYPERLINKTOOLTIPS (8) flag.

To find out what kind of link a range is in or selects, get an ITextFont2 from the range (call ITextRange2::GetFont2(ppFont)) and then call ITextFont2::GetLinkType. The value returned has the following semantics

tomNoLink | 0 | Not any kind of link |

tomClientLink | 1 | Client link |

tomFriendlyLinkName | 2 | Friendly name of a friendly-name link |

tomFriendlyLinkAddress | 3 | Address of a friendly-name link |

tomAutoLinkURL | 4 | Auto URL |

tomAutoLinkEmail | 5 | Email address |

tomAutoLinkPhone | 6 | Phone number |

tomAutoLinkPath | 7 | File path |

tomNoAutoLink | 15 | Auto link recognition suppressed |

If you only select part of the friendly name, the URL isn’t included. If you select the whole friendly name, the URL is included. If you select from inside the friendly name up through a character outside the friendly name, the whole link is selected along with whatever is selected outside the link

Consider the friendly hyperlink for the text “Hello” pointing to the URL “http://www.hello.com”. It has the following dispatch behavior:

- If the cursor is in the middle of the word “Hello” (say between “He” or “el” or “ll” or “lo”) and you hit Enter, an EN_LINK notification is sent and the client launches the link.
- However if the cursor precedes the “H” or follows the “o”, no EN_LINK notification is sent and an end of paragraph is inserted.

Word has the same behavior for the Enter key. The problem is that the Enter key is also used for inserting a paragraph break. So in these edge cases, a choice had to be made and the usual meaning of Enter prevailed. If there’s pointer access to a link, e.g., mouse or touch, the hyperlink can be launched easily that way.

The post RichEdit Hyperlinks appeared first on Math in Office.

]]>The post Setting and Getting Text in Various Formats appeared first on Math in Office.

]]>Option |
Value |
s/g |
Meaning |

tomUnicodeBiDi | 0x00000001 | s | Use Unicode BiDi algorithm for inserted text |

tomAdjustCRLF | 0x00000001 | g | If range start is inside multicode unit like CRLF, surrogate pair, etc., move to start of unit |

tomUseCRLF | 0x00000002 | g | Paragraph ends use CRLF (U+000D U+000A) |

tomTextize | 0x00000004 | g | Embedded objects export alt text; else U+FFFC |

tomAllowFinalEOP | 0x00000008 | g | If range includes final EOP, export it; else don’t |

tomUnlink | 0x00000008 | s | Disables link attributes if present |

tomUnhide | 0x00000010 | s | Disables hidden attribute if present |

tomFoldMathAlpha | 0x00000010 | g | Replace math alphanumerics with ASCII/Greek |

tomIncludeNumbering | 0x00000040 | g | Lists include bullets/numbering |

tomCheckTextLimit | 0x00000020 | s | Only insert up to text limit |

tomDontSelectText | 0x00000040 | s | After insertion, call Collapse(tomEnd) |

tomTranslateTableCell | 0x00000080 | g | Export spaces for table delimiters |

tomNoMathZoneBrackets | 0x00000100 | g | Used with tomConvertUnicodeMath and tomConvertTeX. Set discards math zone brackets |

tomLanguageTag | 0x00001000 | s/g | Sets BCP-47 language tag for range; gets tag |

tomConvertRTF | 0x00002000 | s/g | Set or get RTF |

tomGetTextForSpell | 0x00008000 | g | Export spaces for hidden/math text, table delims |

tomConvertMathML | 0x00010000 | s/g | Set or get MathML |

tomGetUtf16 | 0x00020000 | g | Causes tomConvertRTF, etc. to get UTF-16. SetText2 accepts 8-bit or 16-bit RTF |

tomConvertLinearFormat | 0x00040000 | s/g | Alias for tomConvertUnicodeMath |

tomConvertUnicodeMath | 0x00040000 | s/g | UnicodeMath |

tomConvertOMML | 0x00080000 | s/g | Office MathML |

tomConvertMask | 0x00F00000 | s/g | Mask for mutually exclusive modes |

tomConvertRuby | 0x00100000 | s | See section below on Entering Ruby Text |

tomConvertTeX | 0x00200000 | s/g | See LaTeX Math in Office |

tomConvertMathSpeech | 0x00300000 | g | Math speech (English only here) |

tomConvertSpeechTokens | 0x00400000 | g | Simple Unicode and speech tokens |

tomConvertNemeth | 0x00500000 | s/g | Nemeth math braille in U+2800 block |

tomConvertNemethAscii | 0x00600000 | g | Corresponding ASCII braille |

tomConvertNemethNoItalic | 0x00700000 | g | Nemeth braille in U+2800 block w/o math italic |

tomConvertNemethDefinition | 0x00800000 | g | Fine-grained speech in braille |

tomConvertHtml | 0x00900000 | s/g | Convert HTML |

tomConvertEnclose | 0x00A00000 | s | See section below on Entering Enclosed Text |

tomConvertCRtoLF | 0x01000000 | g | Plain-text paragraphs end with LF, not CRLF |

tomLaTeXDelim | 0x02000000 | g | Use LaTeX math-zone delimiters \(…\) inline, \[…\] display; else $…$, $$…$$. Set handles all |

tomGhostText | 0x04000000 | s | Set ghost text (used for text prediction) |

tomNoGhostText | 0x04000000 | g | Get text without ghost text |

Nonzero values within the mask defined by tomConvertMask (0x00F00000) are mutually exclusive, that is, they cannot be combined (OR’d) with one another. The options UnicodeMath, [La]TeX (tomConvertTeX), and Nemeth math braille (tomConvertNemeth) are also mutually exclusive. You can set only one at a time. But other options can be OR’d in if desired.

A string of Nemeth math braille codes in the Unicode range U+2800..U+283F can be inserted and built up by calling ITextRange2::SetText2(tomConvertNemeth, bstr). If the string is valid, you can get it back in any of the math formats including Nemeth math braille. For example, if you insert the string

⠹⠂⠌⠆⠨⠏⠼⠮⠰⠴⠘⠆⠨⠏⠐⠹⠨⠈⠈⠙⠨⠹⠌⠁⠬⠃⠀⠎⠊⠝⠀⠨⠹⠼⠀⠨⠅⠀⠹⠂⠌⠜⠁⠘⠆⠐⠤⠃⠘⠆⠐⠻⠼

you see

You can also input braille with a standard keyboard by typing a control word \braille assigned to the Unicode character U+24B7 (Ⓑ). (See LaTeX Math in Office for how to add commands to math autocorrect). The \braille command causes math input to accept braille input via a regular keyboard using the braille ASCII codes sometimes referred to as North American Braille Computer Codes. The character ~ (U+007E) disables this input mode. These braille codes are described in the post Nemeth Braille—the first math linear format and can be input using refreshable braille displays. Alternatively, such input can be automated by calling ITextSelection::TypeText(bstr). Just as in entering UnicodeMath, the equations build up on screen as soon as the math braille input becomes unambiguous. The implementation includes the math braille UI that cues the user where the insertion point is for unambiguous editing of math zones using braille. Note that as of this posting, the math braille facility isn’t hooked up to Narrator or other screen readers.

The tomConvertMathSpeech currently only gets math speech in English. Microsoft Office apps like Word, PowerPoint and OneNote deliver math speech in over 18 languages to the assistive technology (AT) program Narrator via the UIA ITextRangeProvider::GetText() function. Other ATs could also get math speech this way, although they usually get MathML and generate speech from that. Dictating (setting) math speech would be nice for both blind and sighted folks. Imagine, you can say 𝑎² + 𝑏² = 𝑐² faster than you can type it or write it! The SetText2(tomConvertMathSpeech, bstr) is ready to handle such input, but the feature is not available yet.

In a nonmath context, the option, tomConvertRuby (0x00100000), can be used to convert strings like “{…|…}” to ruby inline objects, where the first ellipsis represents the ruby text and the second ellipsis the base text. The ASCII curly braces and vertical bar are translated to the internal ruby-object structure characters U+FDD1, U+FDEF, and U+FDEE, respectively. Alternatively, the string can contain those structure characters directly. If a digit follows the start delimiter (‘{‘ or U+FDD1}, the digit defines the ruby options

rubyAlign val |
Meaning |

center (0) | Center <ruby> with respect to <base> |

distributeLetter (1) | Distribute difference in space between longer and shorter text in the latter, evenly between each character |

distributeSpace (2) | Distribute difference in space between longer and shorter text in the latter using a ratio of 1:2:1 which corresponds to lead : inter-character : end |

left (3) | Align <ruby> with the left of <base> |

right (4) | Align <ruby> with the right of <base> |

If you add 5 to these values, the ruby object will display the ruby text below the base text instead of above it. For example, calling ITextRange2::SetText2(tomConvertRuby, bstr) with bstr containing the string “{1にほんご|日本語}” inserts

The string can contain text in addition to ruby objects and the ruby objects can be nested to create compound ruby objects such as

The post Rounded Rectangles and Ellipses – Math in Office (microsoft.com) describes ways to enclose text in possibly rounded rectangles and ellipses. The SetText2(tomConvertEnclose, bstr) option is similar to the tomConvertRuby option. It converts strings like “{…}” to a tomEnclose object.

In addition to the ITextRange2::SetText2/GetText2(), the messages WM_SETTEXT, EM_SETTEXTEX, WM_GETTEXT, and EM_GETTEXTEX are useful. The set-text messages work with plain text or RTF in rich-text controls. EM_SETTEXTEX accepts both 16-bit RTF as well as 8-bit RTF, while WM_SETTEXT doesn’t handle 16-bit RTF.

The post Setting and Getting Text in Various Formats appeared first on Math in Office.

]]>The post Computers I have known appeared first on Math in Office.

]]>The first computer I ever used was an Electronics Associates analog computer at the Perkin Elmer Corporation where I worked as an intern in the summers of 1961—1963. I wired up the machines to simulate aspects of the response of control systems that guided the balloon-borne Stratoscope II telescope. The telescope could be pointed to an accuracy of 0.1 arc seconds, which is the angle subtended by a dime at two miles. During my third summer, I saw an LGP-30 digital drum computer. One weekend I wanted to see what was going on, so I pushed a button that printed out the progress. That action apparently wrecked the whole weekend run much to the frustration of Bob Bernard who ran the machines and called me a button pusher. The LGP-30 was hardly more powerful than the analog computers, although it was suited to solving different problems. The drum had considerable latency, so programs had to be written carefully to catch the magnetized bits optimally. Unlike other computers of the day which used octal, the LGP-30 used hexadecimal with f g j k q w representing 10_{10} – 15_{10} instead of A B C D E F.

The following year I was a physics graduate student at Yale and learned how to program Fortran II on an IBM 709 computer. That computer used vacuum tubes and had 32768 36-bit words which could handle 6 characters in the BCD character set (0-9 A-Z +-.,()$*). Input was on IBM computer cards and output was on a printer or on a pen-and-ink plotter. We prepared our card decks with IBM 026 and later 029 keypunches. With the 029, you could insert a character by holding the source card and typing a character. In 1964, the Yale Computer Center upgraded to Fortran IV and an IBM 7094 computer which was made with discreet transistors, had a 2-microsecond machine cycle, and the same memory architecture as the IBM 709. Since compilations took appreciable time, I used to make simple changes in the binary cards using a keypunch. You had to kill the card check sum before resubmitting the card deck. You could punch more holes or fill up holes with chads that had been punched out. Amazingly the filled-in holes passed through the card reader without falling out. I learned enough assembly language to understand the machine-language 1’s and 0’s. I used the computer for calculating graphs in my PhD dissertation and papers on Zeeman laser theory. The Yale Computer Center also had an IBM 1401 computer with tape drives and an IBM 1620 computer which was a decimal machine. I didn’t use either except to read/write magnetic tapes.

One need for magnetic tape was to collect data for a Stromberg Carlson SC4020 Microfilm Printer & Plotter located at Bell Labs in Murray Hill, NJ. Marlan Scully, Willis Lamb, and I made what was likely the first computer movie (*Build up of laser radiation from spontaneous emission*) in 1965. You can see the movie by thumbing through the corners of Applied Optics circa 1970.

After finishing my PhD in June 1967, I went to Bell Labs in Holmdel, NJ to work as a post doc on laser theory. Bell Labs had an IBM 360 65, which used 8-bit bytes, EBCDIC character codes, and zipped along at 563 kips. The 7-bit ASCII character encoding came out in 1963, but I didn’t get to use it until 1973 on a DEC 10. Both character code standards have lower case, although Fortran IV was all upper case. The card decks required some JCL (job control language) which was sort of awkward and not used on later computers. After a year, I developed the SCROLL math display language and implemented it in Fortran IV. SCROLL was the first facility that formatted and displayed built-up equations on a computer. The notation was Polish prefix.

At the end of my two-year post doc, I was torn between joining the computer science department at Bell Labs in Murray Hill, NJ, and becoming an Assistant Professor of Optical Sciences at the University of Arizona. I went to the latter partly because Marlan, Willis, and I wanted to write a book on Laser Physics. The U of A had a CDC 6400 with 60-bit words, an 18-bit address space, 1 mips, and magically no JCL!

I found out about a special-projects program on computers hosted by the U of A Electrical Engineering department and volunteered to teach a course on comparative programming languages. After a year or so, I concluded that it would be good to formalize the program into a department of its own. I called Ralph Griswold, a Bell Labs colleague, and asked him if he’d be interested in such an endeavor. It was perfect timing. He had been interested in a change and creating a computer science department in an exotic location was compelling. See 50 Years of Computer Science 1971–2021.

Soon we had a Digital Equipment DEC 10 time-shared computer! You could dial in with a 110-baud teletype terminal, or better yet with a 300-baud CRT terminal. I never could abide 110 baud, but I used 300-baud connections for a while. Then I got access to a Tektronix 4010 graphics terminal which sped along at 9600 baud. That could fill up a 24-row screen in a mere second! And you could graph formulas on it. The DEC 10 had 36-bit words and an 18-bit address space. It also had an extended addressing capability consisting of multiple segments of 18-bit address spaces. A similar segment-offset architecture was used later in the Intel 286 microprocessor.

I spent 1975—1976 on sabbatical at the University of Stuttgart and the Max Planck Institute for Solid State Research and learned many things, one of which was that something called a microprocessor was being used in fledgling computers. On December 24, 1976, I bought for $2500 and assembled an IMSAI 8080 microcomputer kit. It had a whopping 48 KB thanks to a dynamic RAM card that one of my physics colleagues said would never be reliable. “Stick with the robust 8 KB static memory cards!” he urged. The IMSAI was like the Altair 8800 that Bill Gates wrote his famous 4K and 8K Basic interpreters on. The 4-MHz Zilog Z80 microprocessor was considerably more powerful than the 2-MHz Intel 8080, so I installed a Z80 processor card in the microcomputer’s S-100 bus. The IMSAI-8080 front panel has 22 switches and many LEDs. I rewired the front panel so that the 8 status LEDs could be controlled by software and set them up to display the contents of the memory byte pointed to by the address switches. I custom wire-wrapped most of the cards in the computer. There was a ROM with a 2 KB monitor program that let you examine and change memory. That program was the start for what evolved into my SST debugger. I added a CRT terminal, a modem, a floppy-disk drive, and a board with programmable relays to control the house lights and the front-door keypad. A friend who worked at a garage-door opener company down in Nogales, Sonora, gave me some garage-door openers that we used to control the house lights and the front door. A far cry from today’s smart phones! The whole system was hard wired since WiFi didn’t exist back in the 1970’s. One advantage of that was that it couldn’t be hacked (until I opened it up to remote control via modem). There were manual overrides for all functionality since I didn’t really trust computers! All programming was in tight Z80 assembly language.

64 KB sounds miniscule by today’s standards with our gigabytes and terabytes and subnanosecond machine cycles. But it was impressive how much we could do with so little. In addition to writing and printing books and papers, we could control experiments. A nifty example was Rick’s measurements of photon echo. For that, you subject a medium to two pulses of light separated by a time interval of *τ *and then watch for a light echo a time *τ* afterwards. But the experimental apparatus was very noisy, so the echo was drowned out if you only measured it once. If you measure it many times and add the results, the noise averages out to an overall flat background and the echo appears on top. But who wants to measure something thousands of times? Enter a microcomputer, which was happy to sit there and do so!

I got a Diablo daisy-wheel printer and wrote a program to send the printer proportionally spaced text. I used this approach to create the camera-ready pages of Rick Shoemaker’s and my first microcomputer book Interfacing Microcomputers to the Real World. That book describes the state of microcomputing at the time in detail. I enhanced the print program to handle mathematical text in multiple fonts using algorithms like those for the SCROLL language. Another physicist, Mike Aronson, who had written the PMATE editor I was using, suggested that the input format should resemble real linearized math as in the C language rather than the Polish prefix format used in SCROLL. So I wrote a translator to accept a simplified linear format, the forerunner of UnicodeMath which we use in Microsoft Office apps today. The translator was coded so tightly in Z80 assembly language that it along with the rest of the formatter fit into 16KB of ROM for a controller some friends of mine created for Diablo daisy-wheel printers. Those friends had also made the Z80 processor card in my IMSAI. When the printer was used with a tractor feed, it could print the whole document with one daisy, roll the document back, print with the next daisy, etc. It was positively wild watching the printer type the symbols into place after printing the main text.

In August 1981, IBM released a cool microcomputer that really surprised Rick and me. We figured that IBM wouldn’t get into microcomputing because it wouldn’t understand the market. IBM was into big machines, wrote its own software, supported a fancy sales force, had proprietary hardware, and didn’t collaborate with other companies. But the IBM PC was developed by a small independent group under Don Estridge in IBM Boca Raton, FL, that espoused open architecture and non-proprietary components and software. It used a 16-bit Intel microprocessor, the 8088, which is an 8086 with an 8-bit data bus, a 20-bit address space instead of the microcomputer industry’s 16-bit address space, and an optional 8087 floating-point processor. IBM had invented the floppy disk, but the PC used Tandon disk drives, and the PCs were sold in major outlets like ComputerLand and Sears Roebuck. The operating system was Microsoft’s MSDOS 1.0, which was an upgrade from the popular CP/M-80 microcomputer OS. It had Bill Gates 8K Basic interpreter stored in ROM in high memory. IBM documented the PC thoroughly as well. If you want lots of details, you can read Rick’s and my second microcomputer book *The IBM Personal Computer from the Inside Out*, also “typeset” on my Diablo daisy-wheel printer. With the PC, IBM was considerably ahead of the competition from the TRS-80, Apple II, and other microcomputers. Thanks to IBM’s excellent documentation, competitors emerged. One that I liked a lot was the Victor 9000. Its floppy disks held 1.2 MB compared to 360 KB on the IBM PC at the time. It had a cute cousin, the Apricot.

One of the many cool third-party IBM PC add-ons was the Hercules Graphics Card, which converted the 80 column by 25 row monochrome display card with 9×14 character cells into a 720×350 monochrome graphics card. Rick and Chris Koliopoulos copied the ROM Basic down into the upper 32K of the video space and modified it to support graphics.

IBM extended its PC lead in August 1984 with the IBM PC/AT, which used an Intel 80286 fully 16-bit processor with the ability to access up to 16 MB of memory in “protected mode”, considerably larger than the 8088’s 1 MB address space. It took a full year for the competition to create personal computers as powerful. My IBM AT had a 10 MB hard drive which was a great upgrade from the floppy disks and more than a third as large as the Model 1 1301 disk drive used with some IBM 7094 computers. I also got an HP laser printer, which HP released in April 1984. Being a laser physicist, I naturally enhanced my PS Technical Word Processor to work with it. So much easier than using multiple passes with a Diablo daisy-wheel printer!

On August 2, 1985, Estridge and his wife died in a plane crash caused by a strong thunderstorm near Dallas, Texas. That tragedy was a turning point for IBM’s microcomputer successes. Subsequent PC releases didn’t keep up with the competition from Compaq and other companies, possibly due to worries that other IBM computer systems might not survive the competition. Steve Jobs was never afraid to cannibalize his products. “If you don’t cannibalize yourself, others will” was his philosophy. The IBM PS/2 released in April 1987 was no match for the competition.

The software industry standardized on Compaq 386’s for a while. I used a Compaq 386 desktop computer and a Toshiba T5100 laptop to enhance my SST debugger to run in protected mode and access all of memory via the selector/offset memory model. In that way 80286 PC’s, which were more prevalent than 386 PC’s at the time, could access all their memory. That capability was key to getting Windows 3.0 to access all of memory and fend off OS/2. Rick and I updated our PC book in 1995 using Microsoft Word and renamed it to The Personal Computer from the Inside Out. Since then we’ve resisted the temptation to write more about the incredible evolution of microcomputers. Windows 95, an updated version of Windows 3.1, could run in as little as 4 MB of memory, although 8 MB was recommended. Nowadays 8 GB or more is recommended for a Windows laptop! Of course, today’s laptops can do so much more that the microcomputers running Windows 95. I almost never used a main frame after getting into microcomputers. The Data General Eclipse minicomputer was the biggest machine I used after 1975 and then only for a few years. The PC’s had all the power I needed.

The post Computers I have known appeared first on Math in Office.

]]>