slack-markdown-parser 2.4.0__tar.gz → 2.4.1__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.
- {slack_markdown_parser-2.4.0 → slack_markdown_parser-2.4.1}/CHANGELOG.md +7 -0
- {slack_markdown_parser-2.4.0/slack_markdown_parser.egg-info → slack_markdown_parser-2.4.1}/PKG-INFO +1 -1
- {slack_markdown_parser-2.4.0 → slack_markdown_parser-2.4.1}/docs/spec-ja.md +8 -2
- {slack_markdown_parser-2.4.0 → slack_markdown_parser-2.4.1}/docs/spec.md +8 -2
- {slack_markdown_parser-2.4.0 → slack_markdown_parser-2.4.1}/pyproject.toml +1 -1
- {slack_markdown_parser-2.4.0 → slack_markdown_parser-2.4.1}/slack_markdown_parser/__init__.py +1 -1
- {slack_markdown_parser-2.4.0 → slack_markdown_parser-2.4.1}/slack_markdown_parser/converter.py +63 -12
- {slack_markdown_parser-2.4.0 → slack_markdown_parser-2.4.1/slack_markdown_parser.egg-info}/PKG-INFO +1 -1
- {slack_markdown_parser-2.4.0 → slack_markdown_parser-2.4.1}/LICENSE +0 -0
- {slack_markdown_parser-2.4.0 → slack_markdown_parser-2.4.1}/MANIFEST.in +0 -0
- {slack_markdown_parser-2.4.0 → slack_markdown_parser-2.4.1}/README-ja.md +0 -0
- {slack_markdown_parser-2.4.0 → slack_markdown_parser-2.4.1}/README.md +0 -0
- {slack_markdown_parser-2.4.0 → slack_markdown_parser-2.4.1}/setup.cfg +0 -0
- {slack_markdown_parser-2.4.0 → slack_markdown_parser-2.4.1}/slack_markdown_parser/py.typed +0 -0
- {slack_markdown_parser-2.4.0 → slack_markdown_parser-2.4.1}/slack_markdown_parser.egg-info/SOURCES.txt +0 -0
- {slack_markdown_parser-2.4.0 → slack_markdown_parser-2.4.1}/slack_markdown_parser.egg-info/dependency_links.txt +0 -0
- {slack_markdown_parser-2.4.0 → slack_markdown_parser-2.4.1}/slack_markdown_parser.egg-info/requires.txt +0 -0
- {slack_markdown_parser-2.4.0 → slack_markdown_parser-2.4.1}/slack_markdown_parser.egg-info/top_level.txt +0 -0
|
@@ -6,6 +6,13 @@ The format is based on Keep a Changelog, and the project follows Semantic Versio
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [2.4.1] - 2026-05-29
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- Stopped punctuation-terminated emphasis from leaking its literal markers (`**`, `*`, `~~`) in `markdown` blocks. A ZWSP placed just outside a closing marker broke Slack's CommonMark right-flanking check whenever the last inner character was punctuation (e.g. `- **項目:**` at a line end, or `**70.9%→83.0%**、` before CJK punctuation), exposing the raw markers. Chunk boundaries are now treated as safe so no stray ZWSP is appended at line/text ends, and when a marker sits against inner punctuation a ZWSP is inserted just inside it so the run flanks via rule 2a regardless of the following character — including before CJK text and CJK punctuation that Slack does not accept as a flanking neighbor.
|
|
14
|
+
- Stopped preserving English-like punctuation-flanked emphasis raw when its tight neighbor is non-ASCII punctuation (e.g. `**APIYI (apiyi.com)**。` or `Score **70.9%→83.0%**、`). Slack only accepts ASCII punctuation/whitespace as a flanking neighbor, so these now receive the inner ZWSP protection instead of being emitted unchanged.
|
|
15
|
+
|
|
9
16
|
## [2.4.0] - 2026-05-14
|
|
10
17
|
|
|
11
18
|
### Added
|
|
@@ -166,16 +166,22 @@ LLM は外枠パイプの省略、区切り行の欠落、列数の不一致な
|
|
|
166
166
|
|
|
167
167
|
### 対象パターン
|
|
168
168
|
|
|
169
|
-
|
|
169
|
+
以下の装飾記号について、見た目を変えずに Slack の装飾境界を保つために必要な箇所だけにゼロ幅スペース(`U+200B`)を挿入します。
|
|
170
170
|
|
|
171
171
|
- `` `code` `` — インラインコード
|
|
172
172
|
- `**bold**` — 太字
|
|
173
173
|
- `*italic*` — 斜体
|
|
174
174
|
- `~~strike~~` — 取消線
|
|
175
175
|
|
|
176
|
+
ルール:
|
|
177
|
+
|
|
178
|
+
- チャンクの先頭・末尾(行頭・行末・テキスト端、またはフェンスドコードブロックの境界)は安全とみなし、ゼロ幅スペースを付けません。
|
|
179
|
+
- 外側の片方が前後の非境界テキストに密着している場合、その側だけにゼロ幅スペースを付けます。安全(境界)側はそのままにします。
|
|
180
|
+
- 強調マーカー(`**`・`*`・`~~`)の内側が句読点に密着している場合(例 `**注意:**` や `**70.9%→83.0%**`)、マーカーの内側にゼロ幅スペースを挿入します。これによりマーカーの内側隣接文字が非句読点になり、後続が何であっても Slack の CommonMark right-/left-flanking 判定が成立します。Slack が flanking 近傍として認めない CJK テキストや CJK 句読点(`、` / `。`)の直前でも有効です。インラインコードは flanking 規則の対象外なので、このルールから除外します。
|
|
181
|
+
|
|
176
182
|
例外:
|
|
177
183
|
|
|
178
|
-
-
|
|
184
|
+
- 装飾の中身が英語系テキストで、密着している隣接文字が **ASCII** 句読点だけの場合は、元のトークンをそのまま保ちます。`**APIYI (apiyi.com)**:` のように Slack がそのまま表示できるケースで、不要なゼロ幅スペースを増やさないためです。`、` や `。` のような非ASCII句読点が隣接する場合は保持せず、上記の内側ゼロ幅スペースで保護します。
|
|
179
185
|
|
|
180
186
|
### 除外範囲
|
|
181
187
|
|
|
@@ -165,16 +165,22 @@ In languages such as Japanese, Chinese, and Korean that do not usually put space
|
|
|
165
165
|
|
|
166
166
|
### Target patterns
|
|
167
167
|
|
|
168
|
-
|
|
168
|
+
The library inserts zero-width spaces (`U+200B`) only where they are needed to keep Slack's formatting boundaries intact, without changing the visible layout, for each formatting token below:
|
|
169
169
|
|
|
170
170
|
- `` `code` ``: inline code
|
|
171
171
|
- `**bold**`: bold
|
|
172
172
|
- `*italic*`: italic
|
|
173
173
|
- `~~strike~~`: strikethrough
|
|
174
174
|
|
|
175
|
+
Rules:
|
|
176
|
+
|
|
177
|
+
- The start and end of a chunk (a line/text boundary, or the edge of a fenced code block) are treated as safe; no zero-width space is added there.
|
|
178
|
+
- When an outer edge is tight against surrounding non-boundary text, only that edge is padded with a zero-width space. The safe (boundary) edge is left clean.
|
|
179
|
+
- When an emphasis marker (`**`, `*`, `~~`) sits directly against punctuation on its inner side (for example `**注意:**` or `**70.9%→83.0%**`), a zero-width space is inserted just *inside* the marker. This makes the marker's inner neighbor a non-punctuation character, so Slack's CommonMark right-/left-flanking check succeeds regardless of what surrounds the token — including before CJK text and CJK punctuation (`、` / `。`), which Slack does not accept as a flanking neighbor. Inline code spans are exempt from this rule because they do not obey flanking rules.
|
|
180
|
+
|
|
175
181
|
Exception:
|
|
176
182
|
|
|
177
|
-
- If the token body is English-like text and
|
|
183
|
+
- If the token body is English-like text and its only tight neighbors are **ASCII** punctuation characters, the raw token is preserved. This avoids over-correcting spans such as `**APIYI (apiyi.com)**:` that Slack already renders correctly without extra zero-width spaces. A non-ASCII punctuation neighbor such as `、` or `。` is not preserved — it is protected by the inner zero-width space described above.
|
|
178
184
|
|
|
179
185
|
### Excluded regions
|
|
180
186
|
|
{slack_markdown_parser-2.4.0 → slack_markdown_parser-2.4.1}/slack_markdown_parser/converter.py
RENAMED
|
@@ -515,6 +515,13 @@ def _should_preserve_raw_punctuation_emphasis(
|
|
|
515
515
|
return False
|
|
516
516
|
if any(not _is_punctuation_like(char, boundary_chars) for char in tight_chars):
|
|
517
517
|
return False
|
|
518
|
+
# Slack only accepts ASCII punctuation (and whitespace) as a flanking
|
|
519
|
+
# neighbor. A non-ASCII punctuation neighbor — e.g. the CJK comma/period
|
|
520
|
+
# ``、``/``。`` — does not satisfy the right-/left-flanking rule, so the
|
|
521
|
+
# token must not be preserved raw; it needs the inner-ZWSP protection in
|
|
522
|
+
# ``wrap_match`` instead.
|
|
523
|
+
if any(ord(char) > 127 for char in tight_chars):
|
|
524
|
+
return False
|
|
518
525
|
if any(_is_han_or_kana_char(char) or _is_hangul_char(char) for char in token_text):
|
|
519
526
|
return False
|
|
520
527
|
|
|
@@ -703,21 +710,65 @@ def _format_markdown_with_spacing_metadata(text: str) -> tuple[str, list[int]]:
|
|
|
703
710
|
|
|
704
711
|
def wrap_match(match: re.Match[str], source: str) -> str:
|
|
705
712
|
start, end = match.start(), match.end()
|
|
706
|
-
|
|
707
|
-
|
|
713
|
+
token = match.group(0)
|
|
714
|
+
# The start/end of the chunk are effective boundaries: there is no
|
|
715
|
+
# adjacent text to separate the marker from, so they are safe. Treating
|
|
716
|
+
# them as unsafe used to append a ZWSP right after a closing marker, and
|
|
717
|
+
# when the last content character was punctuation (e.g. ``**注意:**``)
|
|
718
|
+
# the trailing ZWSP made Slack fail the CommonMark right-flanking check
|
|
719
|
+
# and exposed the literal ``**``.
|
|
720
|
+
before_safe = start == 0 or source[start - 1] in boundary_chars
|
|
721
|
+
after_safe = end == len(source) or source[end] in boundary_chars
|
|
708
722
|
if before_safe and after_safe:
|
|
709
|
-
return
|
|
723
|
+
return token
|
|
710
724
|
if _should_preserve_raw_punctuation_emphasis(
|
|
711
|
-
source, start, end,
|
|
725
|
+
source, start, end, token, boundary_chars
|
|
712
726
|
):
|
|
713
|
-
return
|
|
714
|
-
|
|
715
|
-
# When
|
|
716
|
-
#
|
|
717
|
-
#
|
|
718
|
-
prefix = ZWSP
|
|
719
|
-
suffix = ZWSP
|
|
720
|
-
|
|
727
|
+
return token
|
|
728
|
+
|
|
729
|
+
# When an outer edge is tightly coupled to surrounding text, pad only
|
|
730
|
+
# that edge so Slack can treat the decoration as a standalone span.
|
|
731
|
+
# Padding a safe edge is unnecessary noise.
|
|
732
|
+
prefix = "" if before_safe else ZWSP
|
|
733
|
+
suffix = "" if after_safe else ZWSP
|
|
734
|
+
|
|
735
|
+
# Emphasis markers (``*``/``**``/``~~``) obey CommonMark delimiter-run
|
|
736
|
+
# flanking rules; inline code spans (``` `…` ```) do not. When an
|
|
737
|
+
# emphasis marker sits directly against punctuation on its inner side
|
|
738
|
+
# (``**注意:**``, ``**70%→83%**``) Slack treats the run as a delimiter
|
|
739
|
+
# only when the *outer* neighbour is whitespace or ASCII punctuation; a
|
|
740
|
+
# following CJK character or CJK punctuation (e.g. ``、``) — and even a
|
|
741
|
+
# ZWSP placed just outside the marker — leaves the literal ``**``
|
|
742
|
+
# exposed. Inserting a ZWSP just *inside* the marker makes its inner
|
|
743
|
+
# neighbour a non-punctuation character, so the run flanks via rule 2a
|
|
744
|
+
# regardless of what surrounds the token.
|
|
745
|
+
marker_char = token[0]
|
|
746
|
+
if marker_char != "`":
|
|
747
|
+
marker_len = len(token) - len(token.lstrip(marker_char))
|
|
748
|
+
open_marker = token[:marker_len]
|
|
749
|
+
inner = token[marker_len : len(token) - marker_len]
|
|
750
|
+
close_marker = token[len(token) - marker_len :]
|
|
751
|
+
inner_prefix = (
|
|
752
|
+
ZWSP if inner and _is_punctuation_like(inner[0], boundary_chars) else ""
|
|
753
|
+
)
|
|
754
|
+
inner_suffix = (
|
|
755
|
+
ZWSP
|
|
756
|
+
if inner and _is_punctuation_like(inner[-1], boundary_chars)
|
|
757
|
+
else ""
|
|
758
|
+
)
|
|
759
|
+
if inner_prefix or inner_suffix:
|
|
760
|
+
token = (
|
|
761
|
+
f"{open_marker}{inner_prefix}{inner}{inner_suffix}{close_marker}"
|
|
762
|
+
)
|
|
763
|
+
# The inner ZWSP already lets the marker flank correctly, so an
|
|
764
|
+
# outer ZWSP on the same edge is redundant — and after a closing
|
|
765
|
+
# marker it is precisely what would re-break rendering.
|
|
766
|
+
if inner_prefix:
|
|
767
|
+
prefix = ""
|
|
768
|
+
if inner_suffix:
|
|
769
|
+
suffix = ""
|
|
770
|
+
|
|
771
|
+
return f"{prefix}{token}{suffix}"
|
|
721
772
|
|
|
722
773
|
def wrap_nested_code_emphasis_match(
|
|
723
774
|
match: re.Match[str],
|
|
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
|