mathtype 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +14 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +40 -0
- data/Rakefile +2 -0
- data/lib/mathtype/version.rb +3 -0
- data/lib/mathtype.rb +61 -0
- data/lib/records/char.rb +84 -0
- data/lib/records/color.rb +13 -0
- data/lib/records/color_def.rb +37 -0
- data/lib/records/embell.rb +103 -0
- data/lib/records/encoding_def.rb +22 -0
- data/lib/records/end.rb +8 -0
- data/lib/records/eqn_prefs.rb +44 -0
- data/lib/records/font_def.rb +14 -0
- data/lib/records/font_style_def.rb +14 -0
- data/lib/records/future.rb +14 -0
- data/lib/records/line.rb +36 -0
- data/lib/records/matrix.rb +41 -0
- data/lib/records/mtef.rb +118 -0
- data/lib/records/nudge.rb +34 -0
- data/lib/records/pile.rb +28 -0
- data/lib/records/ruler.rb +22 -0
- data/lib/records/size.rb +44 -0
- data/lib/records/snapshot.rb +19 -0
- data/lib/records/tmpl.rb +449 -0
- data/lib/records/typesizes.rb +24 -0
- data/mathtype.gemspec +28 -0
- data/spec/fixtures/expected/embelishments.xml +848 -0
- data/spec/fixtures/expected/equation1.xml +492 -0
- data/spec/fixtures/expected/equation10.xml +369 -0
- data/spec/fixtures/expected/equation11.xml +370 -0
- data/spec/fixtures/expected/equation12.xml +433 -0
- data/spec/fixtures/expected/equation13.xml +680 -0
- data/spec/fixtures/expected/equation2.xml +429 -0
- data/spec/fixtures/expected/equation3.xml +1374 -0
- data/spec/fixtures/expected/equation4.xml +360 -0
- data/spec/fixtures/expected/equation5.xml +377 -0
- data/spec/fixtures/expected/equation6.xml +364 -0
- data/spec/fixtures/expected/equation7.xml +369 -0
- data/spec/fixtures/expected/equation8.xml +362 -0
- data/spec/fixtures/expected/equation9.xml +355 -0
- data/spec/fixtures/input/embelishments.bin +0 -0
- data/spec/fixtures/input/equation1.bin +0 -0
- data/spec/fixtures/input/equation10.bin +0 -0
- data/spec/fixtures/input/equation11.bin +0 -0
- data/spec/fixtures/input/equation12.bin +0 -0
- data/spec/fixtures/input/equation13.bin +0 -0
- data/spec/fixtures/input/equation2.bin +0 -0
- data/spec/fixtures/input/equation3.bin +0 -0
- data/spec/fixtures/input/equation4.bin +0 -0
- data/spec/fixtures/input/equation5.bin +0 -0
- data/spec/fixtures/input/equation6.bin +0 -0
- data/spec/fixtures/input/equation7.bin +0 -0
- data/spec/fixtures/input/equation8.bin +0 -0
- data/spec/fixtures/input/equation9.bin +0 -0
- data/spec/mathtype_spec.rb +16 -0
- data/spec/spec_helper.rb +64 -0
- 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
data/.rspec
ADDED
data/Gemfile
ADDED
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
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
|
data/lib/records/char.rb
ADDED
@@ -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
|
data/lib/records/end.rb
ADDED
@@ -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
|
data/lib/records/line.rb
ADDED
@@ -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
|