symbol.dart
2.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
part of '../functions.dart';
EncodeResult _symbolEncoder(GreenNode node) {
final symbolNode = node as SymbolNode;
final symbol = symbolNode.symbol;
final mode = symbolNode.mode;
final encodeAsBaseSymbol = _baseSymbolEncoder(
symbol,
mode,
symbolNode.overrideFont,
symbolNode.atomType,
symbolNode.overrideAtomType,
);
if (encodeAsBaseSymbol != null) {
return StaticEncodeResult(encodeAsBaseSymbol);
}
if (mode == Mode.math && negatedOperatorSymbols.containsKey(symbol)) {
final encodeAsNegatedOp =
_baseSymbolEncoder(negatedOperatorSymbols[symbol]![1], Mode.math);
if (encodeAsNegatedOp != null) {
return StaticEncodeResult('\\not $encodeAsNegatedOp');
}
}
return NonStrictEncodeResult(
'unknown symbol',
'Unrecognized symbol encountered during TeX encoding: '
'${unicodeLiteral(symbol)} with mode $mode type ${symbolNode.atomType} '
'font ${symbolNode.overrideFont?.fontName}',
StaticEncodeResult(symbolNode.symbol),
);
}
String? _baseSymbolEncoder(String symbol, Mode mode,
[FontOptions? overrideFont, AtomType? type, AtomType? overrideType]) {
// For alpha-numeric and unescaped symbols, provide a fast track
if (overrideFont == null && overrideType == null && symbol.length == 1) {
if (isAlphaNumericUnit(symbol) ||
const {
'!', '*', '(', ')', '-', '+', '=', //
'|', ':', ';', "'", '"', ',', '<', '.', '>', '?', '/'
}.contains(symbol)) {
return symbol;
}
}
final candidates = <MapEntry<String, TexSymbolConfig>>[];
if (mode != Mode.text) {
candidates.addAll(
texSymbolCommandConfigs[Mode.math]!
.entries
.where((entry) => entry.value.symbol == symbol),
);
}
if (mode != Mode.math) {
candidates.addAll(
texSymbolCommandConfigs[Mode.text]!
.entries
.where((entry) => entry.value.symbol == symbol),
);
}
candidates.sortBy<num>((candidate) {
final candidFont = candidate.value.font;
final fontScore = candidFont == overrideFont
? 1000
: (candidFont?.fontFamily == overrideFont?.fontFamily ? 500 : 0) +
(candidFont?.fontShape == overrideFont?.fontShape ? 300 : 0) +
(candidFont?.fontWeight == overrideFont?.fontWeight ? 200 : 0);
final typeScore = candidate.value.type == overrideType
? 150
: candidate.value.type == type
? 100
: 0;
final commandConciseness = 100 ~/ candidate.key.length -
100 *
candidate.key.runes
.where((point) => point > 126 || point < 32)
.length;
return fontScore + typeScore + commandConciseness;
});
return candidates.lastOrNull?.key;
}