Module: ChemScanner::ChemDraw::BaseValue
- Included in:
- BaseNode
- Defined in:
- lib/chem_scanner/chem_draw/node/base_value.rb
Overview
ChemDraw basic Node
Constant Summary collapse
- TEXT_ATTRIBUTES =
%w[font face size color].freeze
- CDXML_CDX_POINT =
(1.0e6 / 65536)
- ARROW_NOGO_CROSS =
2
- CDXML_ARROW_TYPE =
{ # "HalfHead" => 1, # "FullHead" => 2, "Full" => 2, # "Resonance" => 4, # "Equilibrium" => 8, # "Hollow" => 16, # "RetroSynthetic" => 32, # "NoGo" => 64, # "Dipole" => 128, }.freeze
- CDXML_GRAPHIC_TYPE =
{ "Line" => 1, "Arc" => 2, "Rectangle" => 3, "Oval" => 4, "Orbital" => 5, }.freeze
- CDXML_LINE_TYPE =
{ "Dashed" => 1, }.freeze
- CDXML_NODE_TYPE =
{ "Unspecified" => 0, "Nickname" => 4, "Fragment" => 5, "GenericNickname" => 7, "AnonymousAlternativeGroup" => 8, "ExternalConnectionPoint" => 12, }.freeze
- CDXML_ATOM_EXTERNAL_CONNECTION_TYPE =
{ "Unspecified" => 0, "Diamond" => 1, "Star" => 2, "PolymerBead" => 3, "Wavy" => 4, }.freeze
- CDXML_OVAL_TYPE =
{ "Circle" => 1, "Shaded" => 2, "Circle Shaded" => 3, "Filled" => 4, "Dashed" => 8, "Bold" => 16, "Shadowed" => 32, }.freeze
- CDXML_ORBITAL_TYPE =
{ "s" => 0, "oval" => 1, "lobe" => 2, "p" => 3, "hybridPlus" => 4, "hybridMinus" => 5, "dz2Plus" => 6, "dz2Minus" => 7, "dxy" => 8, "sShaded" => 256, "ovalShaded" => 257, "lobeShaded" => 258, "pShaded" => 259, "sFilled" => 512, "ovalFilled" => 513, "lobeFilled" => 514, "pFilled" => 515, "hybridPlusFilled" => 516, "hybridMinusFilled" => 517, "dz2PlusFilled" => 518, "dz2MinusFilled" => 519, "dxyFilled" => 520, }.freeze
Instance Method Summary collapse
- #binary_chunks(string, size) ⇒ Object
-
#cdx_styles(data, runs) ⇒ Object
Output example: [{ start: 1, face: 96 }].
- #cdx_text(data) ⇒ Object
- #cdxml_text(data) ⇒ Object
- #do_unhandled(tag) ⇒ Object
- #initialize(parser, parser_type, id) ⇒ Object
- #point_2d(data) ⇒ Object
- #point_3d(data) ⇒ Object
-
#polygon_from_bb(data) ⇒ Object
Get polygon based on bounding box data.
- #read_bounding_box(data) ⇒ Object
- #read_ids(data) ⇒ Object
- #read_int(data, unsigned) ⇒ Object
- #read_type(tag, data, cdxml_type) ⇒ Object
- #read_value(prop_name, data) ⇒ Object
Instance Method Details
#binary_chunks(string, size) ⇒ Object
186 187 188 189 190 |
# File 'lib/chem_scanner/chem_draw/node/base_value.rb', line 186 def binary_chunks(string, size) Array.new(((string.length + size - 1) / size)) do |i| string.slice(i * size, size) end end |
#cdx_styles(data, runs) ⇒ Object
Output example: [{ start: 1, face: 96 }]
222 223 224 225 226 227 228 229 230 231 232 233 234 |
# File 'lib/chem_scanner/chem_draw/node/base_value.rb', line 222 def cdx_styles(data, runs) style_list = (0..runs - 1).each_with_object([]) do |sb, list| sr = data[sb * 10, 10] attr_list = (["start"] + TEXT_ATTRIBUTES) style = attr_list.each_with_object({}).with_index do |(attr, acc), id| acc[attr.to_sym] = read_int(sr[id * 2, 2], true) end list.push(style) end style_list.sort_by { |x| x[:start] } end |
#cdx_text(data) ⇒ Object
196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 |
# File 'lib/chem_scanner/chem_draw/node/base_value.rb', line 196 def cdx_text(data) style_runs = read_int(data[0, 2], true) text_pos = style_runs * 10 + 2 plain = data[text_pos, data.size - text_pos] styles = cdx_styles(data[2..-1], style_runs) if styles.empty? return [{ text: plain, font: 3, face: 0, size: 8, color: 0 }] end plain_arr = plain.dup.split("") styled_text = [] styles.each_with_index do |style, idx| t_start = style.delete(:start) t_end = (styles[idx + 1] || {}).fetch(:start, plain.length) text = plain_arr[t_start..t_end - 1].join("") style[:text] = text style[:size] = style[:size] / 20 styled_text.push(style) end styled_text end |
#cdxml_text(data) ⇒ Object
236 237 238 239 240 241 242 243 244 245 246 247 248 |
# File 'lib/chem_scanner/chem_draw/node/base_value.rb', line 236 def cdxml_text(data) styled_text = [] data.xpath("./s").each do |s| style = TEXT_ATTRIBUTES.each_with_object({}) do |attr, acc| acc[attr.to_sym] = s.attr(attr).to_i acc[:text] = s.text end styled_text.push(style) end styled_text end |
#do_unhandled(tag) ⇒ Object
136 137 138 139 140 141 142 |
# File 'lib/chem_scanner/chem_draw/node/base_value.rb', line 136 def do_unhandled(tag) return if @parser_type == "cdxml" return unless (tag & CdxReader::TAG_OBJECT).nonzero? loop { break if @parser.reader.read_next.positive? } end |
#initialize(parser, parser_type, id) ⇒ Object
192 193 194 |
# File 'lib/chem_scanner/chem_draw/node/base_value.rb', line 192 def initialize(parser, parser_type, id) super(parser, parser_type, id) end |
#point_2d(data) ⇒ Object
144 145 146 147 148 149 150 151 152 153 154 155 156 |
# File 'lib/chem_scanner/chem_draw/node/base_value.rb', line 144 def point_2d(data) x = 0 y = 0 if @parser_type == "cdx" y, x = binary_chunks(data, 4).map { |v| read_int(v, false) * 1.0e-6 } elsif @parser_type == "cdxml" values = data.text.split(" ") x, y = values[0..1].map { |v| v.to_f / CDXML_CDX_POINT } end [x.round(5), -y.round(5)] end |
#point_3d(data) ⇒ Object
158 159 160 161 162 163 164 165 166 167 168 169 170 |
# File 'lib/chem_scanner/chem_draw/node/base_value.rb', line 158 def point_3d(data) x = 0 y = 0 if @parser_type == "cdx" x, y, = binary_chunks(data, 4).map { |v| read_int(v, false) * 1.0e-6 } elsif @parser_type == "cdxml" values = data.text.split(" ") x, y = values[0..1].map { |v| v.to_f / CDXML_CDX_POINT } end [x.round(5), -y.round(5)] end |
#polygon_from_bb(data) ⇒ Object
Get polygon based on bounding box data
110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/chem_scanner/chem_draw/node/base_value.rb', line 110 def polygon_from_bb(data) btop, left, bbottom, right = read_bounding_box(data) top = - btop bottom = - bbottom points = [ Geometry::Point.new(left, bottom), Geometry::Point.new(left, top), Geometry::Point.new(right, top), Geometry::Point.new(right, bottom) ] Geometry::Polygon.new(points) end |
#read_bounding_box(data) ⇒ Object
122 123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/chem_scanner/chem_draw/node/base_value.rb', line 122 def read_bounding_box(data) if @parser_type == "cdxml" left, top, right, bottom = data.text.split(" ").map do |x| x.to_f / CDXML_CDX_POINT end else top, left, bottom, right = binary_chunks(data, 4).map do |x| read_int(x, false) * 1.0e-6 end end [top, left, bottom, right] end |
#read_ids(data) ⇒ Object
250 251 252 253 254 |
# File 'lib/chem_scanner/chem_draw/node/base_value.rb', line 250 def read_ids(data) return data.text.split(" ").map(&:to_i) if @parser_type == "cdxml" binary_chunks(data, 4).map { |v| read_int(v, false) } end |
#read_int(data, unsigned) ⇒ Object
172 173 174 175 176 177 178 179 180 181 182 183 184 |
# File 'lib/chem_scanner/chem_draw/node/base_value.rb', line 172 def read_int(data, unsigned) return data.text.to_i if @parser_type == "cdxml" type = case data.length when 1 then "c" when 2 then "s" when 4 then "l" end unsigned = unsigned || false type = unsigned ? type.upcase : type.downcase data.unpack(type)[0] end |
#read_type(tag, data, cdxml_type) ⇒ Object
87 88 89 90 91 |
# File 'lib/chem_scanner/chem_draw/node/base_value.rb', line 87 def read_type(tag, data, cdxml_type) return read_value(tag, data) if @parser_type == "cdx" cdxml_type[data.text] end |
#read_value(prop_name, data) ⇒ Object
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/chem_scanner/chem_draw/node/base_value.rb', line 93 def read_value(prop_name, data) data_type = PROPS_DATA_TYPE[@props_ref[prop_name]] unless (/U?INT[8(16)(32)]/ =~ data_type).nil? return read_int(data, data_type[0] == "U") end case data_type when "CDXObjectID" then read_int(data, true) when "CDXPoint2D" then point_2d(data) when "CDXPoint3D" then point_3d(data) when "CDXRectangle" then polygon_from_bb(data) when "CDXObjectIDArray" then read_ids(data) end end |