1 <?xml version="1.0" encoding="UTF-8"?>
2 <!DOCTYPE script:module PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "module.dtd">
3 <script:module xmlns:script="http://openoffice.org/2000/script" script:name="Main" script:language="StarBasic">' Matt McCutchen's SuperbChemistry for OpenOffice, version 2
5 ' Applies superscript and subscript formatting to chemical formulas in text.
8 ' - Quantities [0-9]+ and charges [0-9]*[-+−] are recognized after an element
9 ' symbol [A-Z][a-z]? or a closing delimiter [])}] . Hyphens are converted
10 ' into real minus signs.
11 ' - A charge sign [-+−] is ignored if it is followed by a letter, digit,
12 ' opening delimiter, or [<>] . (Charges should appear only at the end of a
13 ' formula, and we want to avoid matching ordinary hyphens in text.)
14 ' - When digits followed by a charge sign are recognized, the last digit
15 ' becomes part of the charge and the remaining digits become the quantity.
16 ' (Charges rarely have absolute value more than 9.)
17 ' - Exception: If a single digit follows O or a closing delimiter, that digit
18 ' is always the quantity. (Handle NO3- and Fe(OH)2+. I think oxygen is the
19 ' only element that frequently has a quantity as part of a +/-1 ion. A group
20 ' is rarely parenthesized unless it has a quantity.)
23 ' C12345 ==> C_{12345}
25 ' Cl- ==> Cl^-
26 ' Fe3+ ==> Fe^{3+}
27 ' SO42- ==> SO_4^{2-}
28 ' C1232+ ==> C_{123}^{2+}
29 ' N2- ==> N^{2-}
30 ' NO3- ==> NO_3^-
31 ' Fe(OH)2- ==> Fe(OH)_2^-
32 ' O12 ==> O_{12}
35 ' Foo2 ==> Foo2
36 ' TI-89 ==> TI-89
38 ' Regular expression replace in the document,
39 ' creating superscripts if superb > 0 or subscripts if superb < 0.
40 ' Used by SuperbChemistry.
41 sub SuperbReplace(doc as object, searchStr as string, replaceStr as string, superb as integer)
44 rd = doc.createReplaceDescriptor()
46 rd.SearchCaseSensitive = true
47 rd.SearchRegularExpression = true
48 rd.setSearchString(searchStr)
49 rd.setReplaceString(replaceStr)
51 if superb <> 0 then
52 dim replaceAttrs(1) as new com.sun.star.beans.PropertyValue
53 replaceAttrs(0).Name = "CharEscapement"
55 replaceAttrs(0).Value = 33
57 replaceAttrs(0).Value = -9
59 replaceAttrs(1).Name = "CharEscapementHeight"
60 replaceAttrs(1).Value = 58
61 rd.setReplaceAttributes(replaceAttrs)
68 ' Formats the current document
71 ' Idiom: Match something and tag it on the left or right with @x@
72 ' for further processing. If the replacement text could use
73 ' backreferences, this would be easier.
75 ' Tag candidate quantity/charges following symbols or ).
76 SuperbReplace(ThisComponent, "([A-Z][a-z]?|[\])}])[0-9]*[-+−]", "&@g@", 0)
78 ' Disqualify + and - in compound words, etc.
79 SuperbReplace(ThisComponent, "@g@[[({A-Za-z0-9<>]", "@G@&", 0)
80 SuperbReplace(ThisComponent, "@G@@g@", "", 0)
82 ' O and )]} grab a single digit as quantity.
83 SuperbReplace(ThisComponent, "[\])}O][0-9]", "&@n@", 0)
85 ' Real minus signs in charges.
86 SuperbReplace(ThisComponent, "-@g@", "−@g@", 0)
88 ' Make charges: at most one digit.
89 SuperbReplace(ThisComponent, "[0-9]?[−+]@g@", "@q@&", 1)
91 ' Remove the O and ) markers in case of O57.
92 SuperbReplace(ThisComponent, "@n@", "", 0)
94 ' Tag quantities: as many digits as we can still grab.
95 SuperbReplace(ThisComponent, "([A-Z][a-z]?|[\])}])[0-9]+", "&@n@", 0)
97 ' Make quantities.
98 SuperbReplace(ThisComponent, "[0-9]+@n@", "&", -1)
100 ' Clean up all markers.
101 SuperbReplace(ThisComponent, "@[gGnq]@", "", 0)