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.
Files changed (46) hide show
  1. {qparse-0.1.0 → qparse-0.1.2}/MANIFEST.in +0 -1
  2. {qparse-0.1.0/qparse.egg-info → qparse-0.1.2}/PKG-INFO +1 -1
  3. {qparse-0.1.0 → qparse-0.1.2}/pyproject.toml +6 -4
  4. {qparse-0.1.0 → qparse-0.1.2}/qparse/__init__.py +1 -1
  5. qparse-0.1.2/qparse/__main__.py +7 -0
  6. {qparse-0.1.0 → qparse-0.1.2}/qparse/docx_render/docx_render.py +4 -12
  7. {qparse-0.1.0 → qparse-0.1.2}/qparse/docx_render/write_buffer.py +53 -38
  8. {qparse-0.1.0 → qparse-0.1.2}/qparse/markdwon_document/nodes/img_node.py +16 -3
  9. {qparse-0.1.0 → qparse-0.1.2}/qparse/markdwon_loader.py +192 -189
  10. {qparse-0.1.0 → qparse-0.1.2}/qparse/markdwon_render.py +2 -4
  11. {qparse-0.1.0 → qparse-0.1.2/qparse}/qmd_cli.py +256 -262
  12. {qparse-0.1.0 → qparse-0.1.2}/qparse/qmd_packer.py +2 -6
  13. qparse-0.1.2/qparse/utils/__init__.py +25 -0
  14. qparse-0.1.2/qparse/utils/path_resolve.py +189 -0
  15. {qparse-0.1.0 → qparse-0.1.2/qparse.egg-info}/PKG-INFO +1 -1
  16. {qparse-0.1.0 → qparse-0.1.2}/qparse.egg-info/SOURCES.txt +4 -3
  17. qparse-0.1.2/qparse.egg-info/entry_points.txt +2 -0
  18. qparse-0.1.2/qparse.egg-info/top_level.txt +1 -0
  19. qparse-0.1.0/qparse/utils/__init__.py +0 -3
  20. qparse-0.1.0/qparse.egg-info/entry_points.txt +0 -2
  21. qparse-0.1.0/qparse.egg-info/top_level.txt +0 -2
  22. qparse-0.1.0/requirements.txt +0 -20
  23. {qparse-0.1.0 → qparse-0.1.2}/LICENSE +0 -0
  24. {qparse-0.1.0 → qparse-0.1.2}/README.md +0 -0
  25. {qparse-0.1.0 → qparse-0.1.2}/qparse/docx_render/__init__.py +0 -0
  26. {qparse-0.1.0 → qparse-0.1.2}/qparse/markdwon_document/__init__.py +0 -0
  27. {qparse-0.1.0 → qparse-0.1.2}/qparse/markdwon_document/analysis_document.py +0 -0
  28. {qparse-0.1.0 → qparse-0.1.2}/qparse/markdwon_document/base_document.py +0 -0
  29. {qparse-0.1.0 → qparse-0.1.2}/qparse/markdwon_document/markdwon_document.py +0 -0
  30. {qparse-0.1.0 → qparse-0.1.2}/qparse/markdwon_document/nodes/__init__.py +0 -0
  31. {qparse-0.1.0 → qparse-0.1.2}/qparse/markdwon_document/nodes/answer_node.py +0 -0
  32. {qparse-0.1.0 → qparse-0.1.2}/qparse/markdwon_document/nodes/base_node.py +0 -0
  33. {qparse-0.1.0 → qparse-0.1.2}/qparse/markdwon_document/nodes/text_node.py +0 -0
  34. {qparse-0.1.0 → qparse-0.1.2}/qparse/markdwon_document/question_document.py +0 -0
  35. {qparse-0.1.0 → qparse-0.1.2}/qparse/markdwon_document/stem_document.py +0 -0
  36. {qparse-0.1.0 → qparse-0.1.2}/qparse/markdwon_document/table_document.py +0 -0
  37. {qparse-0.1.0 → qparse-0.1.2}/qparse/qmd_unpacker.py +0 -0
  38. {qparse-0.1.0 → qparse-0.1.2}/qparse/render_option/__init__.py +0 -0
  39. {qparse-0.1.0 → qparse-0.1.2}/qparse/render_option/default_render_option.py +0 -0
  40. {qparse-0.1.0 → qparse-0.1.2}/qparse/render_option/default_render_template.md +0 -0
  41. {qparse-0.1.0 → qparse-0.1.2}/qparse/render_option/referance.docx +0 -0
  42. {qparse-0.1.0 → qparse-0.1.2}/qparse/render_option/theme.json +0 -0
  43. {qparse-0.1.0 → qparse-0.1.2}/qparse/utils/html_full_protector.py +0 -0
  44. {qparse-0.1.0 → qparse-0.1.2}/qparse.egg-info/dependency_links.txt +0 -0
  45. {qparse-0.1.0 → qparse-0.1.2}/qparse.egg-info/requires.txt +0 -0
  46. {qparse-0.1.0 → qparse-0.1.2}/setup.cfg +0 -0
@@ -1,6 +1,5 @@
1
1
  include README.md
2
2
  include LICENSE
3
- include requirements.txt
4
3
  recursive-include qparse/render_option *.json *.md *.docx
5
4
  global-exclude __pycache__ *.py[cod]
6
5
  prune qparse/docx_render/bak
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: qparse
3
- Version: 0.1.0
3
+ Version: 0.1.2
4
4
  Summary: Structured Markdown lesson plans to DOCX, with .qmd pack/unpack tooling.
5
5
  Author: hanbuhuai
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "qparse"
7
- version = "0.1.0"
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 = ["qparse.docx_render.bak", "qparse.docx_render.bak.*"]
54
+ exclude = [
55
+ "qparse.docx_render.bak",
56
+ "qparse.docx_render.bak.*",
57
+ ]
56
58
 
57
59
  [tool.setuptools.package-data]
58
60
  qparse = [
@@ -4,7 +4,7 @@ from .markdwon_render import MarkdwonRender
4
4
  from .qmd_packer import QmdPacker
5
5
  from .qmd_unpacker import QmdUnpacker
6
6
 
7
- __version__ = "0.1.0"
7
+ __version__ = "0.1.2"
8
8
 
9
9
  __all__ = [
10
10
  "MarkdownLoader",
@@ -0,0 +1,7 @@
1
+ # -*- coding: utf-8 -*-
2
+ """支持 python -m qparse。"""
3
+
4
+ from .qmd_cli import main
5
+
6
+ if __name__ == "__main__":
7
+ main()
@@ -2,9 +2,8 @@
2
2
 
3
3
  from pathlib import Path
4
4
  from shutil import copy2, rmtree
5
- from uuid import uuid4
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
- self._run_time_dir = self.src.parent.joinpath(
21
- ".qmd_runtime",
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 = self.src.parent.joinpath(
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
- pypandoc.convert_file(
63
- source_file=temp_md_file_path.as_posix(),
64
- to="docx",
65
- format="markdown+tex_math_dollars+hard_line_breaks",
66
- outputfile=fpath.as_posix(),
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
- pypandoc.convert_file(
158
- source_file=temp_md_file_path.as_posix(),
159
- to="docx",
160
- format="markdown+tex_math_dollars+hard_line_breaks",
161
- outputfile=fpath.as_posix(),
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=["--mathjax", "--no-highlight"]
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
- pypandoc.convert_file(
290
- source_file=temp_html_file_path.as_posix(),
291
- to="docx",
292
- format="html+tex_math_dollars",
293
- outputfile=fpath.as_posix(),
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
- return copy.deepcopy(self._soup)
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'![{alt}]({src} "{title}")'
28
- return f'![{alt}]({src})'
34
+ return f'![{alt}]({src_out} "{title}")'
35
+ return f'![{alt}]({src_out})'
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