chemruby 0.9.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (241) hide show
  1. data/README +120 -0
  2. data/Rakefile +195 -0
  3. data/ext/extconf.rb +4 -0
  4. data/ext/subcomp.c +416 -0
  5. data/lib/chem.rb +130 -0
  6. data/lib/chem/appl.rb +1 -0
  7. data/lib/chem/appl/chem3dole.rb +36 -0
  8. data/lib/chem/appl/tinker/nucleic.rb +40 -0
  9. data/lib/chem/appl/tinker/tinker_reader.rb +43 -0
  10. data/lib/chem/data.rb +4 -0
  11. data/lib/chem/data/atomic_weight.rb +124 -0
  12. data/lib/chem/data/character.rb +2 -0
  13. data/lib/chem/data/electronegativity.rb +14 -0
  14. data/lib/chem/data/periodic_table.rb +6 -0
  15. data/lib/chem/data/prime_numbers.rb +1 -0
  16. data/lib/chem/data/vdw_radii.rb +1 -0
  17. data/lib/chem/db.rb +64 -0
  18. data/lib/chem/db/cansmi.rb +234 -0
  19. data/lib/chem/db/cdx.rb +1525 -0
  20. data/lib/chem/db/eps.rb +164 -0
  21. data/lib/chem/db/g98.rb +909 -0
  22. data/lib/chem/db/gspan.rb +130 -0
  23. data/lib/chem/db/iupac.rb +5 -0
  24. data/lib/chem/db/iupac/a_1.rb +46 -0
  25. data/lib/chem/db/iupac/iuparser.rb +226 -0
  26. data/lib/chem/db/iupac/iuparser.ry +97 -0
  27. data/lib/chem/db/iupac/postfix.rb +2 -0
  28. data/lib/chem/db/kcf.rb +390 -0
  29. data/lib/chem/db/kcf_glycan.rb +19 -0
  30. data/lib/chem/db/kegg.rb +516 -0
  31. data/lib/chem/db/linucs/linparser.rb +144 -0
  32. data/lib/chem/db/linucs/linucs.ry +53 -0
  33. data/lib/chem/db/mdl.rb +379 -0
  34. data/lib/chem/db/molconnz.rb +12 -0
  35. data/lib/chem/db/mopac.rb +88 -0
  36. data/lib/chem/db/msi.rb +107 -0
  37. data/lib/chem/db/pdb_dic.rb +115 -0
  38. data/lib/chem/db/pdf.rb +131 -0
  39. data/lib/chem/db/pubchem.rb +113 -0
  40. data/lib/chem/db/rmagick.rb +70 -0
  41. data/lib/chem/db/sdf.rb +37 -0
  42. data/lib/chem/db/smbl.rb +88 -0
  43. data/lib/chem/db/smiles.rb +2 -0
  44. data/lib/chem/db/smiles/smiles.ry +203 -0
  45. data/lib/chem/db/smiles/smiparser.rb +375 -0
  46. data/lib/chem/db/swf.rb +74 -0
  47. data/lib/chem/db/sybyl.rb +150 -0
  48. data/lib/chem/db/tinker.rb +77 -0
  49. data/lib/chem/db/types/type_cansmi.rb +9 -0
  50. data/lib/chem/db/types/type_cdx.rb +24 -0
  51. data/lib/chem/db/types/type_gspan.rb +31 -0
  52. data/lib/chem/db/types/type_kcf.rb +28 -0
  53. data/lib/chem/db/types/type_kcf_glycan.rb +26 -0
  54. data/lib/chem/db/types/type_kegg.rb +92 -0
  55. data/lib/chem/db/types/type_mdl.rb +31 -0
  56. data/lib/chem/db/types/type_pdf.rb +33 -0
  57. data/lib/chem/db/types/type_png.rb +31 -0
  58. data/lib/chem/db/types/type_rxn.rb +25 -0
  59. data/lib/chem/db/types/type_sdf.rb +25 -0
  60. data/lib/chem/db/types/type_sybyl.rb +30 -0
  61. data/lib/chem/db/types/type_xyz.rb +26 -0
  62. data/lib/chem/db/vector.rb +128 -0
  63. data/lib/chem/db/xyz.rb +39 -0
  64. data/lib/chem/model.rb +119 -0
  65. data/lib/chem/model/skeleton.rb +37 -0
  66. data/lib/chem/utils.rb +11 -0
  67. data/lib/chem/utils/geometry.rb +27 -0
  68. data/lib/chem/utils/graph_db.rb +146 -0
  69. data/lib/chem/utils/math.rb +17 -0
  70. data/lib/chem/utils/prop.rb +123 -0
  71. data/lib/chem/utils/sssr.rb +101 -0
  72. data/lib/chem/utils/sub.rb +78 -0
  73. data/lib/chem/utils/transform.rb +110 -0
  74. data/lib/chem/utils/traverse.rb +37 -0
  75. data/lib/chem/utils/ullmann.rb +134 -0
  76. data/lib/graph.rb +41 -0
  77. data/lib/graph/cluster.rb +20 -0
  78. data/lib/graph/morgan.rb +38 -0
  79. data/sample/frequent_subgraph.rb +46 -0
  80. data/sample/images/ex1.rb +11 -0
  81. data/sample/images/ex2.rb +4 -0
  82. data/sample/images/ex3.rb +5 -0
  83. data/sample/images/ex4.rb +17 -0
  84. data/sample/images/ex5.rb +10 -0
  85. data/sample/images/mol/adenine.mol +26 -0
  86. data/sample/images/mol/atp.mol +69 -0
  87. data/sample/images/temp/ex5.mol +344 -0
  88. data/sample/kegg_db.rb +116 -0
  89. data/setup.rb +1551 -0
  90. data/test/all.rb +6 -0
  91. data/test/coord_test.rb +17 -0
  92. data/test/ctab_test.rb +31 -0
  93. data/test/data/A_21.tar.gz +0 -0
  94. data/test/data/A_21/aceanthrylene.cdx +0 -0
  95. data/test/data/A_21/aceanthrylene.mol +40 -0
  96. data/test/data/A_21/acenaphthylene.cdx +0 -0
  97. data/test/data/A_21/acenaphthylene.mol +31 -0
  98. data/test/data/A_21/acephenanthrylene.cdx +0 -0
  99. data/test/data/A_21/acephenanthrylene.mol +40 -0
  100. data/test/data/A_21/anthracene.cdx +0 -0
  101. data/test/data/A_21/anthracene.mol +35 -0
  102. data/test/data/A_21/as-indacene.cdx +0 -0
  103. data/test/data/A_21/as-indacene.mol +31 -0
  104. data/test/data/A_21/azulene.cdx +0 -0
  105. data/test/data/A_21/azulene.mol +26 -0
  106. data/test/data/A_21/biphenylene.cdx +0 -0
  107. data/test/data/A_21/biphenylene.mol +31 -0
  108. data/test/data/A_21/chrysene.cdx +0 -0
  109. data/test/data/A_21/chrysene.mol +44 -0
  110. data/test/data/A_21/coronen.cdx +0 -0
  111. data/test/data/A_21/coronen.mol +59 -0
  112. data/test/data/A_21/fluoranthene.cdx +0 -0
  113. data/test/data/A_21/fluoranthene.mol +40 -0
  114. data/test/data/A_21/fluorene.cdx +0 -0
  115. data/test/data/A_21/fluorene.mol +33 -0
  116. data/test/data/A_21/heptacene.cdx +0 -0
  117. data/test/data/A_21/heptacene.mol +71 -0
  118. data/test/data/A_21/heptalene.cdx +0 -0
  119. data/test/data/A_21/heptalene.mol +30 -0
  120. data/test/data/A_21/heptaphene.cdx +0 -0
  121. data/test/data/A_21/heptaphene.mol +71 -0
  122. data/test/data/A_21/hexacene.cdx +0 -0
  123. data/test/data/A_21/hexacene.mol +62 -0
  124. data/test/data/A_21/hexaphene.cdx +0 -0
  125. data/test/data/A_21/hexaphene.mol +62 -0
  126. data/test/data/A_21/indene.cdx +0 -0
  127. data/test/data/A_21/indene.mol +24 -0
  128. data/test/data/A_21/iupac.txt +41 -0
  129. data/test/data/A_21/naphthacene.cdx +0 -0
  130. data/test/data/A_21/naphthacene.mol +44 -0
  131. data/test/data/A_21/naphthalene.cdx +0 -0
  132. data/test/data/A_21/naphthalene.mol +26 -0
  133. data/test/data/A_21/ovalene.cdx +0 -0
  134. data/test/data/A_21/ovalene.mol +78 -0
  135. data/test/data/A_21/pentacene.cdx +0 -0
  136. data/test/data/A_21/pentacene.mol +53 -0
  137. data/test/data/A_21/pentalene.cdx +0 -0
  138. data/test/data/A_21/pentalene.mol +22 -0
  139. data/test/data/A_21/pentaphene.cdx +0 -0
  140. data/test/data/A_21/pentaphene.mol +53 -0
  141. data/test/data/A_21/perylene.cdx +0 -0
  142. data/test/data/A_21/perylene.mol +49 -0
  143. data/test/data/A_21/phenalene.cdx +0 -0
  144. data/test/data/A_21/phenalene.mol +33 -0
  145. data/test/data/A_21/phenanthrene.cdx +0 -0
  146. data/test/data/A_21/phenanthrene.mol +35 -0
  147. data/test/data/A_21/picene.cdx +0 -0
  148. data/test/data/A_21/picene.mol +53 -0
  149. data/test/data/A_21/pleiadene.cdx +0 -0
  150. data/test/data/A_21/pleiadene.mol +44 -0
  151. data/test/data/A_21/pyranthrene.cdx +0 -0
  152. data/test/data/A_21/pyranthrene.mol +72 -0
  153. data/test/data/A_21/pyrene.cdx +0 -0
  154. data/test/data/A_21/pyrene.mol +40 -0
  155. data/test/data/A_21/rubicene.cdx +0 -0
  156. data/test/data/A_21/rubicene.mol +63 -0
  157. data/test/data/A_21/s-indacene.cdx +0 -0
  158. data/test/data/A_21/s-indacene.mol +31 -0
  159. data/test/data/A_21/tetraphenylene.cdx +0 -0
  160. data/test/data/A_21/tetraphenylene.mol +57 -0
  161. data/test/data/A_21/trinaphthylene.cdx +0 -0
  162. data/test/data/A_21/trinaphthylene.mol +71 -0
  163. data/test/data/A_21/triphenylene.cdx +0 -0
  164. data/test/data/A_21/triphenylene.mol +44 -0
  165. data/test/data/C00147.kcf +25 -0
  166. data/test/data/G00147.kcf +13 -0
  167. data/test/data/atp.mol +69 -0
  168. data/test/data/cyclohexane.mol +17 -0
  169. data/test/data/cyclohexane.ps +485 -0
  170. data/test/data/fullerene.mol +155 -0
  171. data/test/data/glycan +33 -0
  172. data/test/data/hypericin.cdx +0 -0
  173. data/test/data/hypericin.cdxml +596 -0
  174. data/test/data/hypericin.chm +0 -0
  175. data/test/data/hypericin.ct +85 -0
  176. data/test/data/hypericin.f1d +0 -0
  177. data/test/data/hypericin.f1q +0 -0
  178. data/test/data/hypericin.gif +0 -0
  179. data/test/data/hypericin.mol +88 -0
  180. data/test/data/hypericin.mol2 +159 -0
  181. data/test/data/hypericin.msm +123 -0
  182. data/test/data/hypericin.pdf +359 -0
  183. data/test/data/hypericin.png +0 -0
  184. data/test/data/hypericin.ps +0 -0
  185. data/test/data/hypericin.skc +0 -0
  186. data/test/data/hypericin2.gif +0 -0
  187. data/test/data/hypericin2.ps +0 -0
  188. data/test/data/kegg/genomes/hsa/hsa_enzyme.list +4 -0
  189. data/test/data/kegg/genomes/hsa/hsa_pfam.list +4 -0
  190. data/test/data/kegg/ligand/mol/C00147.mol +26 -0
  191. data/test/data/kegg/ligand/reaction +14 -0
  192. data/test/data/kegg/ligand/reaction.lst +1 -0
  193. data/test/data/kegg/ligand/reaction_mapformula.lst +3 -0
  194. data/test/data/reaction +14 -0
  195. data/test/data/reaction.lst +1 -0
  196. data/test/data/reaction_mapformula.lst +3 -0
  197. data/test/data/rxn/C00001.mol +6 -0
  198. data/test/data/rxn/C00011.mol +10 -0
  199. data/test/data/rxn/C00014.mol +6 -0
  200. data/test/data/rxn/C01010.mol +18 -0
  201. data/test/data/rxn/sample.rxn +50 -0
  202. data/test/data/rxn/substitution.rxn +45 -0
  203. data/test/data/test.eps +0 -0
  204. data/test/data/test.mol +28 -0
  205. data/test/data/test.sdf +143 -0
  206. data/test/data/test.skc +0 -0
  207. data/test/data/test.xyz +4 -0
  208. data/test/data/test_lf.sdf +143 -0
  209. data/test/heavy_test_pubchem.rb +16 -0
  210. data/test/multiple_test.rb +22 -0
  211. data/test/test_adj.rb +54 -0
  212. data/test/test_canonical_smiles.rb +46 -0
  213. data/test/test_cdx.rb +32 -0
  214. data/test/test_chem.rb +18 -0
  215. data/test/test_cluster.rb +19 -0
  216. data/test/test_db.rb +11 -0
  217. data/test/test_eps.rb +24 -0
  218. data/test/test_geometry.rb +11 -0
  219. data/test/test_gspan.rb +28 -0
  220. data/test/test_iupac.rb +36 -0
  221. data/test/test_kcf.rb +24 -0
  222. data/test/test_kcf_glycan.rb +10 -0
  223. data/test/test_kegg.rb +118 -0
  224. data/test/test_linucs.rb +21 -0
  225. data/test/test_mdl.rb +45 -0
  226. data/test/test_mol2.rb +62 -0
  227. data/test/test_morgan.rb +21 -0
  228. data/test/test_pdf.rb +12 -0
  229. data/test/test_prop.rb +86 -0
  230. data/test/test_rmagick.rb +15 -0
  231. data/test/test_sbdb.rb +23 -0
  232. data/test/test_sdf.rb +30 -0
  233. data/test/test_smiles.rb +84 -0
  234. data/test/test_sssr.rb +18 -0
  235. data/test/test_sub.rb +47 -0
  236. data/test/test_subcomp.rb +37 -0
  237. data/test/test_traverse.rb +29 -0
  238. data/test/test_writer.rb +13 -0
  239. data/test/test_xyz.rb +15 -0
  240. data/test/type_test.rb +25 -0
  241. metadata +290 -0
@@ -0,0 +1,234 @@
1
+ # Author:: Nobuya Tanaka tanaka@chemruby.org
2
+
3
+ module Chem
4
+
5
+ # A module for assigning canonical smiles
6
+ module Molecule#CanonicalSmiles
7
+ require 'chem/data/periodic_table'
8
+ require 'chem/data/prime_numbers'
9
+
10
+ # Returns Canonical SMILES
11
+ def to_cansmi
12
+ cycle = 0
13
+ priority = canonical_smiles_priority_from_invariant
14
+ new_priority, n = update_priority(priority)
15
+ # show new_priority
16
+ prev_n = 0
17
+ while prev_n != n
18
+ prev_n = n
19
+ new_priority = calc_prime_product(new_priority)
20
+ # show new_priority
21
+ new_priority, n = update_priority(new_priority)
22
+ # show new_priority
23
+ end
24
+
25
+ puts
26
+ for node in @nodes
27
+ p new_priority[node]
28
+ end
29
+ show new_priority
30
+ start = new_priority.min{|a, b| a[1] <=> b[1]}[0]
31
+ get_tree(start, new_priority)
32
+ # get_canonical_smiles start, new_priority
33
+ end
34
+
35
+ private
36
+ def get_tree start, priority
37
+ traversed = []
38
+ traversed_atom = []
39
+ rings = {}
40
+ ring_to = {}
41
+ n = 1
42
+ cc = cansmi_dfs([nil, start], traversed_atom, traversed, priority, rings)
43
+ p cc
44
+ cansmi_to_s cc, rings, ring_to, n
45
+ end
46
+
47
+ private
48
+ def cansmi_to_s cc, rings, ring_to, n
49
+ str = ''
50
+ while cc and cc.length > 0
51
+ if cc.last.instance_of?(Array)
52
+ c = cc.pop
53
+ while c.length > 1
54
+ str += '('
55
+ str += cansmi_to_s(c.pop, rings, ring_to, n)
56
+ str += ')'
57
+ end
58
+ str += cansmi_to_s(c.pop, rings, ring_to, n)
59
+ else
60
+ atom = cc.pop
61
+ str += atom.respond_to?(:element) ? atom.element.to_s : atom
62
+ if ring_to[atom]
63
+ for r in ring_to[atom]
64
+ str += r.to_s
65
+ end
66
+ end
67
+ if rings[atom]
68
+ for from in rings[atom]
69
+ str += n.to_s
70
+ (ring_to[from] ||=[]).push n
71
+ n += 1
72
+ end
73
+ end
74
+ end
75
+ end
76
+ str
77
+ end
78
+
79
+ private
80
+ def cansmi_dfs from, traversed_atom, traversed, priority, rings
81
+ frag = []
82
+ adjacent_to(from[1]).sort{|a, b|
83
+ if a[0].v == b[0].v
84
+ print " * "
85
+ p priority[b[1]]
86
+ print "=* "
87
+ p priority[a[1]]
88
+ p priority[b[1]] <=> priority[a[1]]
89
+ priority[a[1]] <=> priority[b[1]]
90
+ else
91
+ b[0].v <=> a[0].v
92
+ end
93
+ }.each do |bond, atom|
94
+ next if traversed.include?(bond)
95
+ traversed << bond
96
+ if traversed_atom.include?(atom)
97
+ print "ring!"
98
+ (rings[atom] ||= []) << from[1]
99
+ else
100
+ print "#"
101
+ p priority[atom]
102
+ traversed_atom << from[1]
103
+ frag << cansmi_dfs([bond, atom], traversed_atom, traversed, priority, rings)
104
+ end
105
+ end
106
+ case frag.length
107
+ when 0
108
+ case from[0].v
109
+ when 2
110
+ frag = [from[1], "="]
111
+ when 3
112
+ frag = [from[1], "#"]
113
+ else
114
+ frag = [from[1]]
115
+ end
116
+ when 1
117
+ frag = frag[0]
118
+ if from[0]
119
+ case from[0].v
120
+ when 2
121
+ frag.concat [from[1], "="]
122
+ when 3
123
+ frag.concat [from[1], "#"]
124
+ else
125
+ frag << from[1]
126
+ end
127
+ else
128
+ if from[0]
129
+ case from[0].v
130
+ when 2
131
+ frag.concat [from[1], "="]
132
+ else
133
+ frag << from[1]
134
+ end
135
+ else
136
+ frag << from[1]
137
+ end
138
+ end
139
+ # frag << from[1]
140
+ else
141
+ if from[0]
142
+ case from[0].v
143
+ when 2
144
+ frag = [frag.reverse, from[1], "="]
145
+ else
146
+ frag = [frag.reverse, from[1]]
147
+ end
148
+ else
149
+ frag = [frag.reverse, from[1]]
150
+ end
151
+ end
152
+ frag
153
+ end
154
+
155
+ private
156
+ def show pri
157
+ @nodes.each do |node|
158
+ print "%5d" % pri[node].last
159
+ end
160
+ puts
161
+ end
162
+
163
+ private
164
+ def calc_prime_product priority
165
+ res = priority.keys.inject({}) do |r, node|
166
+ product = self.adjacent_to(node).inject(1) do |result, adj|
167
+ result * priority[adj[1]].last
168
+ end
169
+ r[node] = product
170
+ r
171
+ end
172
+ res.each do |k, v|
173
+ priority[k] << v
174
+ end
175
+ priority
176
+ end
177
+
178
+ private
179
+ def update_priority priority
180
+ i = 0
181
+ prev = nil
182
+ new_priority = {}
183
+ priority.sort_by{|k, v| v}.each do |k, v|
184
+ i += 1 if prev != v
185
+ new_priority[k] = PrimeNumber[i - 1]
186
+ prev = v
187
+ end
188
+ new_priority.each do |k, v|
189
+ priority[k] << v
190
+ end
191
+ [priority, i]
192
+ end
193
+
194
+ # (1) number of connections
195
+ # (2) number of non-hydrogen bonds
196
+ # (3) atomic number
197
+ # (4) sign of charge
198
+ # (5) absoluete charge
199
+ # (6) number of attached hydrogens
200
+ private
201
+ def canonical_smiles_priority_from_invariant
202
+ priority = {}
203
+ @nodes.each do |node|
204
+ n_connection = self.adjacent_to(node).inject(0) do |result, ary|
205
+ result + ary[0].v if ary[1].element != :H
206
+ end
207
+
208
+ n_non_hydrogen_bonds = self.adjacent_to(node).inject(0) do |result, ary|
209
+ result + 1 if ary[1].element != :H
210
+ end
211
+
212
+ atomic_number = node.atomic_number
213
+
214
+ priority[node] = [
215
+ n_connection,
216
+ n_non_hydrogen_bonds,
217
+ atomic_number]
218
+ p priority[node]
219
+ end
220
+ priority
221
+ end
222
+
223
+ end
224
+ end
225
+
226
+
227
+ if $0 == __FILE__
228
+
229
+ require 'chem'
230
+
231
+ mol = Chem.parse_smiles("OCC(CC)CCC(CN)CN")
232
+ mol.extend(Chem::CanonicalSmiles)
233
+ mol.canonical_smiles
234
+ end
@@ -0,0 +1,1525 @@
1
+ #
2
+ # cdx.rb - Cambridge Software cdx and cdxml file parser library
3
+ #
4
+ # Copyright (C) 2003 Nobuya Tanaka <tanaka@chemruby.org>
5
+ #
6
+ # Example:
7
+ # cdx_file = Chem.open_mol("hypericin.cdx")
8
+ # puts cdx_file.to_xml
9
+ #
10
+
11
+
12
+ require 'chem/data/periodic_table'
13
+
14
+ module Chem
15
+ module CDX
16
+ #
17
+ Cdx_value2name = {
18
+ 0x0001=>['CreationUserName', :CDXString],
19
+ 0x0002=>['CreationDate', :CDXDate],
20
+ 0x0003=>['CreationProgram', :CDXString],
21
+ 0x0004=>['ModificationUserName', :CDXString],
22
+ 0x0005=>['ModificationDate', :CDXDate],
23
+ 0x0006=>['ModificationProgram', :CDXString],
24
+ 0x0008=>['Name', :CDXString],
25
+ 0x0009=>['Comment', :CDXString],
26
+ 0x000A=>['Z', :INT16],
27
+ 0x000B=>['RegistryNumber', :CDXString],
28
+ 0x000C=>['RegistryAuthority', :CDXString],
29
+ 0x000E=>['RepresentsProperty', :CDXRepresentsProperty],
30
+ 0x000F=>['IgnoreWarnings', :CDXBooleanImplied],
31
+ 0x0010=>['Warning', :CDXString],
32
+ 0x0011=>['Visible', :CDXBoolean],
33
+ 0x0100=>['fonttable', :CDXFontTable],
34
+ 0x0200=>['p', :CDXPoint2D],
35
+ 0x0201=>['xyz', :CDXPoint3D],
36
+ 0x0202=>['extent', :CDXPoint2D],
37
+ 0x0203=>['extent3D', :CDXPoint3D],
38
+ 0x0204=>['BoundingBox', :CDXRectangle],
39
+ 0x0205=>['RotationAngle', :INT32],
40
+ 0x0207=>['Head3D', :CDXPoint3D],
41
+ 0x0208=>['Tail3D', :CDXPoint3D],
42
+ 0x0209=>['TopLeft', :CDXPoint2D],
43
+ 0x020A=>['TopRight', :CDXPoint2D],
44
+ 0x020B=>['BottomRight', :CDXPoint2D],
45
+ 0x020C=>['BottomLeft', :CDXPoint2D],
46
+ 0x020D=>['Width', :CDXCoordinate],
47
+ 0x020E=>['Height', :CDXCoordinate],
48
+ 0x0300=>['colortable', :CDXColorTable],
49
+ 0x0301=>['color', :UINT16],
50
+ 0x0302=>['bgcolor', :INT16],
51
+ 0x0400=>['NodeType', :INT16],
52
+ 0x0401=>['LabelDisplay', :INT8],
53
+ 0x0402=>['Element', :INT16],
54
+ 0x0403=>['ElementList', :CDXElementList],
55
+ 0x0404=>['Formula', :CDXFormula],
56
+ 0x0420=>['Isotope', :INT16],
57
+ 0x0421=>['Charge', :INT8],
58
+ 0x0422=>['Radical', :UINT8],
59
+ 0x0423=>['FreeSites', :UINT8],
60
+ 0x0424=>['ImplicitHydrogens', :CDXBooleanImplied],
61
+ 0x0425=>['RingBondCount', :INT8],
62
+ 0x0426=>['UnsaturatedBonds', :INT8],
63
+ 0x0427=>['RxnChange', :CDXBooleanImplied],
64
+ 0x0428=>['RxnStereo', :INT8],
65
+ 0x0429=>['AbnormalValence', :CDXBooleanImplied],
66
+ 0x042B=>['NumHydrogens', :UINT16],
67
+ 0x042E=>['HDot', :CDXBooleanImplied],
68
+ 0x042F=>['HDash', :CDXBooleanImplied],
69
+ 0x0430=>['Geometry', :INT8],
70
+ 0x0431=>['BondOrdering', :CDXObjectIDArray],
71
+ 0x0432=>['Attachments', :CDXObjectIDArrayWithCounts],
72
+ 0x0433=>['GenericNickname', :CDXString],
73
+ 0x0434=>['AltGroupID', :CDXObjectID],
74
+ 0x0435=>['SubstituentsUpTo', :UINT8],
75
+ 0x0436=>['SubstituentsExactly', :UINT8],
76
+ 0x0437=>['AS', :INT8],
77
+ 0x0438=>['Translation', :INT8],
78
+ 0x0439=>['AtomNumber', :CDXString],
79
+ 0x043A=>['ShowAtomQuery', :CDXBoolean],
80
+ 0x043B=>['ShowAtomStereo', :CDXBoolean],
81
+ 0x043C=>['ShowAtomNumber', :CDXBoolean],
82
+ 0x043D=>['LinkCountLow', :INT16],
83
+ 0x043E=>['LinkCountHigh', :INT16],
84
+ 0x043F=>['IsotopicAbundance', :INT8],
85
+ 0x0500=>['Racemic', :CDXBoolean],
86
+ 0x0501=>['Absolute', :CDXBoolean],
87
+ 0x0502=>['Relative', :CDXBoolean],
88
+ 0x0503=>['Formula', :CDXFormula],
89
+ 0x0504=>['Weight', :FLOAT64],
90
+ 0x0505=>['ConnectionOrder', :CDXObjectIDArray],
91
+ 0x0600=>['Order', :INT16],
92
+ 0x0601=>['Display', :INT16],
93
+ 0x0602=>['Display2', :INT16],
94
+ 0x0603=>['DoublePosition', :INT16],
95
+ 0x0604=>['B', :CDXObjectID],
96
+ 0x0605=>['E', :CDXObjectID],
97
+ 0x0606=>['Topology', :INT8],
98
+ 0x0607=>['RxnParticipation', :INT8],
99
+ 0x0608=>['BeginAttach', :UINT8],
100
+ 0x0609=>['EndAttach', :UINT8],
101
+ 0x060A=>['BS', :INT8],
102
+ 0x060B=>['BondCircularOrdering', :CDXObjectIDArray],
103
+ 0x060C=>['ShowBondQuery', :CDXBoolean],
104
+ 0x060D=>['ShowBondStereo', :CDXBoolean],
105
+ 0x060E=>['CrossingBonds', :CDXObjectIDArray],
106
+ 0x060F=>['ShowBondRxn', :CDXBoolean],
107
+ 0x0700=>['temp_Text', :CDXString],
108
+ 0x0701=>['Justification', :INT8],
109
+ 0x0702=>['LineHeight', :UINT16],
110
+ 0x0703=>['WordWrapWidth', :INT16],
111
+ 0x0704=>['LineStarts', :INT16ListWithCounts],
112
+ 0x0705=>['LabelAlignment', :INT8],
113
+ 0x0706=>['LabelLineHeight', :INT16],
114
+ 0x0707=>['CaptionLineHeight', :INT16],
115
+ 0x0708=>['InterpretChemically', :CDXBooleanImplied],
116
+ 0x0800=>['MacPrintInfo', :Unformatted],
117
+ 0x0801=>['WinPrintInfo', :Unformatted],
118
+ 0x0802=>['PrintMargins', :CDXRectangle],
119
+ 0x0803=>['ChainAngle', :INT32],
120
+ 0x0804=>['BondSpacing', :INT16],
121
+ 0x0805=>['BondLength', :CDXCoordinate],
122
+ 0x0806=>['BoldWidth', :CDXCoordinate],
123
+ 0x0807=>['LineWidth', :CDXCoordinate],
124
+ 0x0808=>['MarginWidth', :CDXCoordinate],
125
+ 0x0809=>['HashSpacing', :CDXCoordinate],
126
+ 0x080A=>['temp_LabelStyle', :CDXFontStyle],
127
+ 0x080B=>['temp_CaptionStyle', :CDXFontStyle],
128
+ 0x080C=>['CaptionJustification', :INT8],
129
+ 0x080D=>['FractionalWidths', :CDXBooleanImplied],
130
+ 0x080E=>['Magnification', :INT16],
131
+ 0x080F=>['WidthPages', :INT16],
132
+ 0x0810=>['HeightPages', :INT16],
133
+ 0x0811=>['DrawingSpace', :INT8],
134
+ 0x0812=>['Width', :CDXCoordinate],
135
+ 0x0813=>['Height', :CDXCoordinate],
136
+ 0x0814=>['PageOverlap', :CDXCoordinate],
137
+ 0x0815=>['Header', :CDXString],
138
+ 0x0816=>['HeaderPosition', :CDXCoordinate],
139
+ 0x0817=>['Footer', :CDXString],
140
+ 0x0818=>['FooterPosition', :CDXCoordinate],
141
+ 0x0819=>['PrintTrimMarks', :CDXBooleanImplied],
142
+ 0x081A=>['LabelFont', :INT16],
143
+ 0x081B=>['CaptionFont', :INT16],
144
+ 0x081C=>['LabelSize', :INT16],
145
+ 0x081D=>['CaptionSize', :INT16],
146
+ 0x081E=>['LabelFace', :INT16],
147
+ 0x081F=>['CaptionFace', :INT16],
148
+ 0x0820=>['LabelColor', :INT16],
149
+ 0x0821=>['CaptionColor', :INT16],
150
+ 0x0822=>['BondSpacingAbs', :CDXCoordinate],
151
+ 0x0823=>['LabelJustification', :INT8],
152
+ 0x0824=>['FixInPlaceExtent', :CDXPoint2D],
153
+ 0x0825=>['Side', :UINT16],
154
+ 0x0900=>['WindowIsZoomed', :CDXBooleanImplied],
155
+ 0x0901=>['WindowPosition', :CDXPoint2D],
156
+ 0x0902=>['WindowSize', :CDXPoint2D],
157
+ 0x0A00=>['GraphicType', :INT16],
158
+ 0x0A01=>['LineType', :INT16],
159
+ 0x0A02=>['ArrowType', :INT16],
160
+ 0x0A03=>['RectangleType', :INT16],
161
+ 0x0A04=>['OvalType', :INT16],
162
+ 0x0A05=>['OrbitalType', :INT16],
163
+ 0x0A06=>['BracketType', :INT16],
164
+ 0x0A07=>['SymbolType', :INT16],
165
+ 0x0A08=>['CurveType', :INT16],
166
+ 0x0A10=>['OriginFraction', :FLOAT64],
167
+ 0x0A11=>['SolventFrontFraction', :FLOAT64],
168
+ 0x0A12=>['SideTicks', :CDXBoolean],
169
+ 0x0A20=>['HeadSize', :INT16],
170
+ 0x0A20=>['Rf', :FLOAT64],
171
+ 0x0A21=>['AngularSize', :INT16],
172
+ 0x0A21=>['Tail', :CDXCoordinate],
173
+ 0x0A22=>['LipSize', :INT16],
174
+ 0x0A22=>['ShowRf', :CDXBoolean],
175
+ 0x0A23=>['CurvePoints', :CDXCurvePoints],
176
+ 0x0A24=>['BracketUsage', :INT8],
177
+ 0x0A25=>['PolymerRepeatPattern', :INT8],
178
+ 0x0A26=>['PolymerFlipType', :INT8],
179
+ 0x0A27=>['BracketedObjectIDs', :CDXObjectIDArray],
180
+ 0x0A28=>['RepeatCount', :FLOAT64],
181
+ 0x0A29=>['ComponentOrder', :INT16],
182
+ 0x0A2A=>['SRULabel', :CDXString],
183
+ 0x0A2B=>['GraphicID', :CDXObjectID],
184
+ 0x0A2C=>['BondID', :CDXObjectID],
185
+ 0x0A2D=>['InnerAtomID', :CDXObjectID],
186
+ 0x0A2E=>['CurvePoints3D', :CDXCurvePoints3D],
187
+ 0x0A60=>['Edition', :Unformatted],
188
+ 0x0A61=>['EditionAlias', :Unformatted],
189
+ 0x0A62=>['MacPICT', :Unformatted],
190
+ 0x0A63=>['WindowsMetafile', :Unformatted],
191
+ 0x0A64=>['OLEObject', :Unformatted],
192
+ 0x0A80=>['XSpacing', :FLOAT64],
193
+ 0x0A81=>['XLow', :FLOAT64],
194
+ 0x0A82=>['XType', :INT16],
195
+ 0x0A83=>['YType', :INT16],
196
+ 0x0A84=>['XAxisLabel', :CDXString],
197
+ 0x0A85=>['YAxisLabel', :CDXString],
198
+ 0x0A86=>['temp_SpectrumDataPoint', :FLOAT64],
199
+ 0x0A87=>['Class', :INT16],
200
+ 0x0A88=>['YLow', :FLOAT64],
201
+ 0x0A89=>['YScale', :FLOAT64],
202
+ 0x0B00=>['TextFrame', :CDXRectangle],
203
+ 0x0B01=>['GroupFrame', :CDXRectangle],
204
+ 0x0B02=>['Valence', :INT16],
205
+ 0x0B80=>['GeometricFeature', :INT8],
206
+ 0x0B81=>['RelationValue', :FLOAT64],
207
+ 0x0B82=>['BasisObjects', :CDXObjectIDArray],
208
+ 0x0B83=>['ConstraintType', :INT8],
209
+ 0x0B84=>['ConstraintMin', :FLOAT64],
210
+ 0x0B85=>['ConstraintMax', :FLOAT64],
211
+ 0x0B86=>['IgnoreUnconnectedAtoms', :CDXBooleanImplied],
212
+ 0x0B87=>['DihedralIsChiral', :CDXBooleanImplied],
213
+ 0x0B88=>['PointIsDirected', :CDXBooleanImplied],
214
+ 0x0C00=>['ReactionStepAtomMap', :CDXObjectIDArray],
215
+ 0x0C01=>['ReactionStepReactants', :CDXObjectIDArray],
216
+ 0x0C02=>['ReactionStepProducts', :CDXObjectIDArray],
217
+ 0x0C03=>['ReactionStepPlusses', :CDXObjectIDArray],
218
+ 0x0C04=>['ReactionStepArrows', :CDXObjectIDArray],
219
+ 0x0C05=>['ReactionStepObjectsAboveArrow', :CDXObjectIDArray],
220
+ 0x0C06=>['ReactionStepObjectsBelowArrow', :CDXObjectIDArray],
221
+ 0x0C07=>['ReactionStepAtomMapManual', :CDXObjectIDArray],
222
+ 0x0C08=>['ReactionStepAtomMapAuto', :CDXObjectIDArray],
223
+ 0x0D00=>['TagType', :INT16],
224
+ 0x0D03=>['Tracking', :CDXBoolean],
225
+ 0x0D04=>['Persistent', :CDXBoolean],
226
+ 0x0D05=>['Value', :varies],
227
+ 0x0D06=>['PositioningType', :INT8],
228
+ 0x0D07=>['PositioningAngle', :INT32],
229
+ 0x0D08=>['PositioningOffset', :CDXPoint2D],
230
+ 0x0E00=>['SequenceIdentifier', :CDXString],
231
+ 0x0F00=>['CrossReferenceContainer', :CDXString],
232
+ 0x0F01=>['CrossReferenceDocument', :CDXString],
233
+ 0x0F02=>['CrossReferenceIdentifier', :CDXString],
234
+ 0x0F03=>['CrossReferenceSequence', :CDXString],
235
+ 0x1000=>['PaneHeight', :CDXCoordinate],
236
+ 0x1001=>['NumRows', :INT16],
237
+ 0x1002=>['NumColumns', :INT16],
238
+ 0x1100=>['Integral', :CDXBoolean],
239
+ 0x1FF0=>['SplitterPositions', :CDXObjectIDArray],
240
+ 0x1FF1=>['PageDefinition', :INT8],
241
+ 0x206=>['BoundsInParent', :CDXRectangle],
242
+ 0x8000=>['CDXML', :CDXObject],
243
+ 0x8001=>['page', :CDXObject],
244
+ 0x8002=>['group', :CDXObject],
245
+ 0x8003=>['fragment', :CDXObject],
246
+ 0x8004=>['n', :CDXObject],
247
+ 0x8005=>['b', :CDXObject],
248
+ 0x8006=>['t', :CDXObject],
249
+ 0x8007=>['graphic', :CDXObject],
250
+ 0x8017=>['bracketedgroup', :CDXObject],
251
+ 0x8018=>['bracketattachment', :CDXObject],
252
+ 0x8019=>['crossingbond', :CDXObject],
253
+ 0x8008=>['curve', :CDXObject],
254
+ 0x8009=>['embeddedobject', :CDXObject],
255
+ 0x8016=>['table', :CDXObject],
256
+ 0x800A=>['altgroup', :CDXObject],
257
+ 0x800B=>['templategrid', :CDXObject],
258
+ 0x800C=>['regnum', :CDXObject],
259
+ 0x800D=>['scheme', :CDXObject],
260
+ 0x800E=>['step', :CDXObject],
261
+ 0x8010=>['spectrum', :CDXObject],
262
+ 0x8011=>['objecttag', :CDXObject],
263
+ 0x8013=>['sequence', :CDXObject],
264
+ 0x8014=>['crossreference', :CDXObject],
265
+ 0x8020=>['border', :CDXObject],
266
+ 0x8021=>['geometry', :CDXObject],
267
+ 0x8022=>['constraint', :CDXObject],
268
+ 0x8023=>['tlcplate', :CDXObject],
269
+ 0x8024=>['tlclane', :CDXObject],
270
+ 0x8025=>['tlcspot', :CDXObject],
271
+ 0x8015=>['splitter', :CDXObject],
272
+ 0x9000=>['font', :CDXStyle],#Temporarily use user defined id by Nobuya Tanaka.
273
+ 0x9001=>['s', :CDXStyle],#Temporarily use user defined id by Nobuya Tanaka.
274
+ # 0x000e=>['represent', :CDXObject],
275
+ }
276
+
277
+ Cdx_name2value = {'CreationUserName'=>0x0001,
278
+ 'CreationDate'=>0x0002,
279
+ 'CreationProgram'=>0x0003,
280
+ 'ModificationUserName'=>0x0004,
281
+ 'ModificationDate'=>0x0005,
282
+ 'ModificationProgram'=>0x0006,
283
+ 'Name'=>0x0008,
284
+ 'Comment'=>0x0009,
285
+ 'Z'=>0x000A,
286
+ 'RegistryNumber'=>0x000B,
287
+ 'RegistryAuthority'=>0x000C,
288
+ 'RepresentsProperty'=>0x000E,
289
+ 'IgnoreWarnings'=>0x000F,
290
+ 'Warning'=>0x0010,
291
+ 'Visible'=>0x0011,
292
+ 'fonttable'=>0x0100,
293
+ 'p'=>0x0200,
294
+ 'xyz'=>0x0201,
295
+ 'extent'=>0x0202,
296
+ 'extent3D'=>0x0203,
297
+ 'BoundingBox'=>0x0204,
298
+ 'RotationAngle'=>0x0205,
299
+ 'Head3D'=>0x0207,
300
+ 'Tail3D'=>0x0208,
301
+ 'TopLeft'=>0x0209,
302
+ 'TopRight'=>0x020A,
303
+ 'BottomRight'=>0x020B,
304
+ 'BottomLeft'=>0x020C,
305
+ 'Width'=>0x020D,
306
+ 'Height'=>0x020E,
307
+ 'colortable'=>0x0300,
308
+ 'color'=>0x0301,
309
+ 'bgcolor'=>0x0302,
310
+ 'NodeType'=>0x0400,
311
+ 'LabelDisplay'=>0x0401,
312
+ 'Element'=>0x0402,
313
+ 'ElementList'=>0x0403,
314
+ 'Formula'=>0x0404,
315
+ 'Isotope'=>0x0420,
316
+ 'Charge'=>0x0421,
317
+ 'Radical'=>0x0422,
318
+ 'FreeSites'=>0x0423,
319
+ 'ImplicitHydrogens'=>0x0424,
320
+ 'RingBondCount'=>0x0425,
321
+ 'UnsaturatedBonds'=>0x0426,
322
+ 'RxnChange'=>0x0427,
323
+ 'RxnStereo'=>0x0428,
324
+ 'AbnormalValence'=>0x0429,
325
+ 'NumHydrogens'=>0x042B,
326
+ 'HDot'=>0x042E,
327
+ 'HDash'=>0x042F,
328
+ 'Geometry'=>0x0430,
329
+ 'BondOrdering'=>0x0431,
330
+ 'Attachments'=>0x0432,
331
+ 'GenericNickname'=>0x0433,
332
+ 'AltGroupID'=>0x0434,
333
+ 'SubstituentsUpTo'=>0x0435,
334
+ 'SubstituentsExactly'=>0x0436,
335
+ 'AS'=>0x0437,
336
+ 'Translation'=>0x0438,
337
+ 'AtomNumber'=>0x0439,
338
+ 'ShowAtomQuery'=>0x043A,
339
+ 'ShowAtomStereo'=>0x043B,
340
+ 'ShowAtomNumber'=>0x043C,
341
+ 'LinkCountLow'=>0x043D,
342
+ 'LinkCountHigh'=>0x043E,
343
+ 'IsotopicAbundance'=>0x043F,
344
+ 'Racemic'=>0x0500,
345
+ 'Absolute'=>0x0501,
346
+ 'Relative'=>0x0502,
347
+ 'Formula'=>0x0503,
348
+ 'Weight'=>0x0504,
349
+ 'ConnectionOrder'=>0x0505,
350
+ 'Order'=>0x0600,
351
+ 'Display'=>0x0601,
352
+ 'Display2'=>0x0602,
353
+ 'DoublePosition'=>0x0603,
354
+ 'B'=>0x0604,
355
+ 'E'=>0x0605,
356
+ 'Topology'=>0x0606,
357
+ 'RxnParticipation'=>0x0607,
358
+ 'BeginAttach'=>0x0608,
359
+ 'EndAttach'=>0x0609,
360
+ 'BS'=>0x060A,
361
+ 'BondCircularOrdering'=>0x060B,
362
+ 'ShowBondQuery'=>0x060C,
363
+ 'ShowBondStereo'=>0x060D,
364
+ 'CrossingBonds'=>0x060E,
365
+ 'ShowBondRxn'=>0x060F,
366
+ 'temp_Text'=>0x0700,
367
+ 'Justification'=>0x0701,
368
+ 'LineHeight'=>0x0702,
369
+ 'WordWrapWidth'=>0x0703,
370
+ 'LineStarts'=>0x0704,
371
+ 'LabelAlignment'=>0x0705,
372
+ 'LabelLineHeight'=>0x0706,
373
+ 'CaptionLineHeight'=>0x0707,
374
+ 'InterpretChemically'=>0x0708,
375
+ 'MacPrintInfo'=>0x0800,
376
+ 'WinPrintInfo'=>0x0801,
377
+ 'PrintMargins'=>0x0802,
378
+ 'ChainAngle'=>0x0803,
379
+ 'BondSpacing'=>0x0804,
380
+ 'BondLength'=>0x0805,
381
+ 'BoldWidth'=>0x0806,
382
+ 'LineWidth'=>0x0807,
383
+ 'MarginWidth'=>0x0808,
384
+ 'HashSpacing'=>0x0809,
385
+ 'temp_LabelStyle'=>0x080A,
386
+ 'temp_CaptionStyle'=>0x080B,
387
+ 'CaptionJustification'=>0x080C,
388
+ 'FractionalWidths'=>0x080D,
389
+ 'Magnification'=>0x080E,
390
+ 'WidthPages'=>0x080F,
391
+ 'HeightPages'=>0x0810,
392
+ 'DrawingSpace'=>0x0811,
393
+ 'Width'=>0x0812,
394
+ 'Height'=>0x0813,
395
+ 'PageOverlap'=>0x0814,
396
+ 'Header'=>0x0815,
397
+ 'HeaderPosition'=>0x0816,
398
+ 'Footer'=>0x0817,
399
+ 'FooterPosition'=>0x0818,
400
+ 'PrintTrimMarks'=>0x0819,
401
+ 'LabelFont'=>0x081A,
402
+ 'CaptionFont'=>0x081B,
403
+ 'LabelSize'=>0x081C,
404
+ 'CaptionSize'=>0x081D,
405
+ 'LabelFace'=>0x081E,
406
+ 'CaptionFace'=>0x081F,
407
+ 'LabelColor'=>0x0820,
408
+ 'CaptionColor'=>0x0821,
409
+ 'BondSpacingAbs'=>0x0822,
410
+ 'LabelJustification'=>0x0823,
411
+ 'FixInPlaceExtent'=>0x0824,
412
+ 'Side'=>0x0825,
413
+ 'WindowIsZoomed'=>0x0900,
414
+ 'WindowPosition'=>0x0901,
415
+ 'WindowSize'=>0x0902,
416
+ 'GraphicType'=>0x0A00,
417
+ 'LineType'=>0x0A01,
418
+ 'ArrowType'=>0x0A02,
419
+ 'RectangleType'=>0x0A03,
420
+ 'OvalType'=>0x0A04,
421
+ 'OrbitalType'=>0x0A05,
422
+ 'BracketType'=>0x0A06,
423
+ 'SymbolType'=>0x0A07,
424
+ 'CurveType'=>0x0A08,
425
+ 'OriginFraction'=>0x0A10,
426
+ 'SolventFrontFraction'=>0x0A11,
427
+ 'SideTicks'=>0x0A12,
428
+ 'HeadSize'=>0x0A20,
429
+ 'Rf'=>0x0A20,
430
+ 'AngularSize'=>0x0A21,
431
+ 'Tail'=>0x0A21,
432
+ 'LipSize'=>0x0A22,
433
+ 'ShowRf'=>0x0A22,
434
+ 'CurvePoints'=>0x0A23,
435
+ 'BracketUsage'=>0x0A24,
436
+ 'PolymerRepeatPattern'=>0x0A25,
437
+ 'PolymerFlipType'=>0x0A26,
438
+ 'BracketedObjectIDs'=>0x0A27,
439
+ 'RepeatCount'=>0x0A28,
440
+ 'ComponentOrder'=>0x0A29,
441
+ 'SRULabel'=>0x0A2A,
442
+ 'GraphicID'=>0x0A2B,
443
+ 'BondID'=>0x0A2C,
444
+ 'InnerAtomID'=>0x0A2D,
445
+ 'CurvePoints3D'=>0x0A2E,
446
+ 'Edition'=>0x0A60,
447
+ 'EditionAlias'=>0x0A61,
448
+ 'MacPICT'=>0x0A62,
449
+ 'WindowsMetafile'=>0x0A63,
450
+ 'OLEObject'=>0x0A64,
451
+ 'XSpacing'=>0x0A80,
452
+ 'XLow'=>0x0A81,
453
+ 'XType'=>0x0A82,
454
+ 'YType'=>0x0A83,
455
+ 'XAxisLabel'=>0x0A84,
456
+ 'YAxisLabel'=>0x0A85,
457
+ 'temp_SpectrumDataPoint'=>0x0A86,
458
+ 'Class'=>0x0A87,
459
+ 'YLow'=>0x0A88,
460
+ 'YScale'=>0x0A89,
461
+ 'TextFrame'=>0x0B00,
462
+ 'GroupFrame'=>0x0B01,
463
+ 'Valence'=>0x0B02,
464
+ 'GeometricFeature'=>0x0B80,
465
+ 'RelationValue'=>0x0B81,
466
+ 'BasisObjects'=>0x0B82,
467
+ 'ConstraintType'=>0x0B83,
468
+ 'ConstraintMin'=>0x0B84,
469
+ 'ConstraintMax'=>0x0B85,
470
+ 'IgnoreUnconnectedAtoms'=>0x0B86,
471
+ 'DihedralIsChiral'=>0x0B87,
472
+ 'PointIsDirected'=>0x0B88,
473
+ 'ReactionStepAtomMap'=>0x0C00,
474
+ 'ReactionStepReactants'=>0x0C01,
475
+ 'ReactionStepProducts'=>0x0C02,
476
+ 'ReactionStepPlusses'=>0x0C03,
477
+ 'ReactionStepArrows'=>0x0C04,
478
+ 'ReactionStepObjectsAboveArrow'=>0x0C05,
479
+ 'ReactionStepObjectsBelowArrow'=>0x0C06,
480
+ 'ReactionStepAtomMapManual'=>0x0C07,
481
+ 'ReactionStepAtomMapAuto'=>0x0C08,
482
+ 'TagType'=>0x0D00,
483
+ 'Tracking'=>0x0D03,
484
+ 'Persistent'=>0x0D04,
485
+ 'Value'=>0x0D05,
486
+ 'PositioningType'=>0x0D06,
487
+ 'PositioningAngle'=>0x0D07,
488
+ 'PositioningOffset'=>0x0D08,
489
+ 'SequenceIdentifier'=>0x0E00,
490
+ 'CrossReferenceContainer'=>0x0F00,
491
+ 'CrossReferenceDocument'=>0x0F01,
492
+ 'CrossReferenceIdentifier'=>0x0F02,
493
+ 'CrossReferenceSequence'=>0x0F03,
494
+ 'PaneHeight'=>0x1000,
495
+ 'NumRows'=>0x1001,
496
+ 'NumColumns'=>0x1002,
497
+ 'Integral'=>0x1100,
498
+ 'SplitterPositions'=>0x1FF0,
499
+ 'PageDefinition'=>0x1FF1,
500
+ 'BoundsInParent'=>0x206,
501
+ 'CDXML'=>0x8000,
502
+ 'page'=>0x8001,
503
+ 'group'=>0x8002,
504
+ 'fragment'=>0x8003,
505
+ 'n'=>0x8004,
506
+ 'b'=>0x8005,
507
+ 't'=>0x8006,
508
+ 'graphic'=>0x8007,
509
+ 'bracketedgroup'=>0x8017,
510
+ 'bracketattachment'=>0x8018,
511
+ 'crossingbond'=>0x8019,
512
+ 'curve'=>0x8008,
513
+ 'embeddedobject'=>0x8009,
514
+ 'table'=>0x8016,
515
+ 'altgroup'=>0x800A,
516
+ 'templategrid'=>0x800B,
517
+ 'regnum'=>0x800C,
518
+ 'scheme'=>0x800D,
519
+ 'step'=>0x800E,
520
+ 'spectrum'=>0x8010,
521
+ 'objecttag'=>0x8011,
522
+ 'sequence'=>0x8013,
523
+ 'crossreference'=>0x8014,
524
+ 'border'=>0x8020,
525
+ 'geometry'=>0x8021,
526
+ 'constraint'=>0x8022,
527
+ 'tlcplate'=>0x8023,
528
+ 'tlclane'=>0x8024,
529
+ 'tlcspot'=>0x8025,
530
+ 'splitter'=>0x8015,
531
+ 'fonttable'=>0x0100,
532
+ 'font'=>0x9000,#Temporarily use user defined id by Nobuya Tanaka.
533
+ 's'=>0x9001,#Temporarily use user defined id by Nbuya Tanaka.
534
+ # 'colortable'=>0x0300,
535
+ # 'color'=>0x0301,
536
+ 'represent'=>0x000e
537
+ }
538
+
539
+ # module CDX
540
+ # def begin_object type, id
541
+ # return [$cdx_name2value[type]].pack('s') + [id].pack('V')
542
+ # end
543
+
544
+ # def prop type, byte
545
+ # return [$cdx_name2value[type], byte.length].pack('ss') + byte
546
+ # end
547
+ # end
548
+
549
+ class CDXCoordinate
550
+ attr_reader :coord
551
+
552
+ def initialize coord
553
+ @coord = coord.to_f
554
+ end
555
+
556
+ def to_xml
557
+ "%.0f" % [@coord / 65536]
558
+ end
559
+
560
+ def to_bin
561
+ return [@coord].pack('l')
562
+ end
563
+
564
+ end
565
+
566
+ class CDXPoint2D
567
+ attr_reader :x, :y
568
+
569
+ def initialize x, y
570
+ @x, @y = x.to_f, y.to_f
571
+ end
572
+
573
+ def to_bin ; [@y, @x].pack('V2') ; end
574
+
575
+ def to_xml
576
+ "%.2f %.2f" % [@x / 65536, @y / 65536]
577
+ end
578
+
579
+ end
580
+
581
+ class CDXPoint3D
582
+ end
583
+
584
+ class CDXRectangle
585
+ attr_reader :top, :left, :bottom, :right
586
+
587
+ def initialize top, left, bottom, right
588
+ @top, @left, @bottom, @right = top.to_f, left.to_f, bottom.to_f, right.to_f
589
+ end
590
+
591
+ def to_bin ; [@top.to_i, @left.to_i, @bottom.to_i, @right.to_i].pack('V4') ; end
592
+
593
+ def to_xml
594
+ "%.2f %.2f %.2f %.2f" % [@top / 65536, @left / 65536, @bottom / 65536, @right / 65536]
595
+ end
596
+
597
+ end
598
+
599
+ class CDXBoolean
600
+
601
+ def initialize tf
602
+ @bool = tf
603
+ end
604
+
605
+ def to_xml
606
+ @bool ? "yes" : "no"
607
+ end
608
+
609
+ def to_bin
610
+ if @bool
611
+ str = [1].pack('c')
612
+ else
613
+ str = [0].pack('c')
614
+ end
615
+ str
616
+ end
617
+ end
618
+
619
+ class CDXBooleanImplied
620
+
621
+ def initialize tf
622
+ @bool = tf
623
+ end
624
+
625
+ def to_xml
626
+ @bool ? "yes" : "no"
627
+ end
628
+
629
+ def to_bin
630
+ if @bool
631
+ str = [1].pack('c')
632
+ else
633
+ str = [0].pack('c')
634
+ end
635
+ ''
636
+ end
637
+
638
+ end
639
+
640
+ class CDXColorTable
641
+
642
+ def initialize
643
+ @colors = []
644
+ end
645
+
646
+ def push r, g, b
647
+ @colors.push([r, g, b])
648
+ end
649
+
650
+ def to_s #fix me
651
+ "<colortable>"
652
+ end
653
+
654
+ def to_bin
655
+ str = [@colors.length].pack('v')
656
+ @colors.each do |color|
657
+ str += color.pack('v3')
658
+ end
659
+ str
660
+ end
661
+
662
+ def to_xml
663
+ str = "<colortable>\n"
664
+ @colors.each do |c|
665
+ str += "<color r=\"%d\" g=\"%d\" b=\"%d\"/>\n" % c.collect{|cc| cc/65535.0}
666
+ end
667
+ str + "</colortable>\n"
668
+ end
669
+
670
+ end
671
+
672
+ class CDXCurvePoints# fix me
673
+ end
674
+
675
+ class CDXCurvePoints3D# fix me
676
+ end
677
+
678
+ class CDXElementList# fix me
679
+ end
680
+
681
+ class CDXFontTable
682
+ attr_accessor :platform
683
+
684
+ def initialize
685
+ @fonts = []
686
+ end
687
+
688
+ def push_font font
689
+ @fonts.push(font)
690
+ end
691
+
692
+ def to_xml
693
+ str = "<fonttable>\n"
694
+ @fonts.each do |font|
695
+ str += "<font id=\"#{font.font_id}\" charset=\"#{charset(font.charset)}\" name=\"#{font.name}\"/>\n"
696
+ end
697
+ str + "</fonttable>\n"
698
+ end
699
+
700
+ def to_bin
701
+ str = [@platform].pack('v')
702
+ str += [@fonts.length].pack('v')
703
+ @fonts.each do |font|
704
+ str += [font.font_id, font.charset, font.name.length, font.name].pack('vvva*')
705
+ end
706
+ str
707
+ end
708
+ CS = {
709
+ 0=>'Unknown',
710
+ 37=>'EBCDICOEM',
711
+ 437=>'MSDOSUS',
712
+ 500=>'EBCDIC500V1',
713
+ 708=>'ASMO-708',
714
+ 709=>'ArabicASMO449P',
715
+ 710=>'ArabicTransparent',
716
+ 720=>'DOS-720',
717
+ 737=>'Greek437G',
718
+ 775=>'cp775',
719
+ 850=>'windows-850',
720
+ 852=>'ibm852',
721
+ 855=>'cp855',
722
+ 857=>'cp857',
723
+ 860=>'cp860',
724
+ 861=>'cp861',
725
+ 862=>'DOS-862',
726
+ 863=>'cp863',
727
+ 864=>'cp864',
728
+ 865=>'cp865',
729
+ 866=>'cp866',
730
+ 869=>'cp869',
731
+ 874=>'windows-874',
732
+ 875=>'EBCDIC',
733
+ 932=>'shift_jis',
734
+ 936=>'gb2312',
735
+ 949=>'ks_c_5601-1987',
736
+ 950=>'big5',
737
+ 1200=>'iso-10646',
738
+ 1250=>'windows-1250',
739
+ 1251=>'windows-1251',
740
+ 1252=>'iso-8859-1',
741
+ 1253=>'iso-8859-7',
742
+ 1254=>'iso-8859-9',
743
+ 1255=>'windows-1255',
744
+ 1256=>'windows-1256',
745
+ 1257=>'windows-1257',
746
+ 1258=>'windows-1258',
747
+ 1361=>'windows-1361',
748
+ 10000=>'x-mac-roman',
749
+ 10001=>'x-mac-japanese',
750
+ 10002=>'x-mac-tradchinese',
751
+ 10003=>'x-mac-korean',
752
+ 10004=>'x-mac-arabic',
753
+ 10005=>'x-mac-hebrew',
754
+ 10006=>'x-mac-greek',
755
+ 10007=>'x-mac-cyrillic',
756
+ 10008=>'x-mac-reserved',
757
+ 10009=>'x-mac-devanagari',
758
+ 10010=>'x-mac-gurmukhi',
759
+ 10011=>'x-mac-gujarati',
760
+ 10012=>'x-mac-oriya',
761
+ 10013=>'x-mac-nengali',
762
+ 10014=>'x-mac-tamil',
763
+ 10015=>'x-mac-telugu',
764
+ 10016=>'x-mac-kannada',
765
+ 10017=>'x-mac-Malayalam',
766
+ 10018=>'x-mac-sinhalese',
767
+ 10019=>'x-mac-burmese',
768
+ 10020=>'x-mac-khmer',
769
+ 10021=>'x-mac-thai',
770
+ 10022=>'x-mac-lao',
771
+ 10023=>'x-mac-georgian',
772
+ 10024=>'x-mac-armenian',
773
+ 10025=>'x-mac-simpChinese',
774
+ 10026=>'x-mac-tibetan',
775
+ 10027=>'x-mac-mongolian',
776
+ 10028=>'x-mac-ethiopic',
777
+ 10029=>'x-mac-ce',
778
+ 10030=>'x-mac-vietnamese',
779
+ 10031=>'x-mac-extArabic',
780
+ 10032=>'x-mac-uninterpreted',
781
+ 10079=>'x-mac-icelandic',
782
+ 10081=>'x-mac-turkis'
783
+ }
784
+
785
+ def charset cs
786
+ CS[cs]
787
+ end
788
+
789
+ end
790
+
791
+ class CDXFormula# fix me
792
+ end
793
+
794
+ class CDXObjectIDArray
795
+
796
+ def initialize array
797
+ @array = array
798
+ end
799
+
800
+ def to_xml
801
+ @array.collect{|a| "%d" % a}.join(" ")
802
+ end
803
+
804
+ def to_bin
805
+ @array.pack('V')
806
+ end
807
+
808
+ end
809
+
810
+ class CDXObjectIDArrayWithCounts
811
+ end
812
+
813
+ class CDXObjectID
814
+
815
+ def initialize object_id
816
+ @object_id = object_id
817
+ end
818
+
819
+ def to_xml
820
+ @object_id
821
+ end
822
+
823
+ def to_bin
824
+ [@object_id].pack('L')
825
+ end
826
+
827
+ end
828
+
829
+ class CDXRepresentsProperty
830
+ end
831
+
832
+ class CDXString
833
+ Style = {
834
+ 0x00=>'plain',
835
+ 0x01=>'bold',
836
+ 0x02=>'italic',
837
+ 0x04=>'underline',
838
+ 0x08=>'outline',
839
+ 0x10=>'shadow',
840
+ 0x20=>'subscript',
841
+ 0x40=>'superscript',
842
+ 0x60=>'formula'
843
+ }
844
+
845
+ def initialize
846
+ @str = ''
847
+ @style = []
848
+ end
849
+
850
+ def push_string str
851
+ @str += str
852
+ end
853
+
854
+ def push_style style
855
+ @style.push(style)
856
+ end
857
+
858
+ def analyze str
859
+ end
860
+
861
+ def to_s
862
+ @str.gsub(/'/, '&apos;')
863
+ end
864
+
865
+ def to_xml
866
+ if @style.length == 0
867
+ return "<s>%s</s>" % @str
868
+ else
869
+ ret = ''
870
+ i = 0
871
+ @style.each do |style|
872
+ i += 1
873
+ n = @style[i] ? @style[i][0] -1 : -1
874
+ ret += "<s font=\"%d\" size=\"%d\" face=\"%d\">%s</s>" % [style[1], style[3] / 20, style[2], @str[style[0]..n].gsub(/'/, '&apos;')]
875
+ end
876
+ return ret
877
+ end
878
+ end
879
+
880
+ def to_bin
881
+ bin = [@style.length].pack('v')
882
+ @style.each do |style|
883
+ bin += style.pack('v*')
884
+ end
885
+ bin + @str.to_a.pack('a*')
886
+ end
887
+
888
+ def string
889
+ @str
890
+ end
891
+
892
+ end
893
+
894
+ class CDXFontStyle # fix me
895
+
896
+ def initialize style
897
+ @style = style
898
+ end
899
+
900
+ def to_bin
901
+ @style.pack('v4')
902
+ end
903
+
904
+ end
905
+
906
+ class CDXDate # fix me
907
+ end
908
+
909
+ class CDXLineStarts # fix me
910
+ end
911
+
912
+ class INT16ListWithCounts # fix me
913
+ end
914
+
915
+ class Unformatted # fix me
916
+
917
+ def initialize str
918
+ @str = str
919
+ end
920
+
921
+ def to_xml
922
+ @str
923
+ end
924
+
925
+ def to_bin
926
+ @str
927
+ end
928
+
929
+ end
930
+
931
+ class Int8
932
+ attr_reader :num
933
+
934
+ def initialize num ; @num = num ; end
935
+
936
+ def to_xml ; @num.to_s ; end
937
+
938
+ def to_bin ; [@num].pack('c') ; end
939
+
940
+ end
941
+
942
+ class Uint32
943
+
944
+ attr_reader :num
945
+
946
+ def initialize num ; @num = num ; end
947
+
948
+ def to_xml ; @num.to_s ; end
949
+
950
+ def to_bin ; [@num].pack('V') ; end
951
+
952
+ end
953
+
954
+ class Int32
955
+
956
+ attr_reader :num
957
+
958
+ def initialize num ; @num = num ; end
959
+
960
+ def to_xml ; @num.to_s ; end
961
+
962
+ def to_bin ; [@num].pack('v') ;end
963
+
964
+ end
965
+
966
+ class Uint16
967
+ attr_reader :num
968
+
969
+ def initialize num
970
+ @num = num
971
+ end
972
+
973
+ def to_xml ; @num.to_s ; end
974
+ def to_bin ; [@num].pack('v') ; end
975
+
976
+ end
977
+
978
+ class Int16
979
+ attr_reader :num
980
+ def initialize num
981
+ @num = num
982
+ end
983
+ def to_xml
984
+ return @num.to_s
985
+ end
986
+ def to_bin ; [@num].pack('v') ; end
987
+ def to_i
988
+ @num
989
+ end
990
+ end
991
+
992
+ class Uint8
993
+ attr_reader :num
994
+ def initialize num
995
+ @num = num
996
+ end
997
+ def to_xml
998
+ return @num.to_s
999
+ end
1000
+ end
1001
+
1002
+ class Float64
1003
+ attr_reader :num
1004
+ def initialize num
1005
+ @num = num
1006
+ end
1007
+ def to_xml
1008
+ return @num.to_s
1009
+ end
1010
+ end
1011
+
1012
+ class CDXStyle# There is no such Data Types in original CDX file
1013
+ attr_accessor :face, :font, :size, :color
1014
+ end
1015
+
1016
+ class CDXObject
1017
+ attr_accessor :parent, :tag, :name, :object_id
1018
+ attr_reader :properties, :objects
1019
+
1020
+ Justification = {
1021
+ -1=>"Right",
1022
+ 0=>'Left',
1023
+ 1=>'Center',
1024
+ 2=>'Full',
1025
+ 3=>'Above',
1026
+ 4=>'Below',
1027
+ 5=>'Auto'
1028
+ }
1029
+
1030
+ Label_alignment = {
1031
+ 0=>"Auto",
1032
+ 1=>"Left",
1033
+ 2=>"Center",
1034
+ 3=>"Right",
1035
+ 4=>"Above",
1036
+ 5=>"Below",
1037
+ 6=>"Best"
1038
+ }
1039
+
1040
+ Bs = {
1041
+ 0=>'U',
1042
+ 1=>'N',
1043
+ 2=>'D',
1044
+ 3=>'Z'
1045
+ }
1046
+
1047
+ As = {
1048
+ 0=>'U',
1049
+ 1=>'N',
1050
+ 2=>'R',
1051
+ 3=>'S',
1052
+ 4=>'r',
1053
+ 5=>'s',
1054
+ 6=>'u'
1055
+ }
1056
+
1057
+ def initialize name, object_id
1058
+ @name, @object_id = name, object_id
1059
+ @tag = Cdx_name2value[name]
1060
+ @properties = Hash.new
1061
+ @objects = Hash.new
1062
+ end
1063
+
1064
+ def to_xml
1065
+ str = "<%s\n" % [@name]
1066
+ obj = []
1067
+ str += " id=\"%d\"\n" % [@object_id] if @object_id != 0
1068
+
1069
+ @properties.each do |k, p|
1070
+ case k
1071
+ when 'temp_LabelStyle'
1072
+ ;
1073
+ when 'temp_CaptionStyle'
1074
+ ;
1075
+ when 'temp_Text'
1076
+ obj.push(p.to_xml)
1077
+ when 'colortable'
1078
+ obj.push(p.to_xml)
1079
+ when 'fonttable'
1080
+ obj.push(p.to_xml)
1081
+ when 'LabelAlignment'
1082
+ str += " %s=\"%s\"\n" % [k, Label_alignment[p.num]]
1083
+ when 'BS'
1084
+ str += " %s=\"%s\"\n" % [k, Bs[p.num]]
1085
+ when 'AS'
1086
+ p(p)
1087
+ str += " %s=\"%s\"\n" % [k, As[p.num]]
1088
+ when 'Justification'
1089
+ str += " %s=\"%s\"\n" % [k, Justification[p.num]]
1090
+ when 'LabelJustification'
1091
+ str += " %s=\"%s\"\n" % [k, Justification[p.num]]
1092
+ when 'ChainAngle'
1093
+ str += " %s=\"%s\"\n" % [k, p.num / 65536.0]
1094
+ when 'BondSpacing'
1095
+ str += " %s=\"%s\"\n" % [k, p.num / 10.0]
1096
+ when 'LineHeight'
1097
+ if p == 1
1098
+ str += " %s=\"%s\"\n" % [k, 'auto']
1099
+ elsif p == 0
1100
+ ;#fix me
1101
+ else
1102
+ str += " %s=\"%s\"\n" % [k, p.num]
1103
+ end
1104
+ when 'LabelLineHeight'
1105
+ if p == 1
1106
+ str += " %s=\"%s\"\n" % [k, 'auto']
1107
+ elsif p == 0
1108
+ ;#fix me
1109
+ else
1110
+ str += " %s=\"%s\"\n" % [k, p]
1111
+ end
1112
+ else
1113
+ if !p.respond_to?("to_xml")
1114
+ p p
1115
+ end
1116
+ str += " %s=\"%s\"\n" % [k, p.to_xml]
1117
+ end
1118
+ end
1119
+ str += ">"
1120
+ obj.each do |o|
1121
+ str += o
1122
+ end
1123
+ # @objects.to_a.sort{|a, b| p a[0] ; a[0]<=>b[0]}.each do |k, o|
1124
+ @objects.to_a.each do |k, o|
1125
+ str += o.to_xml
1126
+ end
1127
+ if('s' == @name)
1128
+ str += fixme#fix me
1129
+ end
1130
+ str + "</%s>" % [@name]
1131
+ end
1132
+ def to_bin
1133
+ str = ''
1134
+ str += [@tag].pack('s') + [@object_id].pack('V')
1135
+ @properties.each do |key, prop|
1136
+ value = Cdx_name2value[key]
1137
+ if value == nil
1138
+ puts key
1139
+ exit
1140
+ end
1141
+ str += [value].pack('s')
1142
+ prop_bin = prop.to_bin
1143
+ str += [prop_bin.length].pack('v')
1144
+ str += prop_bin
1145
+ end
1146
+ @objects.each do |key, obj|
1147
+ str += obj.to_bin
1148
+ end
1149
+ str + [0x0000].pack('s')
1150
+ end
1151
+
1152
+ def prop type, byte
1153
+ return [Cdx_name2value[type], byte.length].pack('ss') + byte
1154
+ end
1155
+ end
1156
+
1157
+ Xml_header = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n" +
1158
+ '<!DOCTYPE CDXML SYSTEM "http://www.cambridgesoft.com/xml/cdxml.dtd">'
1159
+ Bin_header = [0x56, 0x6A, 0x43, 0x44, 0x30, 0x31, 0x30, 0x30,
1160
+ 0x04, 0x03, 0x02, 0x01,
1161
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1162
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00].pack("c*")
1163
+ Font_class = Struct.new("CDXFont", :font_id, :charset, :length, :name)
1164
+
1165
+ class CDX
1166
+ include Molecule
1167
+
1168
+ def push_mol mol
1169
+ @mols.push(mol)
1170
+ end
1171
+
1172
+ def to_bin
1173
+ return Bin_header + @objects.to_bin
1174
+ end
1175
+
1176
+ def to_xml
1177
+ return Xml_header + @objects.to_xml
1178
+ end
1179
+
1180
+ def set_id id
1181
+ return [id].pack('V')
1182
+ end
1183
+
1184
+ def make_p
1185
+ @objects = CDXObject.new('CDXML', 0)
1186
+ object_id = 1
1187
+ cdxstring = CDXString.new
1188
+ cdxstring.push_string("test.cdxml")
1189
+ @objects.properties["Name"] = cdxstring
1190
+ page = CDXObject.new('page', object_id)
1191
+ @objects.objects[object_id] = page
1192
+ object_id += 1
1193
+ atomlist = {}
1194
+ @mols.last.atoms.each do |atom|
1195
+ # 1.upto(10) do |number|
1196
+ n = CDXObject.new('n', object_id)
1197
+ atomlist[atom] = n
1198
+ n.properties['Z'] = Int16.new(object_id)
1199
+ n.properties['p'] = CDXPoint2D.new((atom.x + 30) * 10 * 65536, (atom.y + 30) * 10 * 65536)
1200
+ n.properties['AS'] = Int16.new(1)
1201
+ n.properties['Element'] = Int16.new(atom.atomic_number)
1202
+ page.objects[object_id] = n
1203
+ object_id += 1
1204
+ end
1205
+ @mols.last.bonds.each do |bond|
1206
+ b = CDXObject.new('b', object_id)
1207
+ b.properties['E'] = CDXObjectID.new(atomlist[bond.e].object_id)
1208
+ b.properties['B'] = CDXObjectID.new(atomlist[bond.b].object_id)
1209
+ b.properties['Order'] = Int16.new(bond.v)
1210
+ page.objects[object_id] = b
1211
+ object_id += 1
1212
+ end
1213
+ end
1214
+
1215
+ def self.open filename
1216
+ CDX.new filename
1217
+ end
1218
+
1219
+ def to_xml
1220
+ Xml_header + @objects.to_xml
1221
+ end
1222
+
1223
+ def objects
1224
+ @objects
1225
+ end
1226
+
1227
+ def pool
1228
+ @object_pool
1229
+ end
1230
+
1231
+ def self.cdx_create_object object_type, str
1232
+ case object_type
1233
+ when :CDXCoordinate
1234
+ return CDXCoordinate.new(str.unpack('l')[0])
1235
+ when :CDXPoint2D
1236
+ xy = str.unpack("V2")
1237
+ return CDXPoint2D.new(xy[1], xy[0])
1238
+ when :CDXPoint3D#fix me
1239
+ return 'fix me'
1240
+ when :CDXRectangle
1241
+ bound = str.unpack("V4")
1242
+ return CDXRectangle.new(bound[1], bound[0], bound[3], bound[2])
1243
+ when :CDXBoolean
1244
+ return CDXBoolean.new(str[0] == 0 ? false : true)
1245
+ when :CDXBooleanImplied
1246
+ return CDXBooleanImplied.new(str[0] == 0 ? false : true)
1247
+ when :CDXColorTable # fix me
1248
+ ct = CDXColorTable.new
1249
+ kaisu = str.unpack("v")[0]
1250
+ start = 2
1251
+ 1.upto(kaisu) do |n|
1252
+ rgb = str[start, 6].unpack("v3")
1253
+ ct.push(rgb[0], rgb[1], rgb[2])
1254
+ start += 6
1255
+ end
1256
+ return ct
1257
+ when :CDXCurvePoints #fix me
1258
+ return 'fix me'
1259
+ when :CDXCurvePoints3D #fix me
1260
+ return 'fix me'
1261
+ when :CDXElementList #fix me
1262
+ return 'fix me'
1263
+ when :CDXFontTable #fix me
1264
+ font_table = CDXFontTable.new
1265
+ font_table.platform = str[0..1].unpack('v')[0]
1266
+ n = str[2..3].unpack('v')[0]
1267
+ start = 4
1268
+ n.times do |n|
1269
+ font = Font_class.new
1270
+ font.font_id = str[start, 2].unpack('v')[0]
1271
+ font.charset = str[start+2, 2].unpack('v')[0]
1272
+ font.length = str[start+4, 2].unpack('v')[0]
1273
+ font.name = str[start+6, font.length].unpack('a*')[0]
1274
+ # p font.name
1275
+ start += 6 + font.length
1276
+ font_table.push_font(font)
1277
+ end
1278
+ return font_table
1279
+ when :CDXFormula #fix me
1280
+ return 'fix me'
1281
+ when :INT8
1282
+ return Int8.new(str.unpack('c')[0])
1283
+ when :UINT32
1284
+ return Uint32.new(str.unpack("V")[0])
1285
+ when :INT32
1286
+ return Int32.new(str.unpack("V")[0])
1287
+ when :UINT16
1288
+ return Uint16.new(str.unpack("v")[0])
1289
+ when :INT16
1290
+ return Int16.new(str.unpack("s")[0])
1291
+ when :UINT8
1292
+ return Uint8.new(str.unpack('C')[0])
1293
+ when :FLOAT64
1294
+ return Float64.new(str.unpack('d')[0])# fix me
1295
+ when :CDXObjectIDArray
1296
+ return CDXObjectIDArray.new(str.unpack('V*'))
1297
+ when :CDXObjectIDArrayWithCounts #fix me
1298
+ return 'fix me'
1299
+ when :CDXObjectID
1300
+ return CDXObjectID.new(str.unpack('L')[0])
1301
+ when :CDXRepresentsProperty #fix me
1302
+ return 'fix me'
1303
+ when :CDXString
1304
+ cdxstring = CDXString.new
1305
+ n = str[0..1].unpack('v')[0]
1306
+ n.times do |nn|
1307
+ start = 2 + 10 * nn
1308
+ cdxstring.push_style(str[start, 10].unpack('v5'))
1309
+ end
1310
+ cdxstring.push_string(str[(2+10*n)..-1].unpack('a*')[0])
1311
+ return cdxstring
1312
+ when :CDXFontStyle# fix me
1313
+ return CDXFontStyle.new(str[0, 10].unpack('v4'))
1314
+ when :CDXDate# fix me
1315
+ return 'fix me'
1316
+ when :CDXLineStarts# fix me
1317
+ return 'fix me'
1318
+ when :INT16ListWithCounts# fix me
1319
+ return 'fix me'
1320
+ when :Unformatted
1321
+ return Unformatted.new(str.unpack('H*')[0].upcase)
1322
+ else
1323
+ p object_type
1324
+ return str
1325
+ end
1326
+ end
1327
+
1328
+ def initialize
1329
+ @mols = Array.new
1330
+ @end_object = [0x0000].pack('s')
1331
+
1332
+ @object_pool = {}
1333
+ end
1334
+
1335
+ def cdxml_open(filename)
1336
+ require 'rexml/document'
1337
+
1338
+ @object_id = 0
1339
+ @objects = parent = CDXObject.new('CDXML', @object_id)
1340
+ @object_id += 1
1341
+
1342
+ file = File.new(filename, "r")
1343
+ doc = REXML::Document.new(file)
1344
+ doc.elements.each do |element|
1345
+ parent.objects[@object_id] = recurse_cdxml(element, parent)
1346
+ end
1347
+ # p parent
1348
+ end
1349
+
1350
+ def each
1351
+ # must return each mol
1352
+ end
1353
+
1354
+ def recurse_cdxml element, parent
1355
+ obj = CDXObject.new(element.name, 0)
1356
+ case element.name
1357
+ when 'color'#fix me
1358
+ when 's'#fix me
1359
+ obj.properties['']
1360
+ when 'font'#fix me
1361
+ else
1362
+ element.attributes.each do |key, att|
1363
+ if 'id' == key
1364
+ obj.object_id = att.to_i
1365
+ else
1366
+ # puts "%s %s" % [key, $cdx_name2value[key].inspect]
1367
+ obj.properties[key] = cdxml_create_object(Cdx_value2name[Cdx_name2value[key]][1], att)
1368
+ end
1369
+ end
1370
+ end
1371
+ element.elements.each do |el|
1372
+ if el.attributes['id']
1373
+ object_id = el.attributes['id']# fix me
1374
+ else
1375
+ object_id = @object_id
1376
+ @object_id += 1
1377
+ end
1378
+ obj.objects[@object_id] = recurse_cdxml(el, obj)
1379
+ @object_id += 1
1380
+ end
1381
+ obj
1382
+ end
1383
+
1384
+ def cdxml_create_object object_type, att
1385
+ case object_type
1386
+ when :CDXStyle
1387
+ p att
1388
+ when :CDXObject
1389
+ p att
1390
+ when :CDXCoordinate
1391
+ return CDXCoordinate.new(att.to_i)
1392
+ when :CDXPoint2D
1393
+ return CDXPoint2D.new(att.split[0].to_i * 65536, att.split[1].to_i * 65536)
1394
+ when :CDXPoint3D#fix me
1395
+ return 'fix me'
1396
+ when :CDXRectangle
1397
+ bound = att.split
1398
+ return CDXRectangle.new(bound[0].to_i * 65536, bound[0].to_i * 65536, bound[3].to_i * 65536, bound[2].to_i * 65536)
1399
+ when :CDXBoolean
1400
+ return CDXBoolean.new(att == "yes")
1401
+ when :CDXBooleanImplied
1402
+ return CDXBooleanImplied.new(att == "yes")
1403
+ # when :CDXColorTable # fix me
1404
+ # ct = CDXColorTable.new
1405
+ # p ct
1406
+ # 1.upto(kaisu) do |n|
1407
+ # rgb = str[start, 6].unpack("v3")
1408
+ # ct.push(rgb[0], rgb[1], rgb[2])
1409
+ # start += 6
1410
+ # end
1411
+ # return ct
1412
+ # when :CDXCurvePoints #fix me
1413
+ # return 'fix me'
1414
+ # when :CDXCurvePoints3D #fix me
1415
+ # return 'fix me'
1416
+ # when :CDXElementList #fix me
1417
+ # return 'fix me'
1418
+ # when :CDXFontTable #fix me
1419
+ # font_table = CDXFontTable.new
1420
+ # font_table.platform = str[0..1].unpack('v')[0]
1421
+ # n = str[2..3].unpack('v')[0]
1422
+ # start = 4
1423
+ # font_class = Struct.new("Font", :font_id, :charset, :length, :name)
1424
+ # n.times do |n|
1425
+ # font = font_class.new
1426
+ # font.font_id = str[start, 2].unpack('v')[0]
1427
+ # font.charset = str[start+2, 2].unpack('v')[0]
1428
+ # font.length = str[start+4, 2].unpack('v')[0]
1429
+ # font.name = str[start+6, font.length].unpack('a*')[0]
1430
+ # # p font.name
1431
+ # start += 6 + font.length
1432
+ # font_table.push_font(font)
1433
+ # end
1434
+ # return font_table
1435
+ # when :CDXFormula #fix me
1436
+ # return 'fix me'
1437
+ when :INT8
1438
+ return Int8.new(att.to_i)
1439
+ when :UINT32
1440
+ return Uint32.new(att.to_i)
1441
+ when :INT32
1442
+ return Int32.new(att.to_i)
1443
+ when :UINT16
1444
+ return Uint16.new(att.to_i)
1445
+ when :INT16
1446
+ return Int16.new(att.to_i)
1447
+ when :UINT8
1448
+ return Uint8.new(att.to_i)
1449
+ when :FLOAT64
1450
+ return Float64.new(att.to_i)
1451
+ when :CDXObjectIDArray
1452
+ return CDXObjectIDArray.new(att.split.collect{|i| i.to_i})
1453
+ # when :CDXObjectIDArrayWithCounts #fix me
1454
+ # return 'fix me'
1455
+ when :CDXObjectID
1456
+ return CDXObjectID.new(att.to_i)
1457
+ # when :CDXRepresentsProperty #fix me
1458
+ # return 'fix me'
1459
+ when :CDXString# may be fix me
1460
+ cdxstring = CDXString.new
1461
+ cdxstring.push_string(att)
1462
+ return cdxstring
1463
+ # n = str[0..1].unpack('v')[0]
1464
+ # n.times do |nn|
1465
+ # start = 2 + 10 * nn
1466
+ # cdxstring.push_style(str[start, 10].unpack('v5'))
1467
+ # end
1468
+ # cdxstring.push_string(str[(2+10*n)..-1].unpack('a*')[0])
1469
+ # return cdxstring
1470
+ # when :CDXFontStyle# fix me
1471
+ # return CDXFontStyle.new(str[0, 10].unpack('v4'))
1472
+ # when :CDXDate# fix me
1473
+ # return 'fix me'
1474
+ # when :CDXLineStarts# fix me
1475
+ # return 'fix me'
1476
+ # when :INT16ListWithCounts# fix me
1477
+ # return 'fix me'
1478
+ when :Unformatted
1479
+ return Unformatted.new(att)
1480
+ else
1481
+ p object_type
1482
+ return "cdxml_create_object not supported data type! please fix me!"
1483
+ end
1484
+ end
1485
+
1486
+ def open(filename)
1487
+ input = File.open(filename, 'r')
1488
+ input.read(8)
1489
+ input.read(4)
1490
+ input.read(16)
1491
+
1492
+ @objects = parent = CDXObject.new('CDXML', 0)
1493
+ parent.parent = parent
1494
+
1495
+ sp = 0
1496
+ while !input.eof? do
1497
+ tag = input.read(2).unpack("v")[0]
1498
+ if tag == 0
1499
+ sp -= 1
1500
+ parent = parent.parent
1501
+ elsif (tag & 0x8000) == 0 # Property
1502
+ num = input.read(2).unpack("v")[0]
1503
+ bytes = input.read(num)
1504
+ puts "null number %04x " % tag if Cdx_value2name[tag] == nil
1505
+ STDOUT.flush
1506
+ parent.properties[Cdx_value2name[tag][0]] =
1507
+ CDX.cdx_create_object(Cdx_value2name[tag][1], bytes)
1508
+ elsif tag == nil
1509
+ next
1510
+ else # Object
1511
+ id = input.read(4).unpack('V')[0]
1512
+ object = CDXObject.new(Cdx_value2name[tag][0], id)
1513
+ object.name = Cdx_value2name[tag][0]
1514
+ @object_pool[id] = object
1515
+ parent.objects[id] = object
1516
+ object.parent = parent
1517
+ parent = object
1518
+ end
1519
+ end
1520
+ self
1521
+ end
1522
+
1523
+ end
1524
+ end
1525
+ end