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
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c126bddd1633e3653d495031407818cad1f5a7c0
4
+ data.tar.gz: 8760f0a03d8fec312fdb017ff0a3fa7208aae165
5
+ SHA512:
6
+ metadata.gz: 091ecf23a9cdc5280ba0e4b7f64e6b78344a9ca46e41ee802359652b53800ff93cfed0d8c19d4bf1c29dfb76f098ddcfba17f84fb5cd867a3c8a1a545e9cc328
7
+ data.tar.gz: 9c838f8d116f8d6c7e4945f1b05b5b57fb7ef423de467285941710238de8b2e16d4c271db39e3e328f8599b8f6193c4318cdf6824400521271736d9c677ce716
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in mathtype.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Jure Triglav
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,40 @@
1
+ # Mathtype
2
+
3
+ This gem can read proprietary MathType binary equations that are usually embedded in Word documents and convert these equations into an XML form. This XML form can then be used for further processing, e.g. to convert the equation to MathML.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'mathtype'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install mathtype
20
+
21
+ ## Usage
22
+
23
+ To convert a MathType binary equation (e.g. extracted from a Word document) to an XML form:
24
+
25
+ ```
26
+ xml = Mathtype::Converter.new("equation1.bin") # to get the Nokogiri XML object
27
+ puts xml.to_xml # to get the string XML representation
28
+ ```
29
+
30
+ # Testing
31
+
32
+ Run `bundle exec rspec` to run specs.
33
+
34
+ ## Contributing
35
+
36
+ 1. Fork it ( https://github.com/[my-github-username]/mathtype/fork )
37
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
38
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
39
+ 4. Push to the branch (`git push origin my-new-feature`)
40
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,3 @@
1
+ module Mathtype
2
+ VERSION = "0.0.2"
3
+ end
data/lib/mathtype.rb ADDED
@@ -0,0 +1,61 @@
1
+ require "mathtype/version"
2
+ require "bindata"
3
+ require "ole/storage"
4
+ require "nokogiri"
5
+ require_relative "records/mtef.rb"
6
+
7
+ module Mathtype
8
+ class Converter
9
+ attr_reader :xml
10
+ attr_reader :builder
11
+ def initialize(equation)
12
+ ole = Ole::Storage.open(equation, "rb+")
13
+ eq = ole.file.read("Equation Native")[28..-1]
14
+
15
+ data = Mathtype::Equation.read(eq).snapshot
16
+ @builder = Nokogiri::XML::Builder.new do |xml|
17
+ @xml = xml
18
+ xml.root do
19
+ process(object: data)
20
+ end
21
+ end
22
+ end
23
+
24
+ def to_xml
25
+ @builder.to_xml
26
+ end
27
+
28
+ def process(element: "mtef", object:)
29
+ if object.is_a? Hash
30
+ name = Mathtype::RECORD_NAMES[object[:record_type]]
31
+ if name
32
+ xml.send(name) do
33
+ (object[:payload] || {}).each do |k, v|
34
+ process(element: k, object: v)
35
+ end
36
+ end
37
+ else
38
+ xml.send(element) do
39
+ object.each do |k, v|
40
+ process(element: k, object: v)
41
+ end
42
+ end
43
+ end
44
+ elsif object.is_a? Array
45
+ object.each do |a|
46
+ process(element: element, object: a)
47
+ end
48
+ else
49
+ process_final_element(element, object)
50
+ end
51
+ end
52
+
53
+ def process_final_element(element, object)
54
+ if object.is_a? Hash
55
+ xml.send(element, object)
56
+ else
57
+ xml.send(element) { xml.text object }
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,84 @@
1
+ # CHAR record (2):
2
+ # Consists of:
3
+ # record type (2)
4
+ # options
5
+ # [nudge] if mtefOPT_NUDGE is set
6
+ # [typeface] typeface value (signed integer; see FONT_STYLE_DEF record below)
7
+ # [character] character value (see below)
8
+ # [embellishment list] if mtefOPT_CHAR_EMBELL is set (embellishments)
9
+ # The character value itself is represented by one or more values. The presence or absence of these value is indicated by options and appear in this order:
10
+ # 16-bit integer MTCode value present unless the mtefOPT_CHAR_ENC_NO_MTCODE option is set
11
+ # 8-bit font position present if the mtefOPT_CHAR_ENC_CHAR_8 option is set
12
+ # 16-bit integer font position present if the mtefOPT_CHAR_ENC_CHAR_16 option is set
13
+ # The MTCode value defines the character independent of its font. MTCode is a superset of Unicode and is described in MTCode Encoding Tables. The 8-bit and 16-bit font positions are mutually exclusive but may both be absent. This is the position of the character within its font. Some of the common font encodings are given in Font Encoding Tables.
14
+
15
+ require_relative "snapshot"
16
+
17
+ module Mathtype
18
+ class RecordEmbell < BinData::Record; end
19
+ class RecordChar < BinData::Record
20
+ include Snapshot
21
+ EXPOSED_IN_SNAPSHOT = %i(nudge typeface mt_code_value options font_position
22
+ variation embellishment_list)
23
+
24
+ endian :little
25
+ int8 :options
26
+
27
+ nudge :nudge, onlyif: lambda { options & OPTIONS["mtefOPT_NUDGE"] > 0 }
28
+
29
+ int8 :_typeface
30
+
31
+ int16 :_mt_code_value, onlyif: (lambda do
32
+ options & OPTIONS["mtefOPT_CHAR_ENC_NO_MTCODE"] == 0
33
+ end)
34
+
35
+ font_position_choice = lambda do
36
+ char_enc_char_8 = options & OPTIONS["mtefOPT_CHAR_ENC_CHAR_8"] > 0
37
+ char_enc_char_16 = options & OPTIONS["mtefOPT_CHAR_ENC_CHAR_16"] > 0
38
+
39
+ if char_enc_char_8
40
+ 8
41
+ elsif char_enc_char_16
42
+ 16
43
+ end
44
+ end
45
+
46
+ font_position_present = lambda do
47
+ char_enc_char_8 = options & OPTIONS["mtefOPT_CHAR_ENC_CHAR_8"] > 0
48
+ char_enc_char_16 = options & OPTIONS["mtefOPT_CHAR_ENC_CHAR_16"] > 0
49
+
50
+ return true if char_enc_char_8 || char_enc_char_16
51
+ end
52
+
53
+ choice :font_position,
54
+ selection: font_position_choice,
55
+ onlyif: font_position_present do
56
+
57
+ uint8 8
58
+ uint16 16
59
+ end
60
+
61
+ array :embellishment_list,
62
+ onlyif: lambda { options & OPTIONS["mtefOPT_CHAR_EMBELL"] > 0 },
63
+ read_until: lambda { element.record_type == 0 } do
64
+ named_record
65
+ end
66
+
67
+ def mt_code_value
68
+ sprintf("0x%04X", _mt_code_value)
69
+ end
70
+
71
+ def typeface
72
+ _typeface + 128
73
+ end
74
+
75
+ def variation
76
+ case typeface
77
+ when 8
78
+ "mathmode"
79
+ when 1
80
+ "textmode"
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,13 @@
1
+ # COLOR records (15):
2
+ # Consists of:
3
+ # record type (15)
4
+ # [color_def_index] index of corresponding COLOR_DEF record (unsigned integer)
5
+ # The appearance of this record in the stream indicates that all following
6
+ # equation records (until the next COLOR record) have the color defined by the
7
+ # indicated COLOR_DEF record.
8
+
9
+ module Mathtype
10
+ class RecordColor < BinData::Record
11
+ int8 :color_def_index
12
+ end
13
+ end
@@ -0,0 +1,37 @@
1
+ # COLOR_DEF records (16):
2
+ # Consists of:
3
+ # record type (16)
4
+ # [options] model is RGB unless mtefCOLOR_CMYK bit is set; type is process
5
+ # unless mtefCOLOR_SPOT bit is set; color is unnamed unless mtefCOLOR_NAME bit is set
6
+ # [color values] if RGB, 3 values (red, green, blue); if CMYK, 4 values (cyan,
7
+ # magenta, yellow, black); see below for details
8
+ # [name] null-terminated color name appears only if mtefCOLOR_NAME is set
9
+ # This record defines a color (see Definition records). Each color value is
10
+ # written as a 16-bit integer that ranges between 0 and 1000 where 0 is the
11
+ # absence of the color and 1000 is a fully saturated color. So, an RGB color
12
+ # definition for black has all three components at 0.
13
+
14
+ module Mathtype
15
+ class RecordColorDef < BinData::Record
16
+ endian :little
17
+
18
+ int8 :options
19
+
20
+ struct :rgb, onlyif: lambda { options & OPTIONS["mtefCOLOR_CMYK"] == 0 } do
21
+ int16 :r
22
+ int16 :g
23
+ int16 :b
24
+ end
25
+
26
+ struct :cmyk, onlyif: lambda { options & OPTIONS["mtefCOLOR_CMYK"] > 0} do
27
+ int16 :c
28
+ int16 :m
29
+ int16 :y
30
+ int16 :k
31
+ end
32
+
33
+ stringz :color_name, onlyif: (lambda do
34
+ options & OPTIONS["mtefCOLOR_NAME"] > 0
35
+ end)
36
+ end
37
+ end
@@ -0,0 +1,103 @@
1
+ require_relative "snapshot"
2
+
3
+ # EMBELL record (6):
4
+ # Consists of:
5
+ # record type (6)
6
+ # options
7
+ # [nudge] if mtefOPT_NUDGE is set
8
+ # [embell] embellishment type
9
+ # The embellishment types are:
10
+
11
+ # value symbol description
12
+ # 2 emb1DOT over single dot
13
+ # 3 emb2DOT over double dot
14
+ # 4 emb3DOT over triple dot
15
+ # 5 emb1PRIME single prime
16
+ # 6 emb2PRIME double prime
17
+ # 7 embBPRIME backwards prime (left of character)
18
+ # 8 embTILDE tilde
19
+ # 9 embHAT hat (circumflex)
20
+ # 10 embNOT diagonal slash through character
21
+ # 11 embRARROW over right arrow
22
+ # 12 embLARROW over left arrow
23
+ # 13 embBARROW over both arrow (left and right)
24
+ # 14 embR1ARROW over right single-barbed arrow
25
+ # 15 embL1ARROW over left single-barbed arrow
26
+ # 16 embMBAR mid-height horizontal bar
27
+ # 17 embOBAR over-bar
28
+ # 18 emb3PRIME triple prime
29
+ # 19 embFROWN over-arc, concave downward
30
+ # 20 embSMILE over-arc, concave upward
31
+ # 21 embX_BARS double diagonal bars
32
+ # 22 embUP_BAR bottom-left to top-right diagonal bar
33
+ # 23 embDOWN_BAR top-left to bottom-right diagonal bar
34
+ # 24 emb4DOT over quad dot
35
+ # 25 embU_1DOT under single dot
36
+ # 26 embU_2DOT under double dot
37
+ # 27 embU_3DOT under triple dot
38
+ # 28 embU_4DOT under quad dot
39
+ # 29 embU_BAR under bar
40
+ # 30 embU_TILDE under tilde (~)
41
+ # 31 embU_FROWN under arc (ends point down)
42
+ # 32 embU_SMILE under arc (ends point up)
43
+ # 33 embU_RARROW under right arrow
44
+ # 34 embU_LARROW under left arrow
45
+ # 35 embU_BARROW under both arrow (left and right)
46
+ # 36 embU_R1ARROW under right arrow (1 barb)
47
+ # 37 embU_L1ARROW under left arrow (1 barb)
48
+
49
+ module Mathtype
50
+ class RecordEmbell < BinData::Record
51
+ include Snapshot
52
+ EXPOSED_IN_SNAPSHOT = %i(options nudge embell)
53
+
54
+ EMBELL = {
55
+ 2 => "emb1DOT", # over single dot
56
+ 3 => "emb2DOT", # over double dot
57
+ 4 => "emb3DOT", # over triple dot
58
+ 5 => "emb1PRIME", # single prime
59
+ 6 => "emb2PRIME", # double prime
60
+ 7 => "embBPRIME", # backwards prime (left of character)
61
+ 8 => "embTILDE", # tilde
62
+ 9 => "embHAT", # hat (circumflex)
63
+ 10 => "embNOT", # diagonal slash through character
64
+ 11 => "embRARROW", # over right arrow
65
+ 12 => "embLARROW", # over left arrow
66
+ 13 => "embBARROW", # over both arrow (left and right)
67
+ 14 => "embR1ARROW", # over right single-barbed arrow
68
+ 15 => "embL1ARROW", # over left single-barbed arrow
69
+ 16 => "embMBAR", # mid-height horizontal bar
70
+ 17 => "embOBAR", # over-bar
71
+ 18 => "emb3PRIME", # triple prime
72
+ 19 => "embFROWN", # over-arc, concave downward
73
+ 20 => "embSMILE", # over-arc, concave upward
74
+ 21 => "embX_BARS", # double diagonal bars
75
+ 22 => "embUP_BAR", # bottom-left to top-right diagonal bar
76
+ 23 => "embDOWN_BAR", # top-left to bottom-right diagonal bar
77
+ 24 => "emb4DOT", # over quad dot
78
+ 25 => "embU_1DOT", # under single dot
79
+ 26 => "embU_2DOT", # under double dot
80
+ 27 => "embU_3DOT", # under triple dot
81
+ 28 => "embU_4DOT", # under quad dot
82
+ 29 => "embU_BAR", # under bar
83
+ 30 => "embU_TILDE", # under tilde (~)
84
+ 31 => "embU_FROWN", # under arc (ends point down)
85
+ 32 => "embU_SMILE", # under arc (ends point up)
86
+ 33 => "embU_RARROW", # under right arrow
87
+ 34 => "embU_LARROW", # under left arrow
88
+ 35 => "embU_BARROW", # under both arrow (left and right)
89
+ 36 => "embU_R1ARROW", # under right arrow (1 barb)
90
+ 37 => "embU_L1ARROW", # under left arrow (1 barb)
91
+ }
92
+
93
+ int8 :options
94
+
95
+ nudge :nudge, onlyif: lambda { options & OPTIONS["mtefOPT_NUDGE"] > 0 }
96
+
97
+ int8 :_embell
98
+
99
+ def embell
100
+ EMBELL[_embell]
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,22 @@
1
+ # ENCODING_DEF records (19):
2
+ # Consists of:
3
+ # record type (19)
4
+ # [name] null-terminated encoding name
5
+ # This record defines (see Definition records) a font encoding and is referred
6
+ # to by a FONT_DEF record. In order to reduce the size of the MTEF stream,
7
+ # the following 4 encodings are predefined:
8
+
9
+ # ENCODING_DEF index encoding name
10
+ # 1 MTCode
11
+ # 2 Unknown
12
+ # 3 Symbol
13
+ # 4 MTExtra
14
+ # This means that the first ENCODING_DEF record in the MTEF stream is considered
15
+ # to have an index of 5. See Extending MathType's Font and Character Information
16
+ # and MathType's Character Encodings for more information on font encodings.
17
+
18
+ module Mathtype
19
+ class RecordEncodingDef < BinData::Record
20
+ stringz :name
21
+ end
22
+ end
@@ -0,0 +1,8 @@
1
+ module Mathtype
2
+ class RecordEnd < BinData::Primitive
3
+ def get; ""; end
4
+ def set(v); end
5
+
6
+ def to_formatted_s(indent = 0); to_s; end
7
+ end
8
+ end
@@ -0,0 +1,44 @@
1
+ # EQN_PREFS records (18):
2
+
3
+ # Consists of:
4
+
5
+ # record type (18)
6
+ # [options] none defined in this version of MTEF
7
+ # [sizes] dimension array for typesize definitions
8
+ # [spaces] dimension array for spacing definitions (see below)
9
+ # [styles] array of style definitions (see below)
10
+ # When reading arrays, the number of values may be less than or greater than
11
+ # expected. MTEF readers should be driven by the array count.
12
+ # If the array is shorter than expected, assume defaults for the missing values.
13
+ # If the array is longer than expected, the extra values must be skipped to stay
14
+ # in sync with the MTEF stream.
15
+
16
+ module Mathtype
17
+ class Entry < BinData::Record
18
+ bit4 :unit
19
+ array :nibbles, read_until: lambda { element == 0xF } do
20
+ bit4
21
+ end
22
+ resume_byte_alignment
23
+ end
24
+
25
+ class RecordEqnPrefs < BinData::Record
26
+ int8 :options
27
+
28
+ int8 :sizes_count
29
+ array :sizes, initial_length: :sizes_count do
30
+ entry
31
+ end
32
+
33
+ int8 :spaces_count
34
+ array :spaces, initial_length: :spaces_count do
35
+ entry
36
+ end
37
+
38
+ int8 :styles_count
39
+ array :styles, initial_length: :styles_count do
40
+ int8 :font_def
41
+ int8 :font_style, onlyif: lambda { font_def != 0x00 }
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,14 @@
1
+ # FONT_DEF records (17):
2
+ # Consists of:
3
+ # record type (17)
4
+ # [enc_def_index] index of corresponding ENCODING_DEF record (unsigned integer)
5
+ # [name] null-terminated font name
6
+ # This record associates an font encoding with a font name. See Definition
7
+ # records.
8
+
9
+ module Mathtype
10
+ class RecordFontDef < BinData::Record
11
+ uint8 :enc_def_index
12
+ stringz :font_name
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ # FONT_STYLE_DEF record (8):
2
+ # Consists of:
3
+ # record type (8)
4
+ # [font_def_index] index of mtefFONT_DEF record (unsigned integer)
5
+ # [char_style] character style bits
6
+ # This record associates a character style with a font. See Definition records.
7
+
8
+ module Mathtype
9
+ class RecordFontStyleDef < BinData::Record
10
+ uint8 :font_def_index
11
+
12
+ int8 :char_style
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ # If the record type is 100 or greater, it represents a record that will be
2
+ # defined in a future version of MTEF. For now, readers can assume that an
3
+ # unsigned integer follows the record type and is the number of bytes following
4
+ # it in the record (i.e. it doesn't include the record type and length). This
5
+ # makes it easy for software that reads MTEF to skip these records. Although it
6
+ # might be handy if all records had such a length value, it will only be present
7
+ # on future expansion records (i.e. those with record types >= 100).
8
+
9
+ module Mathtype
10
+ class RecordFuture < BinData::Record
11
+ uint8 :skip
12
+ skip length: :skip
13
+ end
14
+ end
@@ -0,0 +1,36 @@
1
+ # LINE record (1):
2
+ # Consists of:
3
+ # record type (1)
4
+ # options
5
+ # [nudge] if mtefOPT_NUDGE is set
6
+ # [line spacing] if mtefOPT_LINE_LSPACE is set (16-bit integer)
7
+ # [RULER record] if mtefOPT_LP_RULER is set
8
+ # object list of line (single pile, characters and templates, or nothing)
9
+ # The line spacing value, if present, is the distance between the baseline of
10
+ # this line and the line above it.
11
+
12
+ module Mathtype
13
+ class NamedRecord < BinData::Record; end
14
+ class RecordLine < BinData::Record
15
+ endian :little
16
+ int8 :options
17
+
18
+ nudge :nudge, onlyif: lambda { options & OPTIONS["mtefOPT_NUDGE"] > 0 }
19
+
20
+ int16 :line_spacing, onlyif: (lambda do
21
+ options & OPTIONS["mtefOPT_LINE_LSPACE"] > 0
22
+ end)
23
+
24
+ record_ruler :ruler, onlyif: (lambda do
25
+ options & OPTIONS["mtefOPT_LP_RULER"] > 0
26
+ end)
27
+
28
+ array :object_list,
29
+ onlyif: lambda { options & OPTIONS["mtefOPT_LINE_NULL"] == 0 },
30
+ read_until: lambda { element.record_type == 0 } do
31
+ named_record
32
+ end
33
+
34
+ def to_formatted_s(indent = 0); to_s; end
35
+ end
36
+ end
@@ -0,0 +1,41 @@
1
+ # PILE record (4):
2
+ # Consists of:
3
+ # record type (4)
4
+ # options
5
+ # [nudge] if mtefOPT_NUDGE is set
6
+ # [halign] horizontal alignment
7
+ # [valign] vertical alignment
8
+ # [[RULER record]] if mtefOPT_LP_RULER is set
9
+ # [object list] list of lines contained by the pile
10
+
11
+ # The row partition line type list consists of two-bit values for each possible
12
+ # partition line (one more than the number of rows), rounded out to the nearest
13
+ # byte. Each value determines the line style of the corresponding partition line
14
+ # (0 for none, 1 for solid, 2 for dashed, or 3 for dotted). Similarly for the
15
+ # column partition lines.
16
+
17
+ module Mathtype
18
+ class RecordMatrix < BinData::Record
19
+ int8 :options
20
+
21
+ nudge :nudge, onlyif: lambda { options & OPTIONS["mtefOPT_NUDGE"] > 0 }
22
+
23
+ int8 :valign
24
+ int8 :h_just
25
+ int8 :v_just
26
+ int8 :rows
27
+ int8 :cols
28
+
29
+ array :row_parts, initial_length: lambda { rows + 1 } do
30
+ bit nbits: 2
31
+ end
32
+
33
+ array :col_parts, initial_length: lambda { cols + 1 } do
34
+ bit nbits: 2
35
+ end
36
+
37
+ array :object_list, read_until: lambda { element.record_type == 0 } do
38
+ named_record
39
+ end
40
+ end
41
+ end