markdocx 4.0.0__tar.gz → 6.0.0__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.
- {markdocx-4.0.0 → markdocx-6.0.0}/PKG-INFO +1 -1
- {markdocx-4.0.0 → markdocx-6.0.0}/pyproject.toml +1 -1
- {markdocx-4.0.0 → markdocx-6.0.0}/rule/ai_gen_doc_rule.md +6 -0
- {markdocx-4.0.0 → markdocx-6.0.0}/rule/ai_gen_doc_rule_en.md +6 -0
- {markdocx-4.0.0 → markdocx-6.0.0}/src/markdocx/__init__.py +1 -1
- {markdocx-4.0.0 → markdocx-6.0.0}/src/markdocx/diagram_renderer.py +60 -24
- {markdocx-4.0.0 → markdocx-6.0.0}/.gitignore +0 -0
- {markdocx-4.0.0 → markdocx-6.0.0}/.python-version +0 -0
- {markdocx-4.0.0 → markdocx-6.0.0}/LICENSE +0 -0
- {markdocx-4.0.0 → markdocx-6.0.0}/README.md +0 -0
- {markdocx-4.0.0 → markdocx-6.0.0}/main.py +0 -0
- {markdocx-4.0.0 → markdocx-6.0.0}/requirements.txt +0 -0
- {markdocx-4.0.0 → markdocx-6.0.0}/src/markdocx/cli.py +0 -0
- {markdocx-4.0.0 → markdocx-6.0.0}/src/markdocx/code_renderer.py +0 -0
- {markdocx-4.0.0 → markdocx-6.0.0}/src/markdocx/core.py +0 -0
- {markdocx-4.0.0 → markdocx-6.0.0}/src/markdocx/docx_builder.py +0 -0
- {markdocx-4.0.0 → markdocx-6.0.0}/src/markdocx/math_renderer.py +0 -0
- {markdocx-4.0.0 → markdocx-6.0.0}/src/markdocx/md_parser.py +0 -0
- {markdocx-4.0.0 → markdocx-6.0.0}/src/markdocx/styles.py +0 -0
- {markdocx-4.0.0 → markdocx-6.0.0}/uv.lock +0 -0
|
@@ -665,6 +665,12 @@ caption: Hình 8: Quy trình ETL
|
|
|
665
665
|
- Khuyến nghị dùng `[Bắt đầu]` và `[Kết thúc]` cho bước đầu và cuối
|
|
666
666
|
- Giữ quy trình tối đa **8 bước** để dễ đọc
|
|
667
667
|
- Dùng `title:` và `caption:` để đặt nhãn
|
|
668
|
+
- **Mỗi bước viết ngắn gọn, tối đa 10-12 ký tự** (ví dụ: `Thu nhận ảnh`, `Xử lý ảnh`)
|
|
669
|
+
- Nếu tên bước dài hơn 10 ký tự, hệ thống sẽ tự động xuống dòng
|
|
670
|
+
- **Bố cục ngang (`horizontal`):** viết tên bước **thật ngắn** (2-3 từ), không dùng câu dài
|
|
671
|
+
- ✅ Đúng: `(Thu nhận ảnh)`, `(Trích xuất)`, `(Phân loại)`
|
|
672
|
+
- ❌ Sai: `(Thu nhận và tiền xử lý ảnh đầu vào)`, `(Trích xuất đặc trưng từ dữ liệu)`
|
|
673
|
+
- **Bố cục dọc (`vertical`):** có thể viết dài hơn (tối đa 25-30 ký tự)
|
|
668
674
|
|
|
669
675
|
---
|
|
670
676
|
|
|
@@ -702,6 +702,12 @@ caption: Figure 8: ETL pipeline
|
|
|
702
702
|
- `[Start]` and `[End]` are recommended for the first and last steps
|
|
703
703
|
- Keep workflows to **8 steps or fewer** for readability
|
|
704
704
|
- Use `title:` and `caption:` for labeling
|
|
705
|
+
- **Keep each step label short — max 10-12 characters** (e.g., `Read Data`, `Transform`)
|
|
706
|
+
- Text longer than 10 characters will automatically wrap to 2 lines
|
|
707
|
+
- **Horizontal layout (`horizontal`):** use **very short** step labels (2-3 words max)
|
|
708
|
+
- ✅ Correct: `(Read Data)`, `(Transform)`, `(Classify)`
|
|
709
|
+
- ❌ Wrong: `(Read and preprocess input images)`, `(Extract features from data)`
|
|
710
|
+
- **Vertical layout (`vertical`):** may use longer labels (up to 25-30 characters)
|
|
705
711
|
|
|
706
712
|
---
|
|
707
713
|
|
|
@@ -766,31 +766,46 @@ def _render_workflow(code: str):
|
|
|
766
766
|
fig_w = max(6, box_w + 3.0)
|
|
767
767
|
fig_h = max(4, n * spacing_y + 2.0)
|
|
768
768
|
else:
|
|
769
|
-
# Horizontal
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
769
|
+
# Horizontal with multi-row zigzag layout
|
|
770
|
+
# Determine how many steps per row (max 4 per row for readability)
|
|
771
|
+
cols_per_row = min(4, n) # at most 4 boxes per row
|
|
772
|
+
if n > 4:
|
|
773
|
+
cols_per_row = (n + 1) // 2 # split roughly in half
|
|
774
|
+
cols_per_row = min(cols_per_row, 4) # cap at 4
|
|
775
|
+
|
|
776
|
+
max_chars_per_line = 16
|
|
777
|
+
box_w = max(3.0, min(4.5, max_text_len * 0.16 + 1.5))
|
|
778
|
+
box_h = 1.2
|
|
779
|
+
fontsize_normal = 13
|
|
780
|
+
fontsize_decision = 12
|
|
781
|
+
spacing_x = box_w + 1.5 # horizontal gap between boxes
|
|
782
|
+
spacing_y = 2.5 # vertical gap between rows
|
|
783
|
+
|
|
784
|
+
num_rows = (n + cols_per_row - 1) // cols_per_row
|
|
785
|
+
fig_w = max(8, cols_per_row * spacing_x + 2.0)
|
|
786
|
+
fig_h = max(4, num_rows * spacing_y + 2.5)
|
|
779
787
|
|
|
780
788
|
fig, ax = plt.subplots(figsize=(fig_w, fig_h))
|
|
781
|
-
# Do NOT use set_aspect("equal") — it distorts boxes
|
|
782
789
|
ax.axis("off")
|
|
783
790
|
|
|
784
791
|
# ── Calculate positions ─────────────────────────────────────
|
|
785
792
|
positions = []
|
|
786
|
-
|
|
787
|
-
|
|
793
|
+
if is_vertical:
|
|
794
|
+
for i in range(n):
|
|
788
795
|
x = fig_w / 2
|
|
789
796
|
y = fig_h - 1.5 - i * spacing_y
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
797
|
+
positions.append((x, y))
|
|
798
|
+
else:
|
|
799
|
+
# Zigzag: row 0 left→right, row 1 right→left, row 2 left→right, ...
|
|
800
|
+
for i in range(n):
|
|
801
|
+
row = i // cols_per_row
|
|
802
|
+
col = i % cols_per_row
|
|
803
|
+
# Reverse direction on odd rows
|
|
804
|
+
if row % 2 == 1:
|
|
805
|
+
col = cols_per_row - 1 - col
|
|
806
|
+
x = 1.5 + col * spacing_x
|
|
807
|
+
y = fig_h - 1.8 - row * spacing_y
|
|
808
|
+
positions.append((x, y))
|
|
794
809
|
|
|
795
810
|
# Adjust axes limits
|
|
796
811
|
all_x = [p[0] for p in positions]
|
|
@@ -881,12 +896,13 @@ def _render_workflow(code: str):
|
|
|
881
896
|
cur_type = steps[i].get("type", "process")
|
|
882
897
|
next_type = steps[i + 1].get("type", "process")
|
|
883
898
|
|
|
884
|
-
# Recompute effective heights for arrow endpoints
|
|
885
899
|
cur_text = _wrap_text(steps[i].get("text", ""), max_chars_per_line)
|
|
886
900
|
next_text = _wrap_text(steps[i + 1].get("text", ""), max_chars_per_line)
|
|
887
901
|
cur_h = max(box_h, box_h + (cur_text.count("\n")) * 0.3)
|
|
888
902
|
next_h = max(box_h, box_h + (next_text.count("\n")) * 0.3)
|
|
889
903
|
|
|
904
|
+
same_row = abs(y1 - y2) < 0.1 # same horizontal row
|
|
905
|
+
|
|
890
906
|
if is_vertical:
|
|
891
907
|
if cur_type == "decision":
|
|
892
908
|
start_y = y1 - cur_h * 0.9 - 0.08
|
|
@@ -900,18 +916,38 @@ def _render_workflow(code: str):
|
|
|
900
916
|
arrowprops=dict(arrowstyle="-|>", color="#555555",
|
|
901
917
|
lw=2, mutation_scale=15),
|
|
902
918
|
zorder=2)
|
|
919
|
+
elif same_row:
|
|
920
|
+
# Horizontal arrow on same row
|
|
921
|
+
if x2 > x1:
|
|
922
|
+
# Left to right
|
|
923
|
+
start_x = x1 + box_w / 2 + 0.08
|
|
924
|
+
end_x = x2 - box_w / 2 - 0.08
|
|
925
|
+
else:
|
|
926
|
+
# Right to left
|
|
927
|
+
start_x = x1 - box_w / 2 - 0.08
|
|
928
|
+
end_x = x2 + box_w / 2 + 0.08
|
|
929
|
+
if cur_type == "decision":
|
|
930
|
+
start_x = x1 + (box_w * 0.55 + 0.08) * (1 if x2 > x1 else -1)
|
|
931
|
+
if next_type == "decision":
|
|
932
|
+
end_x = x2 - (box_w * 0.55 + 0.08) * (1 if x2 > x1 else -1)
|
|
933
|
+
ax.annotate("", xy=(end_x, y2), xytext=(start_x, y1),
|
|
934
|
+
arrowprops=dict(arrowstyle="-|>", color="#555555",
|
|
935
|
+
lw=2, mutation_scale=15),
|
|
936
|
+
zorder=2)
|
|
903
937
|
else:
|
|
938
|
+
# Vertical arrow between rows (row transition)
|
|
904
939
|
if cur_type == "decision":
|
|
905
|
-
|
|
940
|
+
start_y = y1 - cur_h * 0.9 - 0.08
|
|
906
941
|
else:
|
|
907
|
-
|
|
942
|
+
start_y = y1 - cur_h / 2 - 0.08
|
|
908
943
|
if next_type == "decision":
|
|
909
|
-
|
|
944
|
+
end_y = y2 + next_h * 0.9 + 0.08
|
|
910
945
|
else:
|
|
911
|
-
|
|
912
|
-
ax.annotate("", xy=(
|
|
946
|
+
end_y = y2 + next_h / 2 + 0.08
|
|
947
|
+
ax.annotate("", xy=(x2, end_y), xytext=(x1, start_y),
|
|
913
948
|
arrowprops=dict(arrowstyle="-|>", color="#555555",
|
|
914
|
-
lw=2, mutation_scale=15
|
|
949
|
+
lw=2, mutation_scale=15,
|
|
950
|
+
connectionstyle="arc3,rad=0"),
|
|
915
951
|
zorder=2)
|
|
916
952
|
|
|
917
953
|
if title:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|