qparse 0.1.0__tar.gz → 0.1.2__tar.gz
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.
- {qparse-0.1.0 → qparse-0.1.2}/MANIFEST.in +0 -1
- {qparse-0.1.0/qparse.egg-info → qparse-0.1.2}/PKG-INFO +1 -1
- {qparse-0.1.0 → qparse-0.1.2}/pyproject.toml +6 -4
- {qparse-0.1.0 → qparse-0.1.2}/qparse/__init__.py +1 -1
- qparse-0.1.2/qparse/__main__.py +7 -0
- {qparse-0.1.0 → qparse-0.1.2}/qparse/docx_render/docx_render.py +4 -12
- {qparse-0.1.0 → qparse-0.1.2}/qparse/docx_render/write_buffer.py +53 -38
- {qparse-0.1.0 → qparse-0.1.2}/qparse/markdwon_document/nodes/img_node.py +16 -3
- {qparse-0.1.0 → qparse-0.1.2}/qparse/markdwon_loader.py +192 -189
- {qparse-0.1.0 → qparse-0.1.2}/qparse/markdwon_render.py +2 -4
- {qparse-0.1.0 → qparse-0.1.2/qparse}/qmd_cli.py +256 -262
- {qparse-0.1.0 → qparse-0.1.2}/qparse/qmd_packer.py +2 -6
- qparse-0.1.2/qparse/utils/__init__.py +25 -0
- qparse-0.1.2/qparse/utils/path_resolve.py +189 -0
- {qparse-0.1.0 → qparse-0.1.2/qparse.egg-info}/PKG-INFO +1 -1
- {qparse-0.1.0 → qparse-0.1.2}/qparse.egg-info/SOURCES.txt +4 -3
- qparse-0.1.2/qparse.egg-info/entry_points.txt +2 -0
- qparse-0.1.2/qparse.egg-info/top_level.txt +1 -0
- qparse-0.1.0/qparse/utils/__init__.py +0 -3
- qparse-0.1.0/qparse.egg-info/entry_points.txt +0 -2
- qparse-0.1.0/qparse.egg-info/top_level.txt +0 -2
- qparse-0.1.0/requirements.txt +0 -20
- {qparse-0.1.0 → qparse-0.1.2}/LICENSE +0 -0
- {qparse-0.1.0 → qparse-0.1.2}/README.md +0 -0
- {qparse-0.1.0 → qparse-0.1.2}/qparse/docx_render/__init__.py +0 -0
- {qparse-0.1.0 → qparse-0.1.2}/qparse/markdwon_document/__init__.py +0 -0
- {qparse-0.1.0 → qparse-0.1.2}/qparse/markdwon_document/analysis_document.py +0 -0
- {qparse-0.1.0 → qparse-0.1.2}/qparse/markdwon_document/base_document.py +0 -0
- {qparse-0.1.0 → qparse-0.1.2}/qparse/markdwon_document/markdwon_document.py +0 -0
- {qparse-0.1.0 → qparse-0.1.2}/qparse/markdwon_document/nodes/__init__.py +0 -0
- {qparse-0.1.0 → qparse-0.1.2}/qparse/markdwon_document/nodes/answer_node.py +0 -0
- {qparse-0.1.0 → qparse-0.1.2}/qparse/markdwon_document/nodes/base_node.py +0 -0
- {qparse-0.1.0 → qparse-0.1.2}/qparse/markdwon_document/nodes/text_node.py +0 -0
- {qparse-0.1.0 → qparse-0.1.2}/qparse/markdwon_document/question_document.py +0 -0
- {qparse-0.1.0 → qparse-0.1.2}/qparse/markdwon_document/stem_document.py +0 -0
- {qparse-0.1.0 → qparse-0.1.2}/qparse/markdwon_document/table_document.py +0 -0
- {qparse-0.1.0 → qparse-0.1.2}/qparse/qmd_unpacker.py +0 -0
- {qparse-0.1.0 → qparse-0.1.2}/qparse/render_option/__init__.py +0 -0
- {qparse-0.1.0 → qparse-0.1.2}/qparse/render_option/default_render_option.py +0 -0
- {qparse-0.1.0 → qparse-0.1.2}/qparse/render_option/default_render_template.md +0 -0
- {qparse-0.1.0 → qparse-0.1.2}/qparse/render_option/referance.docx +0 -0
- {qparse-0.1.0 → qparse-0.1.2}/qparse/render_option/theme.json +0 -0
- {qparse-0.1.0 → qparse-0.1.2}/qparse/utils/html_full_protector.py +0 -0
- {qparse-0.1.0 → qparse-0.1.2}/qparse.egg-info/dependency_links.txt +0 -0
- {qparse-0.1.0 → qparse-0.1.2}/qparse.egg-info/requires.txt +0 -0
- {qparse-0.1.0 → qparse-0.1.2}/setup.cfg +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "qparse"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.2"
|
|
8
8
|
description = "Structured Markdown lesson plans to DOCX, with .qmd pack/unpack tooling."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.9"
|
|
@@ -43,16 +43,18 @@ Repository = "https://github.com/hanbuhuai/qparse"
|
|
|
43
43
|
Issues = "https://github.com/hanbuhuai/qparse/issues"
|
|
44
44
|
|
|
45
45
|
[project.scripts]
|
|
46
|
-
qmd = "qmd_cli:main"
|
|
46
|
+
qmd = "qparse.qmd_cli:main"
|
|
47
47
|
|
|
48
48
|
[tool.setuptools]
|
|
49
49
|
include-package-data = true
|
|
50
|
-
py-modules = ["qmd_cli"]
|
|
51
50
|
|
|
52
51
|
[tool.setuptools.packages.find]
|
|
53
52
|
where = ["."]
|
|
54
53
|
include = ["qparse*"]
|
|
55
|
-
exclude = [
|
|
54
|
+
exclude = [
|
|
55
|
+
"qparse.docx_render.bak",
|
|
56
|
+
"qparse.docx_render.bak.*",
|
|
57
|
+
]
|
|
56
58
|
|
|
57
59
|
[tool.setuptools.package-data]
|
|
58
60
|
qparse = [
|
|
@@ -2,9 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
from pathlib import Path
|
|
4
4
|
from shutil import copy2, rmtree
|
|
5
|
-
from
|
|
5
|
+
from tempfile import mkdtemp
|
|
6
6
|
from qparse.markdwon_document import *
|
|
7
|
-
from typing import List
|
|
8
7
|
from .write_buffer import *
|
|
9
8
|
|
|
10
9
|
class DocxRender():
|
|
@@ -17,13 +16,9 @@ class DocxRender():
|
|
|
17
16
|
self._run_time_dir = None
|
|
18
17
|
|
|
19
18
|
def __enter__(self):
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
uuid4().hex
|
|
23
|
-
)
|
|
24
|
-
self._run_time_dir.mkdir(parents=True, exist_ok=True)
|
|
19
|
+
# 用系统临时目录,避免中文工作区路径让 Windows pandoc 找不到图片
|
|
20
|
+
self._run_time_dir = Path(mkdtemp(prefix="qmd_runtime_"))
|
|
25
21
|
self.render_buffer = DocumentBuffer(self)
|
|
26
|
-
|
|
27
22
|
return self
|
|
28
23
|
|
|
29
24
|
def __exit__(self, exc_type, exc_value, traceback):
|
|
@@ -36,10 +31,7 @@ class DocxRender():
|
|
|
36
31
|
@property
|
|
37
32
|
def run_time_dir(self)->Path:
|
|
38
33
|
if self._run_time_dir is None:
|
|
39
|
-
self._run_time_dir =
|
|
40
|
-
".qmd_runtime",
|
|
41
|
-
uuid4().hex
|
|
42
|
-
)
|
|
34
|
+
self._run_time_dir = Path(mkdtemp(prefix="qmd_runtime_"))
|
|
43
35
|
return self._run_time_dir
|
|
44
36
|
@property
|
|
45
37
|
def dist(self):
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
from __future__ import annotations
|
|
3
3
|
from typing import List,Union
|
|
4
4
|
from pathlib import Path
|
|
5
|
+
import os
|
|
5
6
|
import re
|
|
6
7
|
import pypandoc
|
|
7
8
|
from docxcompose.composer import Composer
|
|
@@ -12,6 +13,7 @@ from docx.oxml import OxmlElement
|
|
|
12
13
|
from docx.oxml.ns import qn
|
|
13
14
|
from docx.enum.text import WD_ALIGN_PARAGRAPH
|
|
14
15
|
from docx.shared import Inches
|
|
16
|
+
from qparse.utils.path_resolve import rewrite_local_images_for_pandoc
|
|
15
17
|
|
|
16
18
|
class BaseBuffer():
|
|
17
19
|
|
|
@@ -29,9 +31,42 @@ class BaseBuffer():
|
|
|
29
31
|
def create_docx_file_path(self):
|
|
30
32
|
return self.create_temp_file_path(f".{id(self)}.docx")
|
|
31
33
|
|
|
34
|
+
def _localize_images(self, text: str) -> str:
|
|
35
|
+
cache = getattr(self._render, "_pandoc_image_cache", None)
|
|
36
|
+
if cache is None:
|
|
37
|
+
cache = {}
|
|
38
|
+
self._render._pandoc_image_cache = cache
|
|
39
|
+
return rewrite_local_images_for_pandoc(text, self._render.run_time_dir, cache)
|
|
40
|
+
|
|
41
|
+
def _pandoc_extra_args(self, with_reference: bool = False):
|
|
42
|
+
runtime = Path(self._render.run_time_dir).resolve()
|
|
43
|
+
args = [
|
|
44
|
+
"--mathjax",
|
|
45
|
+
"--no-highlight",
|
|
46
|
+
f"--resource-path={runtime}",
|
|
47
|
+
]
|
|
48
|
+
if with_reference:
|
|
49
|
+
args.append(f"--reference-doc={Path(self.referance_path).as_posix()}")
|
|
50
|
+
return args
|
|
51
|
+
|
|
52
|
+
def _convert_with_pandoc(self, source_file: Path, outputfile: Path, fmt: str, extra_args):
|
|
53
|
+
old_cwd = os.getcwd()
|
|
54
|
+
runtime = Path(self._render.run_time_dir).resolve()
|
|
55
|
+
try:
|
|
56
|
+
os.chdir(str(runtime))
|
|
57
|
+
pypandoc.convert_file(
|
|
58
|
+
source_file=Path(source_file).name,
|
|
59
|
+
to="docx",
|
|
60
|
+
format=fmt,
|
|
61
|
+
outputfile=str(Path(outputfile).resolve()),
|
|
62
|
+
extra_args=extra_args,
|
|
63
|
+
)
|
|
64
|
+
finally:
|
|
65
|
+
os.chdir(old_cwd)
|
|
66
|
+
|
|
32
67
|
def write_to_text_file(self):
|
|
33
68
|
fpath= self.create_temp_file_path(".md")
|
|
34
|
-
fpath.write_text(self.text,encoding='utf-8')
|
|
69
|
+
fpath.write_text(self._localize_images(self.text), encoding='utf-8')
|
|
35
70
|
return fpath
|
|
36
71
|
def _restore_outer_blank_lines(self, docx_path):
|
|
37
72
|
lines = self.text.splitlines()
|
|
@@ -59,16 +94,11 @@ class BaseBuffer():
|
|
|
59
94
|
def write_to_docx_file(self):
|
|
60
95
|
temp_md_file_path = self.write_to_text_file()
|
|
61
96
|
fpath= self.create_temp_file_path(".docx")
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
extra_args=[
|
|
68
|
-
"--mathjax",
|
|
69
|
-
"--no-highlight",
|
|
70
|
-
f"--reference-doc={Path(self.referance_path).as_posix()}"
|
|
71
|
-
]
|
|
97
|
+
self._convert_with_pandoc(
|
|
98
|
+
temp_md_file_path,
|
|
99
|
+
fpath,
|
|
100
|
+
"markdown+tex_math_dollars+hard_line_breaks",
|
|
101
|
+
self._pandoc_extra_args(with_reference=True),
|
|
72
102
|
)
|
|
73
103
|
self._restore_outer_blank_lines(fpath)
|
|
74
104
|
return fpath
|
|
@@ -154,16 +184,11 @@ class MarkdwonTextBuffer(BaseBuffer):
|
|
|
154
184
|
def write_to_docx_file(self):
|
|
155
185
|
temp_md_file_path = self.write_to_text_file()
|
|
156
186
|
fpath= self.create_temp_file_path(".docx")
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
extra_args=[
|
|
163
|
-
"--mathjax",
|
|
164
|
-
"--no-highlight",
|
|
165
|
-
f"--reference-doc={Path(self.referance_path).as_posix()}"
|
|
166
|
-
]
|
|
187
|
+
self._convert_with_pandoc(
|
|
188
|
+
temp_md_file_path,
|
|
189
|
+
fpath,
|
|
190
|
+
"markdown+tex_math_dollars+hard_line_breaks",
|
|
191
|
+
self._pandoc_extra_args(with_reference=True),
|
|
167
192
|
)
|
|
168
193
|
self._restore_outer_blank_lines(fpath)
|
|
169
194
|
self._adjust_tables(fpath)
|
|
@@ -196,12 +221,7 @@ class HtmlTextBuffer(MarkdwonTextBuffer):
|
|
|
196
221
|
|
|
197
222
|
def write_to_text_file(self):
|
|
198
223
|
fpath= self.create_temp_file_path(".html")
|
|
199
|
-
fpath.write_text(self.text,encoding='utf-8')
|
|
200
|
-
return fpath
|
|
201
|
-
|
|
202
|
-
def write_to_text_file(self):
|
|
203
|
-
fpath= self.create_temp_file_path(".html")
|
|
204
|
-
fpath.write_text(self.text,encoding='utf-8')
|
|
224
|
+
fpath.write_text(self._localize_images(self.text), encoding='utf-8')
|
|
205
225
|
return fpath
|
|
206
226
|
|
|
207
227
|
def write_to_docx_file(self):
|
|
@@ -214,7 +234,7 @@ class HtmlTextBuffer(MarkdwonTextBuffer):
|
|
|
214
234
|
to="docx",
|
|
215
235
|
format="html+tex_math_dollars",
|
|
216
236
|
outputfile=fpath.as_posix(),
|
|
217
|
-
extra_args=
|
|
237
|
+
extra_args=self._pandoc_extra_args(with_reference=False),
|
|
218
238
|
)
|
|
219
239
|
return fpath
|
|
220
240
|
class TableHtmlTextBuffer(HtmlTextBuffer):
|
|
@@ -286,16 +306,11 @@ class TableHtmlTextBuffer(HtmlTextBuffer):
|
|
|
286
306
|
def write_to_docx_file(self):
|
|
287
307
|
temp_html_file_path = self.write_to_text_file()
|
|
288
308
|
fpath = self.create_docx_file_path()
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
extra_args=[
|
|
295
|
-
"--mathjax",
|
|
296
|
-
"--no-highlight",
|
|
297
|
-
f"--reference-doc={Path(self.referance_path).as_posix()}"
|
|
298
|
-
]
|
|
309
|
+
self._convert_with_pandoc(
|
|
310
|
+
temp_html_file_path,
|
|
311
|
+
fpath,
|
|
312
|
+
"html+tex_math_dollars",
|
|
313
|
+
self._pandoc_extra_args(with_reference=True),
|
|
299
314
|
)
|
|
300
315
|
self._adjust_docx(fpath)
|
|
301
316
|
return fpath
|
|
@@ -3,6 +3,7 @@ from bs4 import BeautifulSoup,element
|
|
|
3
3
|
from typing import Union
|
|
4
4
|
import copy
|
|
5
5
|
from .base_node import BaseNode
|
|
6
|
+
from qparse.utils.path_resolve import to_pandoc_local_url
|
|
6
7
|
|
|
7
8
|
class ImgNode(BaseNode):
|
|
8
9
|
def __init__(self, node, render_option):
|
|
@@ -14,7 +15,11 @@ class ImgNode(BaseNode):
|
|
|
14
15
|
return None
|
|
15
16
|
|
|
16
17
|
def dump_soup(self):
|
|
17
|
-
|
|
18
|
+
soup = copy.deepcopy(self._soup)
|
|
19
|
+
src = soup.attrs.get("src", "")
|
|
20
|
+
if src:
|
|
21
|
+
soup.attrs["src"] = to_pandoc_local_url(src)
|
|
22
|
+
return soup
|
|
18
23
|
def dump_markdwon(self):
|
|
19
24
|
alt = self._soup.attrs.get("alt", "")
|
|
20
25
|
src = self._soup.attrs.get("src", "")
|
|
@@ -23,9 +28,17 @@ class ImgNode(BaseNode):
|
|
|
23
28
|
if not src:
|
|
24
29
|
return ""
|
|
25
30
|
|
|
31
|
+
src_out = to_pandoc_local_url(src)
|
|
32
|
+
src_out = f"<{src_out}>" if (" " in src_out or "\\" in src_out) else src_out
|
|
26
33
|
if title:
|
|
27
|
-
return f''
|
|
35
|
+
return f''
|
|
36
|
+
|
|
37
|
+
def dump_docx_buffer(self):
|
|
38
|
+
text = self.dump_markdwon()
|
|
39
|
+
if not text:
|
|
40
|
+
return []
|
|
41
|
+
return [{'type': 'markdwonText', 'text': text}]
|
|
29
42
|
|
|
30
43
|
|
|
31
44
|
|