mathtype 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +14 -0
  3. data/.rspec +2 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +40 -0
  7. data/Rakefile +2 -0
  8. data/lib/mathtype/version.rb +3 -0
  9. data/lib/mathtype.rb +61 -0
  10. data/lib/records/char.rb +84 -0
  11. data/lib/records/color.rb +13 -0
  12. data/lib/records/color_def.rb +37 -0
  13. data/lib/records/embell.rb +103 -0
  14. data/lib/records/encoding_def.rb +22 -0
  15. data/lib/records/end.rb +8 -0
  16. data/lib/records/eqn_prefs.rb +44 -0
  17. data/lib/records/font_def.rb +14 -0
  18. data/lib/records/font_style_def.rb +14 -0
  19. data/lib/records/future.rb +14 -0
  20. data/lib/records/line.rb +36 -0
  21. data/lib/records/matrix.rb +41 -0
  22. data/lib/records/mtef.rb +118 -0
  23. data/lib/records/nudge.rb +34 -0
  24. data/lib/records/pile.rb +28 -0
  25. data/lib/records/ruler.rb +22 -0
  26. data/lib/records/size.rb +44 -0
  27. data/lib/records/snapshot.rb +19 -0
  28. data/lib/records/tmpl.rb +449 -0
  29. data/lib/records/typesizes.rb +24 -0
  30. data/mathtype.gemspec +28 -0
  31. data/spec/fixtures/expected/embelishments.xml +848 -0
  32. data/spec/fixtures/expected/equation1.xml +492 -0
  33. data/spec/fixtures/expected/equation10.xml +369 -0
  34. data/spec/fixtures/expected/equation11.xml +370 -0
  35. data/spec/fixtures/expected/equation12.xml +433 -0
  36. data/spec/fixtures/expected/equation13.xml +680 -0
  37. data/spec/fixtures/expected/equation2.xml +429 -0
  38. data/spec/fixtures/expected/equation3.xml +1374 -0
  39. data/spec/fixtures/expected/equation4.xml +360 -0
  40. data/spec/fixtures/expected/equation5.xml +377 -0
  41. data/spec/fixtures/expected/equation6.xml +364 -0
  42. data/spec/fixtures/expected/equation7.xml +369 -0
  43. data/spec/fixtures/expected/equation8.xml +362 -0
  44. data/spec/fixtures/expected/equation9.xml +355 -0
  45. data/spec/fixtures/input/embelishments.bin +0 -0
  46. data/spec/fixtures/input/equation1.bin +0 -0
  47. data/spec/fixtures/input/equation10.bin +0 -0
  48. data/spec/fixtures/input/equation11.bin +0 -0
  49. data/spec/fixtures/input/equation12.bin +0 -0
  50. data/spec/fixtures/input/equation13.bin +0 -0
  51. data/spec/fixtures/input/equation2.bin +0 -0
  52. data/spec/fixtures/input/equation3.bin +0 -0
  53. data/spec/fixtures/input/equation4.bin +0 -0
  54. data/spec/fixtures/input/equation5.bin +0 -0
  55. data/spec/fixtures/input/equation6.bin +0 -0
  56. data/spec/fixtures/input/equation7.bin +0 -0
  57. data/spec/fixtures/input/equation8.bin +0 -0
  58. data/spec/fixtures/input/equation9.bin +0 -0
  59. data/spec/mathtype_spec.rb +16 -0
  60. data/spec/spec_helper.rb +64 -0
  61. metadata +233 -0
@@ -0,0 +1,118 @@
1
+ require_relative "end"
2
+ require_relative "nudge"
3
+ require_relative "ruler"
4
+ require_relative "line"
5
+ require_relative "embell"
6
+ require_relative "char"
7
+ require_relative "pile"
8
+ require_relative "tmpl"
9
+ require_relative "eqn_prefs"
10
+ require_relative "font_def"
11
+ require_relative "typesizes"
12
+ require_relative "font_style_def"
13
+ require_relative "matrix"
14
+ require_relative "encoding_def"
15
+ require_relative "embell"
16
+ require_relative "size"
17
+ require_relative "color"
18
+ require_relative "color_def"
19
+ require_relative "future"
20
+
21
+ module Mathtype
22
+ RECORD_NAMES = {
23
+ 0 => "end",
24
+ 1 => "slot",
25
+ 2 => "char",
26
+ 3 => "tmpl",
27
+ 4 => "pile",
28
+ 5 => "matrix",
29
+ 6 => "embell",
30
+ 7 => "ruler",
31
+ 8 => "font_style_def",
32
+ 9 => "size",
33
+ 10 => "full",
34
+ 11 => "sub",
35
+ 12 => "sub2",
36
+ 13 => "sym",
37
+ 14 => "subsym",
38
+ 15 => "color",
39
+ 16 => "color_def",
40
+ 17 => "font_def",
41
+ 18 => "eqn_prefs",
42
+ 19 => "encoding_def",
43
+ 100 => "future"
44
+ }
45
+
46
+ OPTIONS = {
47
+ # value => symbol # description
48
+ # Option flag values for all equation structure records:
49
+ "mtefOPT_NUDGE" => 0x08, # nudge values follow tag
50
+ # Option flag values for CHAR records:
51
+ "mtefOPT_CHAR_EMBELL" => 0x01, # character is followed by an embellishment list
52
+ "mtefOPT_CHAR_FUNC_START" => 0x02, # character starts a function (sin, cos, etc.)
53
+ "mtefOPT_CHAR_ENC_CHAR_8" => 0x04, # character is written with an 8-bit encoded value
54
+ "mtefOPT_CHAR_ENC_CHAR_16" => 0x10, # character is written with an 16-bit encoded value
55
+ "mtefOPT_CHAR_ENC_NO_MTCODE" => 0x20, # character is written without an 16-bit MTCode value
56
+ # Option flag values for LINE records:
57
+ "mtefOPT_LINE_NULL" => 0x01, # line is a placeholder only (i.e. not displayed)
58
+ "mtefOPT_LINE_LSPACE" => 0x04, # line spacing value follows tag
59
+ # Option flag values for LINE and PILE records:
60
+ "mtefOPT_LP_RULER" => 0x02, # RULER record follows LINE or PILE record
61
+ # Option flag values for COLOR_DEF records:
62
+ "mtefCOLOR_CMYK" => 0x01, # color model is CMYK, else RGB
63
+ "mtefCOLOR_SPOT" => 0x02, # color is a spot color, else a process color
64
+ "mtefCOLOR_NAME" => 0x04, # color has a name, else no name
65
+ }
66
+
67
+ ## Payload is the most important class to understand.
68
+ ## This abstraction allows recursive formats.
69
+ ## eg. lists can contain lists can contain lists.
70
+
71
+ class Payload < BinData::Choice
72
+ record_end 0 # end is a reserved keyword
73
+ record_line 1
74
+ record_char 2
75
+ record_tmpl 3
76
+ record_pile 4
77
+ record_matrix 5
78
+ record_embell 6
79
+ record_ruler 7
80
+ record_font_style_def 8
81
+ record_size 9
82
+ record_full 10
83
+ record_sub 11
84
+ record_sub2 12
85
+ record_sym 13
86
+ record_subsym 14
87
+ record_color 15
88
+ record_color_def 16
89
+ record_font_def 17
90
+ record_eqn_prefs 18
91
+ record_encoding_def 19
92
+ record_future 100
93
+ end
94
+
95
+ class NamedRecord < BinData::Record
96
+ int8 :record_type
97
+ payload :payload, :onlyif => :not_end_tag?, :selection => :record_type
98
+
99
+ def not_end_tag?
100
+ record_type != 0
101
+ end
102
+ end
103
+
104
+ class Equation < BinData::Record
105
+ endian :little
106
+ uint8 :mtef_version
107
+ uint8 :platform
108
+ uint8 :product
109
+ uint8 :product_version
110
+ uint8 :product_subversion
111
+ stringz :application_key
112
+ uint8 :equation_options
113
+
114
+ array :equation, read_until: lambda { element.record_type == 0 } do
115
+ named_record
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,34 @@
1
+ # Nudge values:
2
+ # LINE, CHAR, TMPL, PILE, MATRIX, and EMBELL records may store the result of
3
+ # nudging (small offsets applied by the user). A nudged record has the
4
+ # mtefOPT_NUDGE option (0x8) and the option byte is followed immediately by
5
+ # the nudge offset. The nudge offset consists of either two bytes or six,
6
+ # depending on the amount of offset. If -128 <= dx < +128 and
7
+ # -128 <= dy < +128, then the offsets are stored as two bytes, dx followed
8
+ # by dy, where each value has 128 added to it before it is written. Otherwise,
9
+ # two bytes of 128 are stored, followed by the offsets, dx and dy, stored as
10
+ # 16-bit values, low byte followed by high byte.
11
+
12
+ require_relative "snapshot"
13
+
14
+ module Mathtype
15
+ class Nudge < BinData::Record
16
+ include Snapshot
17
+ EXPOSED_IN_SNAPSHOT = %i(dx dy)
18
+
19
+ endian :little
20
+
21
+ int8 :_small_dx
22
+ int8 :_small_dy
23
+ int16 :_large_dx, :onlyif => lambda { _small_dx == 128 }
24
+ int16 :_large_dy, :onlyif => lambda { _small_dy == 128 }
25
+
26
+ def dx
27
+ _small_dx == 128 ? _large_dx : (_small_dx - 128)
28
+ end
29
+
30
+ def dy
31
+ _small_dy == 128 ? _large_dy : (_small_dy - 128)
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,28 @@
1
+ # PILE record (4):
2
+
3
+ # Consists of:
4
+
5
+ # record type (4)
6
+ # options
7
+ # [nudge] if mtefOPT_NUDGE is set
8
+ # [halign] horizontal alignment
9
+ # [valign] vertical alignment
10
+ # [[RULER record]] if mtefOPT_LP_RULER is set
11
+ # [object list] list of lines contained by the pile
12
+
13
+ module Mathtype
14
+ class RecordPile < BinData::Record
15
+ int8 :options
16
+
17
+ nudge :nudge, onlyif: lambda { options & OPTIONS["mtefOPT_NUDGE"] > 0 }
18
+
19
+ int8 :halign
20
+ int8 :valign
21
+
22
+ record_ruler :ruler, onlyif: lambda { options & OPTIONS["mtefOPT_LP_RULER"] > 0 }
23
+
24
+ array :object_list, read_until: lambda { element.record_type == 0 } do
25
+ named_record
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,22 @@
1
+ # RULER record (7):
2
+ # Consists of:
3
+ # record type (7)
4
+ # [n_stops] number of tab-stops
5
+ # [tab-stop list] tab-stops in order from left-to-right
6
+ # Each tab stop is described by a tab-stop type
7
+ # (0 for left, 1 for center, 2 for right, 3 for equal, 4 for decimal),
8
+ # followed by a 16-bit integer offset from the left end of the slot or pile
9
+ # with which it is associated.
10
+
11
+ module Mathtype
12
+ class RecordRuler < BinData::Record
13
+ endian :little
14
+
15
+ int8 :n_stops
16
+
17
+ array :tab_stops, initial_length: :n_stops do
18
+ int8 :tab_stop_type
19
+ int16 :tab_stop
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,44 @@
1
+ # SIZE record (9):
2
+ # Consists of one of the following cases:
3
+
4
+ # if lsize < 0 (explicit point size):
5
+ # record type (9)
6
+ # 101
7
+ # -point size (16 bit integer)
8
+ # else if -128 < dsize < +128:
9
+ # record type (9)
10
+ # lsize (typesize)
11
+ # dsize + 128
12
+ # else: (large delta)
13
+ # record type (9)
14
+ # 100
15
+ # lsize (typesize)
16
+ # dsize (16 bit integer)
17
+ # Sizes in MathType are represented as a pair of values, lsize and dsize. Lsize
18
+ # stands for "logical size", dsize for "delta size". If it is negative, it is an
19
+ # explicit point size (in 32nds of a point) negated and dsize is ignored.
20
+ # Otherwise, lsize is a typesize value and dsize is a delta from that size:
21
+ # Simple typesizes, without a delta value, are written using the records
22
+ # described in the next section.
23
+
24
+ module Mathtype
25
+ class RecordSize < BinData::Record
26
+ endian :little
27
+ int8 :lsize
28
+
29
+ uint16 :point_size, onlyif: lambda { lsize == 101 }
30
+
31
+ dsize_choice = lambda do
32
+ if lsize == 100
33
+ 100
34
+ elsif lsize != 100 && lsize != 101
35
+ 0
36
+ end
37
+ end
38
+
39
+ choice :dsize, selection: dsize_choice do
40
+ uint16 100
41
+ uint16 0
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,19 @@
1
+ require "bindata"
2
+
3
+ module Mathtype
4
+ module Snapshot
5
+ def snapshot
6
+ snapshot = BinData::Record::Snapshot.new
7
+ exposed = self.class.const_get(:EXPOSED_IN_SNAPSHOT)
8
+ exposed.each do |name|
9
+ obj = find_obj_for_name(name)
10
+ if obj
11
+ snapshot[name] = obj.snapshot if include_obj?(obj)
12
+ else
13
+ snapshot[name] = self.send(name)
14
+ end
15
+ end
16
+ snapshot
17
+ end
18
+ end
19
+ end