chemruby 0.9.3

Sign up to get free protection for your applications and to get access to all the features.
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