docling 2.25.2__py3-none-any.whl → 2.27.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- docling/backend/asciidoc_backend.py +1 -1
- docling/backend/csv_backend.py +1 -1
- docling/backend/docling_parse_backend.py +21 -13
- docling/backend/docling_parse_v2_backend.py +20 -12
- docling/backend/docling_parse_v4_backend.py +185 -0
- docling/backend/docx/__init__.py +0 -0
- docling/backend/docx/latex/__init__.py +0 -0
- docling/backend/docx/latex/latex_dict.py +271 -0
- docling/backend/docx/latex/omml.py +453 -0
- docling/backend/html_backend.py +7 -7
- docling/backend/md_backend.py +1 -1
- docling/backend/msexcel_backend.py +2 -45
- docling/backend/mspowerpoint_backend.py +1 -1
- docling/backend/msword_backend.py +65 -3
- docling/backend/pdf_backend.py +7 -2
- docling/backend/pypdfium2_backend.py +52 -30
- docling/backend/xml/uspto_backend.py +1 -1
- docling/cli/main.py +62 -23
- docling/cli/models.py +1 -1
- docling/datamodel/base_models.py +8 -10
- docling/datamodel/pipeline_options.py +27 -31
- docling/document_converter.py +5 -5
- docling/models/base_model.py +9 -1
- docling/models/base_ocr_model.py +27 -16
- docling/models/code_formula_model.py +84 -5
- docling/models/document_picture_classifier.py +1 -1
- docling/models/easyocr_model.py +28 -13
- docling/models/factories/__init__.py +27 -0
- docling/models/factories/base_factory.py +122 -0
- docling/models/factories/ocr_factory.py +11 -0
- docling/models/factories/picture_description_factory.py +11 -0
- docling/models/ocr_mac_model.py +39 -11
- docling/models/page_preprocessing_model.py +4 -0
- docling/models/picture_description_api_model.py +20 -3
- docling/models/picture_description_base_model.py +19 -3
- docling/models/picture_description_vlm_model.py +14 -2
- docling/models/plugins/__init__.py +0 -0
- docling/models/plugins/defaults.py +28 -0
- docling/models/rapid_ocr_model.py +34 -13
- docling/models/table_structure_model.py +14 -5
- docling/models/tesseract_ocr_cli_model.py +40 -15
- docling/models/tesseract_ocr_model.py +37 -12
- docling/pipeline/standard_pdf_pipeline.py +25 -78
- docling/utils/export.py +8 -6
- docling/utils/layout_postprocessor.py +26 -23
- docling/utils/visualization.py +1 -1
- {docling-2.25.2.dist-info → docling-2.27.0.dist-info}/METADATA +48 -19
- docling-2.27.0.dist-info/RECORD +83 -0
- {docling-2.25.2.dist-info → docling-2.27.0.dist-info}/entry_points.txt +3 -0
- docling-2.25.2.dist-info/RECORD +0 -72
- {docling-2.25.2.dist-info → docling-2.27.0.dist-info}/LICENSE +0 -0
- {docling-2.25.2.dist-info → docling-2.27.0.dist-info}/WHEEL +0 -0
@@ -380,7 +380,7 @@ class AsciiDocBackend(DeclarativeDocumentBackend):
|
|
380
380
|
end_row_offset_idx=row_idx + row_span,
|
381
381
|
start_col_offset_idx=col_idx,
|
382
382
|
end_col_offset_idx=col_idx + col_span,
|
383
|
-
|
383
|
+
column_header=row_idx == 0,
|
384
384
|
row_header=False,
|
385
385
|
)
|
386
386
|
data.table_cells.append(cell)
|
docling/backend/csv_backend.py
CHANGED
@@ -111,7 +111,7 @@ class CsvDocumentBackend(DeclarativeDocumentBackend):
|
|
111
111
|
end_row_offset_idx=row_idx + 1,
|
112
112
|
start_col_offset_idx=col_idx,
|
113
113
|
end_col_offset_idx=col_idx + 1,
|
114
|
-
|
114
|
+
column_header=row_idx == 0, # First row as header
|
115
115
|
row_header=False,
|
116
116
|
)
|
117
117
|
table_data.table_cells.append(cell)
|
@@ -6,12 +6,12 @@ from typing import Iterable, List, Optional, Union
|
|
6
6
|
|
7
7
|
import pypdfium2 as pdfium
|
8
8
|
from docling_core.types.doc import BoundingBox, CoordOrigin, Size
|
9
|
+
from docling_core.types.doc.page import BoundingRectangle, SegmentedPdfPage, TextCell
|
9
10
|
from docling_parse.pdf_parsers import pdf_parser_v1
|
10
11
|
from PIL import Image, ImageDraw
|
11
12
|
from pypdfium2 import PdfPage
|
12
13
|
|
13
14
|
from docling.backend.pdf_backend import PdfDocumentBackend, PdfPageBackend
|
14
|
-
from docling.datamodel.base_models import Cell
|
15
15
|
from docling.datamodel.document import InputDocument
|
16
16
|
|
17
17
|
_log = logging.getLogger(__name__)
|
@@ -68,8 +68,11 @@ class DoclingParsePageBackend(PdfPageBackend):
|
|
68
68
|
|
69
69
|
return text_piece
|
70
70
|
|
71
|
-
def
|
72
|
-
|
71
|
+
def get_segmented_page(self) -> Optional[SegmentedPdfPage]:
|
72
|
+
return None
|
73
|
+
|
74
|
+
def get_text_cells(self) -> Iterable[TextCell]:
|
75
|
+
cells: List[TextCell] = []
|
73
76
|
cell_counter = 0
|
74
77
|
|
75
78
|
if not self.valid:
|
@@ -91,19 +94,24 @@ class DoclingParsePageBackend(PdfPageBackend):
|
|
91
94
|
|
92
95
|
text_piece = self._dpage["cells"][i]["content"]["rnormalized"]
|
93
96
|
cells.append(
|
94
|
-
|
95
|
-
|
97
|
+
TextCell(
|
98
|
+
index=cell_counter,
|
96
99
|
text=text_piece,
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
100
|
+
orig=text_piece,
|
101
|
+
from_ocr=False,
|
102
|
+
rect=BoundingRectangle.from_bounding_box(
|
103
|
+
BoundingBox(
|
104
|
+
# l=x0, b=y0, r=x1, t=y1,
|
105
|
+
l=x0 * page_size.width / parser_width,
|
106
|
+
b=y0 * page_size.height / parser_height,
|
107
|
+
r=x1 * page_size.width / parser_width,
|
108
|
+
t=y1 * page_size.height / parser_height,
|
109
|
+
coord_origin=CoordOrigin.BOTTOMLEFT,
|
110
|
+
)
|
104
111
|
).to_top_left_origin(page_size.height),
|
105
112
|
)
|
106
113
|
)
|
114
|
+
|
107
115
|
cell_counter += 1
|
108
116
|
|
109
117
|
def draw_clusters_and_cells():
|
@@ -112,7 +120,7 @@ class DoclingParsePageBackend(PdfPageBackend):
|
|
112
120
|
) # make new image to avoid drawing on the saved ones
|
113
121
|
draw = ImageDraw.Draw(image)
|
114
122
|
for c in cells:
|
115
|
-
x0, y0, x1, y1 = c.
|
123
|
+
x0, y0, x1, y1 = c.rect.to_bounding_box().as_tuple()
|
116
124
|
cell_color = (
|
117
125
|
random.randint(30, 140),
|
118
126
|
random.randint(30, 140),
|
@@ -6,12 +6,13 @@ from typing import TYPE_CHECKING, Iterable, List, Optional, Union
|
|
6
6
|
|
7
7
|
import pypdfium2 as pdfium
|
8
8
|
from docling_core.types.doc import BoundingBox, CoordOrigin
|
9
|
+
from docling_core.types.doc.page import BoundingRectangle, SegmentedPdfPage, TextCell
|
9
10
|
from docling_parse.pdf_parsers import pdf_parser_v2
|
10
11
|
from PIL import Image, ImageDraw
|
11
12
|
from pypdfium2 import PdfPage
|
12
13
|
|
13
14
|
from docling.backend.pdf_backend import PdfDocumentBackend, PdfPageBackend
|
14
|
-
from docling.datamodel.base_models import
|
15
|
+
from docling.datamodel.base_models import Size
|
15
16
|
from docling.utils.locks import pypdfium2_lock
|
16
17
|
|
17
18
|
if TYPE_CHECKING:
|
@@ -78,8 +79,11 @@ class DoclingParseV2PageBackend(PdfPageBackend):
|
|
78
79
|
|
79
80
|
return text_piece
|
80
81
|
|
81
|
-
def
|
82
|
-
|
82
|
+
def get_segmented_page(self) -> Optional[SegmentedPdfPage]:
|
83
|
+
return None
|
84
|
+
|
85
|
+
def get_text_cells(self) -> Iterable[TextCell]:
|
86
|
+
cells: List[TextCell] = []
|
83
87
|
cell_counter = 0
|
84
88
|
|
85
89
|
if not self.valid:
|
@@ -106,16 +110,20 @@ class DoclingParseV2PageBackend(PdfPageBackend):
|
|
106
110
|
|
107
111
|
text_piece = cell_data[cells_header.index("text")]
|
108
112
|
cells.append(
|
109
|
-
|
110
|
-
|
113
|
+
TextCell(
|
114
|
+
index=cell_counter,
|
111
115
|
text=text_piece,
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
116
|
+
orig=text_piece,
|
117
|
+
from_ocr=False,
|
118
|
+
rect=BoundingRectangle.from_bounding_box(
|
119
|
+
BoundingBox(
|
120
|
+
# l=x0, b=y0, r=x1, t=y1,
|
121
|
+
l=x0 * page_size.width / parser_width,
|
122
|
+
b=y0 * page_size.height / parser_height,
|
123
|
+
r=x1 * page_size.width / parser_width,
|
124
|
+
t=y1 * page_size.height / parser_height,
|
125
|
+
coord_origin=CoordOrigin.BOTTOMLEFT,
|
126
|
+
)
|
119
127
|
).to_top_left_origin(page_size.height),
|
120
128
|
)
|
121
129
|
)
|
@@ -0,0 +1,185 @@
|
|
1
|
+
import logging
|
2
|
+
import random
|
3
|
+
from io import BytesIO
|
4
|
+
from pathlib import Path
|
5
|
+
from typing import TYPE_CHECKING, Iterable, List, Optional, Union
|
6
|
+
|
7
|
+
import pypdfium2 as pdfium
|
8
|
+
from docling_core.types.doc import BoundingBox, CoordOrigin
|
9
|
+
from docling_core.types.doc.page import SegmentedPdfPage, TextCell
|
10
|
+
from docling_parse.pdf_parser import DoclingPdfParser, PdfDocument
|
11
|
+
from PIL import Image, ImageDraw
|
12
|
+
from pypdfium2 import PdfPage
|
13
|
+
|
14
|
+
from docling.backend.pdf_backend import PdfDocumentBackend, PdfPageBackend
|
15
|
+
from docling.datamodel.base_models import Size
|
16
|
+
from docling.utils.locks import pypdfium2_lock
|
17
|
+
|
18
|
+
if TYPE_CHECKING:
|
19
|
+
from docling.datamodel.document import InputDocument
|
20
|
+
|
21
|
+
_log = logging.getLogger(__name__)
|
22
|
+
|
23
|
+
|
24
|
+
class DoclingParseV4PageBackend(PdfPageBackend):
|
25
|
+
def __init__(self, parsed_page: SegmentedPdfPage, page_obj: PdfPage):
|
26
|
+
self._ppage = page_obj
|
27
|
+
self._dpage = parsed_page
|
28
|
+
self.valid = parsed_page is not None
|
29
|
+
|
30
|
+
def is_valid(self) -> bool:
|
31
|
+
return self.valid
|
32
|
+
|
33
|
+
def get_text_in_rect(self, bbox: BoundingBox) -> str:
|
34
|
+
# Find intersecting cells on the page
|
35
|
+
text_piece = ""
|
36
|
+
page_size = self.get_size()
|
37
|
+
|
38
|
+
scale = (
|
39
|
+
1 # FIX - Replace with param in get_text_in_rect across backends (optional)
|
40
|
+
)
|
41
|
+
|
42
|
+
for i, cell in enumerate(self._dpage.textline_cells):
|
43
|
+
cell_bbox = (
|
44
|
+
cell.rect.to_bounding_box()
|
45
|
+
.to_top_left_origin(page_height=page_size.height)
|
46
|
+
.scaled(scale)
|
47
|
+
)
|
48
|
+
|
49
|
+
overlap_frac = cell_bbox.intersection_area_with(bbox) / cell_bbox.area()
|
50
|
+
|
51
|
+
if overlap_frac > 0.5:
|
52
|
+
if len(text_piece) > 0:
|
53
|
+
text_piece += " "
|
54
|
+
text_piece += cell.text
|
55
|
+
|
56
|
+
return text_piece
|
57
|
+
|
58
|
+
def get_segmented_page(self) -> Optional[SegmentedPdfPage]:
|
59
|
+
return self._dpage
|
60
|
+
|
61
|
+
def get_text_cells(self) -> Iterable[TextCell]:
|
62
|
+
page_size = self.get_size()
|
63
|
+
|
64
|
+
[tc.to_top_left_origin(page_size.height) for tc in self._dpage.textline_cells]
|
65
|
+
|
66
|
+
# for cell in self._dpage.textline_cells:
|
67
|
+
# rect = cell.rect
|
68
|
+
#
|
69
|
+
# assert (
|
70
|
+
# rect.to_bounding_box().l <= rect.to_bounding_box().r
|
71
|
+
# ), f"left is > right on bounding box {rect.to_bounding_box()} of rect {rect}"
|
72
|
+
# assert (
|
73
|
+
# rect.to_bounding_box().t <= rect.to_bounding_box().b
|
74
|
+
# ), f"top is > bottom on bounding box {rect.to_bounding_box()} of rect {rect}"
|
75
|
+
|
76
|
+
return self._dpage.textline_cells
|
77
|
+
|
78
|
+
def get_bitmap_rects(self, scale: float = 1) -> Iterable[BoundingBox]:
|
79
|
+
AREA_THRESHOLD = 0 # 32 * 32
|
80
|
+
|
81
|
+
images = self._dpage.bitmap_resources
|
82
|
+
|
83
|
+
for img in images:
|
84
|
+
cropbox = img.rect.to_bounding_box().to_top_left_origin(
|
85
|
+
self.get_size().height
|
86
|
+
)
|
87
|
+
|
88
|
+
if cropbox.area() > AREA_THRESHOLD:
|
89
|
+
cropbox = cropbox.scaled(scale=scale)
|
90
|
+
|
91
|
+
yield cropbox
|
92
|
+
|
93
|
+
def get_page_image(
|
94
|
+
self, scale: float = 1, cropbox: Optional[BoundingBox] = None
|
95
|
+
) -> Image.Image:
|
96
|
+
|
97
|
+
page_size = self.get_size()
|
98
|
+
|
99
|
+
if not cropbox:
|
100
|
+
cropbox = BoundingBox(
|
101
|
+
l=0,
|
102
|
+
r=page_size.width,
|
103
|
+
t=0,
|
104
|
+
b=page_size.height,
|
105
|
+
coord_origin=CoordOrigin.TOPLEFT,
|
106
|
+
)
|
107
|
+
padbox = BoundingBox(
|
108
|
+
l=0, r=0, t=0, b=0, coord_origin=CoordOrigin.BOTTOMLEFT
|
109
|
+
)
|
110
|
+
else:
|
111
|
+
padbox = cropbox.to_bottom_left_origin(page_size.height).model_copy()
|
112
|
+
padbox.r = page_size.width - padbox.r
|
113
|
+
padbox.t = page_size.height - padbox.t
|
114
|
+
|
115
|
+
image = (
|
116
|
+
self._ppage.render(
|
117
|
+
scale=scale * 1.5,
|
118
|
+
rotation=0, # no additional rotation
|
119
|
+
crop=padbox.as_tuple(),
|
120
|
+
)
|
121
|
+
.to_pil()
|
122
|
+
.resize(size=(round(cropbox.width * scale), round(cropbox.height * scale)))
|
123
|
+
) # We resize the image from 1.5x the given scale to make it sharper.
|
124
|
+
|
125
|
+
return image
|
126
|
+
|
127
|
+
def get_size(self) -> Size:
|
128
|
+
return Size(
|
129
|
+
width=self._dpage.dimension.width,
|
130
|
+
height=self._dpage.dimension.height,
|
131
|
+
)
|
132
|
+
|
133
|
+
def unload(self):
|
134
|
+
self._ppage = None
|
135
|
+
self._dpage = None
|
136
|
+
|
137
|
+
|
138
|
+
class DoclingParseV4DocumentBackend(PdfDocumentBackend):
|
139
|
+
def __init__(self, in_doc: "InputDocument", path_or_stream: Union[BytesIO, Path]):
|
140
|
+
super().__init__(in_doc, path_or_stream)
|
141
|
+
|
142
|
+
with pypdfium2_lock:
|
143
|
+
self._pdoc = pdfium.PdfDocument(self.path_or_stream)
|
144
|
+
self.parser = DoclingPdfParser(loglevel="fatal")
|
145
|
+
self.dp_doc: PdfDocument = self.parser.load(path_or_stream=self.path_or_stream)
|
146
|
+
success = self.dp_doc is not None
|
147
|
+
|
148
|
+
if not success:
|
149
|
+
raise RuntimeError(
|
150
|
+
f"docling-parse v4 could not load document {self.document_hash}."
|
151
|
+
)
|
152
|
+
|
153
|
+
def page_count(self) -> int:
|
154
|
+
# return len(self._pdoc) # To be replaced with docling-parse API
|
155
|
+
|
156
|
+
len_1 = len(self._pdoc)
|
157
|
+
len_2 = self.dp_doc.number_of_pages()
|
158
|
+
|
159
|
+
if len_1 != len_2:
|
160
|
+
_log.error(f"Inconsistent number of pages: {len_1}!={len_2}")
|
161
|
+
|
162
|
+
return len_2
|
163
|
+
|
164
|
+
def load_page(
|
165
|
+
self, page_no: int, create_words: bool = True, create_textlines: bool = True
|
166
|
+
) -> DoclingParseV4PageBackend:
|
167
|
+
with pypdfium2_lock:
|
168
|
+
return DoclingParseV4PageBackend(
|
169
|
+
self.dp_doc.get_page(
|
170
|
+
page_no + 1,
|
171
|
+
create_words=create_words,
|
172
|
+
create_textlines=create_textlines,
|
173
|
+
),
|
174
|
+
self._pdoc[page_no],
|
175
|
+
)
|
176
|
+
|
177
|
+
def is_valid(self) -> bool:
|
178
|
+
return self.page_count() > 0
|
179
|
+
|
180
|
+
def unload(self):
|
181
|
+
super().unload()
|
182
|
+
self.dp_doc.unload()
|
183
|
+
with pypdfium2_lock:
|
184
|
+
self._pdoc.close()
|
185
|
+
self._pdoc = None
|
File without changes
|
File without changes
|
@@ -0,0 +1,271 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
"""
|
4
|
+
Adapted from https://github.com/xiilei/dwml/blob/master/dwml/latex_dict.py
|
5
|
+
On 23/01/2025
|
6
|
+
"""
|
7
|
+
|
8
|
+
from __future__ import unicode_literals
|
9
|
+
|
10
|
+
CHARS = ("{", "}", "_", "^", "#", "&", "$", "%", "~")
|
11
|
+
|
12
|
+
BLANK = ""
|
13
|
+
BACKSLASH = "\\"
|
14
|
+
ALN = "&"
|
15
|
+
|
16
|
+
CHR = {
|
17
|
+
# Unicode : Latex Math Symbols
|
18
|
+
# Top accents
|
19
|
+
"\u0300": "\\grave{{{0}}}",
|
20
|
+
"\u0301": "\\acute{{{0}}}",
|
21
|
+
"\u0302": "\\hat{{{0}}}",
|
22
|
+
"\u0303": "\\tilde{{{0}}}",
|
23
|
+
"\u0304": "\\bar{{{0}}}",
|
24
|
+
"\u0305": "\\overbar{{{0}}}",
|
25
|
+
"\u0306": "\\breve{{{0}}}",
|
26
|
+
"\u0307": "\\dot{{{0}}}",
|
27
|
+
"\u0308": "\\ddot{{{0}}}",
|
28
|
+
"\u0309": "\\ovhook{{{0}}}",
|
29
|
+
"\u030a": "\\ocirc{{{0}}}}",
|
30
|
+
"\u030c": "\\check{{{0}}}}",
|
31
|
+
"\u0310": "\\candra{{{0}}}",
|
32
|
+
"\u0312": "\\oturnedcomma{{{0}}}",
|
33
|
+
"\u0315": "\\ocommatopright{{{0}}}",
|
34
|
+
"\u031a": "\\droang{{{0}}}",
|
35
|
+
"\u0338": "\\not{{{0}}}",
|
36
|
+
"\u20d0": "\\leftharpoonaccent{{{0}}}",
|
37
|
+
"\u20d1": "\\rightharpoonaccent{{{0}}}",
|
38
|
+
"\u20d2": "\\vertoverlay{{{0}}}",
|
39
|
+
"\u20d6": "\\overleftarrow{{{0}}}",
|
40
|
+
"\u20d7": "\\vec{{{0}}}",
|
41
|
+
"\u20db": "\\dddot{{{0}}}",
|
42
|
+
"\u20dc": "\\ddddot{{{0}}}",
|
43
|
+
"\u20e1": "\\overleftrightarrow{{{0}}}",
|
44
|
+
"\u20e7": "\\annuity{{{0}}}",
|
45
|
+
"\u20e9": "\\widebridgeabove{{{0}}}",
|
46
|
+
"\u20f0": "\\asteraccent{{{0}}}",
|
47
|
+
# Bottom accents
|
48
|
+
"\u0330": "\\wideutilde{{{0}}}",
|
49
|
+
"\u0331": "\\underbar{{{0}}}",
|
50
|
+
"\u20e8": "\\threeunderdot{{{0}}}",
|
51
|
+
"\u20ec": "\\underrightharpoondown{{{0}}}",
|
52
|
+
"\u20ed": "\\underleftharpoondown{{{0}}}",
|
53
|
+
"\u20ee": "\\underledtarrow{{{0}}}",
|
54
|
+
"\u20ef": "\\underrightarrow{{{0}}}",
|
55
|
+
# Over | group
|
56
|
+
"\u23b4": "\\overbracket{{{0}}}",
|
57
|
+
"\u23dc": "\\overparen{{{0}}}",
|
58
|
+
"\u23de": "\\overbrace{{{0}}}",
|
59
|
+
# Under| group
|
60
|
+
"\u23b5": "\\underbracket{{{0}}}",
|
61
|
+
"\u23dd": "\\underparen{{{0}}}",
|
62
|
+
"\u23df": "\\underbrace{{{0}}}",
|
63
|
+
}
|
64
|
+
|
65
|
+
CHR_BO = {
|
66
|
+
# Big operators,
|
67
|
+
"\u2140": "\\Bbbsum",
|
68
|
+
"\u220f": "\\prod",
|
69
|
+
"\u2210": "\\coprod",
|
70
|
+
"\u2211": "\\sum",
|
71
|
+
"\u222b": "\\int",
|
72
|
+
"\u22c0": "\\bigwedge",
|
73
|
+
"\u22c1": "\\bigvee",
|
74
|
+
"\u22c2": "\\bigcap",
|
75
|
+
"\u22c3": "\\bigcup",
|
76
|
+
"\u2a00": "\\bigodot",
|
77
|
+
"\u2a01": "\\bigoplus",
|
78
|
+
"\u2a02": "\\bigotimes",
|
79
|
+
}
|
80
|
+
|
81
|
+
T = {
|
82
|
+
"\u2192": "\\rightarrow ",
|
83
|
+
# Greek letters
|
84
|
+
"\U0001d6fc": "\\alpha ",
|
85
|
+
"\U0001d6fd": "\\beta ",
|
86
|
+
"\U0001d6fe": "\\gamma ",
|
87
|
+
"\U0001d6ff": "\\theta ",
|
88
|
+
"\U0001d700": "\\epsilon ",
|
89
|
+
"\U0001d701": "\\zeta ",
|
90
|
+
"\U0001d702": "\\eta ",
|
91
|
+
"\U0001d703": "\\theta ",
|
92
|
+
"\U0001d704": "\\iota ",
|
93
|
+
"\U0001d705": "\\kappa ",
|
94
|
+
"\U0001d706": "\\lambda ",
|
95
|
+
"\U0001d707": "\\m ",
|
96
|
+
"\U0001d708": "\\n ",
|
97
|
+
"\U0001d709": "\\xi ",
|
98
|
+
"\U0001d70a": "\\omicron ",
|
99
|
+
"\U0001d70b": "\\pi ",
|
100
|
+
"\U0001d70c": "\\rho ",
|
101
|
+
"\U0001d70d": "\\varsigma ",
|
102
|
+
"\U0001d70e": "\\sigma ",
|
103
|
+
"\U0001d70f": "\\ta ",
|
104
|
+
"\U0001d710": "\\upsilon ",
|
105
|
+
"\U0001d711": "\\phi ",
|
106
|
+
"\U0001d712": "\\chi ",
|
107
|
+
"\U0001d713": "\\psi ",
|
108
|
+
"\U0001d714": "\\omega ",
|
109
|
+
"\U0001d715": "\\partial ",
|
110
|
+
"\U0001d716": "\\varepsilon ",
|
111
|
+
"\U0001d717": "\\vartheta ",
|
112
|
+
"\U0001d718": "\\varkappa ",
|
113
|
+
"\U0001d719": "\\varphi ",
|
114
|
+
"\U0001d71a": "\\varrho ",
|
115
|
+
"\U0001d71b": "\\varpi ",
|
116
|
+
# Relation symbols
|
117
|
+
"\u2190": "\\leftarrow ",
|
118
|
+
"\u2191": "\\uparrow ",
|
119
|
+
"\u2192": "\\rightarrow ",
|
120
|
+
"\u2193": "\\downright ",
|
121
|
+
"\u2194": "\\leftrightarrow ",
|
122
|
+
"\u2195": "\\updownarrow ",
|
123
|
+
"\u2196": "\\nwarrow ",
|
124
|
+
"\u2197": "\\nearrow ",
|
125
|
+
"\u2198": "\\searrow ",
|
126
|
+
"\u2199": "\\swarrow ",
|
127
|
+
"\u22ee": "\\vdots ",
|
128
|
+
"\u22ef": "\\cdots ",
|
129
|
+
"\u22f0": "\\adots ",
|
130
|
+
"\u22f1": "\\ddots ",
|
131
|
+
"\u2260": "\\ne ",
|
132
|
+
"\u2264": "\\leq ",
|
133
|
+
"\u2265": "\\geq ",
|
134
|
+
"\u2266": "\\leqq ",
|
135
|
+
"\u2267": "\\geqq ",
|
136
|
+
"\u2268": "\\lneqq ",
|
137
|
+
"\u2269": "\\gneqq ",
|
138
|
+
"\u226a": "\\ll ",
|
139
|
+
"\u226b": "\\gg ",
|
140
|
+
"\u2208": "\\in ",
|
141
|
+
"\u2209": "\\notin ",
|
142
|
+
"\u220b": "\\ni ",
|
143
|
+
"\u220c": "\\nni ",
|
144
|
+
# Ordinary symbols
|
145
|
+
"\u221e": "\\infty ",
|
146
|
+
# Binary relations
|
147
|
+
"\u00b1": "\\pm ",
|
148
|
+
"\u2213": "\\mp ",
|
149
|
+
# Italic, Latin, uppercase
|
150
|
+
"\U0001d434": "A",
|
151
|
+
"\U0001d435": "B",
|
152
|
+
"\U0001d436": "C",
|
153
|
+
"\U0001d437": "D",
|
154
|
+
"\U0001d438": "E",
|
155
|
+
"\U0001d439": "F",
|
156
|
+
"\U0001d43a": "G",
|
157
|
+
"\U0001d43b": "H",
|
158
|
+
"\U0001d43c": "I",
|
159
|
+
"\U0001d43d": "J",
|
160
|
+
"\U0001d43e": "K",
|
161
|
+
"\U0001d43f": "L",
|
162
|
+
"\U0001d440": "M",
|
163
|
+
"\U0001d441": "N",
|
164
|
+
"\U0001d442": "O",
|
165
|
+
"\U0001d443": "P",
|
166
|
+
"\U0001d444": "Q",
|
167
|
+
"\U0001d445": "R",
|
168
|
+
"\U0001d446": "S",
|
169
|
+
"\U0001d447": "T",
|
170
|
+
"\U0001d448": "U",
|
171
|
+
"\U0001d449": "V",
|
172
|
+
"\U0001d44a": "W",
|
173
|
+
"\U0001d44b": "X",
|
174
|
+
"\U0001d44c": "Y",
|
175
|
+
"\U0001d44d": "Z",
|
176
|
+
# Italic, Latin, lowercase
|
177
|
+
"\U0001d44e": "a",
|
178
|
+
"\U0001d44f": "b",
|
179
|
+
"\U0001d450": "c",
|
180
|
+
"\U0001d451": "d",
|
181
|
+
"\U0001d452": "e",
|
182
|
+
"\U0001d453": "f",
|
183
|
+
"\U0001d454": "g",
|
184
|
+
"\U0001d456": "i",
|
185
|
+
"\U0001d457": "j",
|
186
|
+
"\U0001d458": "k",
|
187
|
+
"\U0001d459": "l",
|
188
|
+
"\U0001d45a": "m",
|
189
|
+
"\U0001d45b": "n",
|
190
|
+
"\U0001d45c": "o",
|
191
|
+
"\U0001d45d": "p",
|
192
|
+
"\U0001d45e": "q",
|
193
|
+
"\U0001d45f": "r",
|
194
|
+
"\U0001d460": "s",
|
195
|
+
"\U0001d461": "t",
|
196
|
+
"\U0001d462": "u",
|
197
|
+
"\U0001d463": "v",
|
198
|
+
"\U0001d464": "w",
|
199
|
+
"\U0001d465": "x",
|
200
|
+
"\U0001d466": "y",
|
201
|
+
"\U0001d467": "z",
|
202
|
+
}
|
203
|
+
|
204
|
+
FUNC = {
|
205
|
+
"sin": "\\sin({fe})",
|
206
|
+
"cos": "\\cos({fe})",
|
207
|
+
"tan": "\\tan({fe})",
|
208
|
+
"arcsin": "\\arcsin({fe})",
|
209
|
+
"arccos": "\\arccos({fe})",
|
210
|
+
"arctan": "\\arctan({fe})",
|
211
|
+
"arccot": "\\arccot({fe})",
|
212
|
+
"sinh": "\\sinh({fe})",
|
213
|
+
"cosh": "\\cosh({fe})",
|
214
|
+
"tanh": "\\tanh({fe})",
|
215
|
+
"coth": "\\coth({fe})",
|
216
|
+
"sec": "\\sec({fe})",
|
217
|
+
"csc": "\\csc({fe})",
|
218
|
+
}
|
219
|
+
|
220
|
+
FUNC_PLACE = "{fe}"
|
221
|
+
|
222
|
+
BRK = "\\\\"
|
223
|
+
|
224
|
+
CHR_DEFAULT = {
|
225
|
+
"ACC_VAL": "\\hat{{{0}}}",
|
226
|
+
}
|
227
|
+
|
228
|
+
POS = {
|
229
|
+
"top": "\\overline{{{0}}}", # not sure
|
230
|
+
"bot": "\\underline{{{0}}}",
|
231
|
+
}
|
232
|
+
|
233
|
+
POS_DEFAULT = {
|
234
|
+
"BAR_VAL": "\\overline{{{0}}}",
|
235
|
+
}
|
236
|
+
|
237
|
+
SUB = "_{{{0}}}"
|
238
|
+
|
239
|
+
SUP = "^{{{0}}}"
|
240
|
+
|
241
|
+
F = {
|
242
|
+
"bar": "\\frac{{{num}}}{{{den}}}",
|
243
|
+
"skw": r"^{{{num}}}/_{{{den}}}",
|
244
|
+
"noBar": "\\genfrac{{}}{{}}{{0pt}}{{}}{{{num}}}{{{den}}}",
|
245
|
+
"lin": "{{{num}}}/{{{den}}}",
|
246
|
+
}
|
247
|
+
F_DEFAULT = "\\frac{{{num}}}{{{den}}}"
|
248
|
+
|
249
|
+
D = "\\left{left}{text}\\right{right}"
|
250
|
+
|
251
|
+
D_DEFAULT = {
|
252
|
+
"left": "(",
|
253
|
+
"right": ")",
|
254
|
+
"null": ".",
|
255
|
+
}
|
256
|
+
|
257
|
+
RAD = "\\sqrt[{deg}]{{{text}}}"
|
258
|
+
RAD_DEFAULT = "\\sqrt{{{text}}}"
|
259
|
+
ARR = "{text}"
|
260
|
+
|
261
|
+
LIM_FUNC = {
|
262
|
+
"lim": "\\lim_{{{lim}}}",
|
263
|
+
"max": "\\max_{{{lim}}}",
|
264
|
+
"min": "\\min_{{{lim}}}",
|
265
|
+
}
|
266
|
+
|
267
|
+
LIM_TO = ("\\rightarrow", "\\to")
|
268
|
+
|
269
|
+
LIM_UPP = "\\overset{{{lim}}}{{{text}}}"
|
270
|
+
|
271
|
+
M = "\\begin{{matrix}}{text}\\end{{matrix}}"
|