Skip to content

Commit 3746b5f

Browse files
committed
Add all fences and integrals, account for situations where a simple bitmask is not sufficient to check variation conditions, e.g. 0x2 and 0x3 are both present in 0x33, while only 0x3 is the correct option.
1 parent 231734a commit 3746b5f

25 files changed

+4085
-93
lines changed

lib/mathtype/version.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
module Mathtype
2-
VERSION = "0.0.5"
2+
VERSION = "0.0.6"
33
end

lib/records/char.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,10 @@ def typeface
8080

8181
def variation
8282
case typeface
83-
when 8
84-
"mathmode"
85-
when 1
83+
when 1, 9, 10
8684
"textmode"
85+
else
86+
"mathmode"
8787
end
8888
end
8989
end

lib/records/tmpl.rb

Lines changed: 74 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,13 @@ class RecordTmpl < BinData::Record
251251
37 => "tmBOX"
252252
}
253253

254+
255+
# When options overlap in the binary space, ordinary bitmasks
256+
# are not the correct tool to use for detection. We use digit
257+
# position and presence instead.
258+
259+
DIGIT_MODE_VARIATIONS = [9]
260+
254261
# Top-level keys are template identifiers, defined in TEMPLATES.
255262
# Second-level keys are bits for certain variations, negative keys mean
256263
# that the variation is present if the bit is absent.
@@ -264,20 +271,26 @@ class RecordTmpl < BinData::Record
264271

265272
# Intervals:
266273
9 => {
267-
0x0000 => "tvINTV_LEFT_LP", # left fence is left parenthesis
268-
0x0001 => "tvINTV_LEFT_RP", # left fence is right parenthesis
269-
0x0002 => "tvINTV_LEFT_LB", # left fence is left bracket
270-
0x0003 => "tvINTV_LEFT_RB", # left fence is right bracket
271-
0x0004 => "tvINTV_RIGHT_LP", # right fence is left parenthesis # WARNING: DOCUMENTATION SAYS 0x0000?
272-
0x0010 => "tvINTV_RIGHT_RP", # right fence is right parenthesis
273-
0x0020 => "tvINTV_RIGHT_LB", # right fence is left bracket
274-
0x0030 => "tvINTV_RIGHT_RB", # right fence is right bracket
275-
# Added to match MathML translator
276-
0x0022 => "tvINTV_LBLB",
277-
0x0033 => "tvINTV_RBRB",
278-
0x0023 => "tvINTV_RBLB",
279-
0x0012 => "tvINTV_LBRP",
280-
0x0030 => "tvINTV_LPRB"
274+
# 0x0000 => "tvINTV_LEFT_LP", # left fence is left parenthesis
275+
# 0x0001 => "tvINTV_LEFT_RP", # left fence is right parenthesis
276+
# 0x0002 => "tvINTV_LEFT_LB", # left fence is left bracket
277+
# 0x0003 => "tvINTV_LEFT_RB", # left fence is right bracket
278+
# 0x0004 => "tvINTV_RIGHT_LP", # right fence is left parenthesis # WARNING: DOCUMENTATION SAYS 0x0000?
279+
# 0x0010 => "tvINTV_RIGHT_RP", # right fence is right parenthesis
280+
# 0x0020 => "tvINTV_RIGHT_LB", # right fence is left bracket
281+
# 0x0030 => "tvINTV_RIGHT_RB", # right fence is right bracket
282+
# Replaced above to match MathML translator
283+
0x0002 => {
284+
0x0020 => "tvINTV_LBLB", # left bracket, left bracket
285+
0x0010 => "tvINTV_LBRP", # left bracket, right parenthesis
286+
},
287+
0x0003 => {
288+
0x0030 => "tvINTV_RBRB", # right bracket, right bracket
289+
0x0020 => "tvINTV_RBLB", # right bracket, left bracket
290+
},
291+
0x0000 => {
292+
0x0030 => "tvINTV_LPRB", # left parenthesis, right bracket
293+
}
281294
},
282295

283296
# Radicals (square and nth roots):
@@ -415,28 +428,26 @@ class RecordTmpl < BinData::Record
415428
end
416429

417430
def variation
418-
variation = (_variation_first_byte & 0x7F) | (_variation_second_byte << 8)
419-
variations = VARIATIONS.select do |selector, _|
431+
@variation = (_variation_first_byte & 0x7F) | (_variation_second_byte << 8)
432+
@variations = VARIATIONS.select do |selector, _|
420433
selector === _selector
421434
end.values.reduce(Hash.new, :merge)
422435

423-
process_variations(variation, variations)
436+
process_variations
424437
end
425438

426-
def process_variations(variation, variations)
427-
variations.select do |bit, value|
428-
# bit should NOT be active
429-
if bit < 0
430-
variation & -bit == 0
431-
# bit should be active
432-
else
433-
variation & bit == bit
439+
def process_variations
440+
@variations.select do |flag, _|
441+
if flag < 0 # flag should NOT be active
442+
!check_flag(-flag)
443+
else # flag should be active
444+
check_flag(flag)
434445
end
435-
end.map do |bit, value|
446+
end.map do |flag, value|
436447
case value
437448
when Hash # Conditional variations
438-
result = value.detect do |conditional, value|
439-
variation & conditional == conditional
449+
result = value.detect do |conditional, _|
450+
check_flag(conditional)
440451
end
441452
result.last if result
442453
else
@@ -445,6 +456,41 @@ def process_variations(variation, variations)
445456
end.uniq
446457
end
447458

459+
def check_flag(flag)
460+
case mode
461+
when :bitmask
462+
check_bitmask(flag)
463+
when :digit
464+
check_digit(flag)
465+
end
466+
end
467+
468+
def check_bitmask(flag)
469+
if flag == 0
470+
@variation & 0xf == 0
471+
else
472+
@variation & flag == flag
473+
end
474+
end
475+
476+
# E.g. is 0x3 present in 0x33
477+
def check_digit(flag)
478+
digits = if flag == 0
479+
1
480+
else
481+
(Math.log(flag+1)/Math.log(16)).ceil # digits in a hex number
482+
end
483+
mask = (15<<(4*digits-4)) # e.g. 0xf0
484+
variation_digit = (@variation & mask) >> (digits * 4 - 4)
485+
flag_digit = (flag & mask) >> (digits * 4 - 4)
486+
variation_digit == flag_digit
487+
end
488+
489+
490+
def mode
491+
DIGIT_MODE_VARIATIONS.include?(selector) ? :digit : :bitmask
492+
end
493+
448494
def selector
449495
SELECTORS[_selector]
450496
end

0 commit comments

Comments
 (0)