slack-markdown-parser 2.3.0__tar.gz → 2.3.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.
Files changed (18) hide show
  1. {slack_markdown_parser-2.3.0 → slack_markdown_parser-2.3.1}/CHANGELOG.md +7 -0
  2. {slack_markdown_parser-2.3.0/slack_markdown_parser.egg-info → slack_markdown_parser-2.3.1}/PKG-INFO +1 -1
  3. {slack_markdown_parser-2.3.0 → slack_markdown_parser-2.3.1}/pyproject.toml +1 -1
  4. {slack_markdown_parser-2.3.0 → slack_markdown_parser-2.3.1}/slack_markdown_parser/__init__.py +1 -1
  5. {slack_markdown_parser-2.3.0 → slack_markdown_parser-2.3.1}/slack_markdown_parser/converter.py +61 -16
  6. {slack_markdown_parser-2.3.0 → slack_markdown_parser-2.3.1/slack_markdown_parser.egg-info}/PKG-INFO +1 -1
  7. {slack_markdown_parser-2.3.0 → slack_markdown_parser-2.3.1}/LICENSE +0 -0
  8. {slack_markdown_parser-2.3.0 → slack_markdown_parser-2.3.1}/MANIFEST.in +0 -0
  9. {slack_markdown_parser-2.3.0 → slack_markdown_parser-2.3.1}/README-ja.md +0 -0
  10. {slack_markdown_parser-2.3.0 → slack_markdown_parser-2.3.1}/README.md +0 -0
  11. {slack_markdown_parser-2.3.0 → slack_markdown_parser-2.3.1}/docs/spec-ja.md +0 -0
  12. {slack_markdown_parser-2.3.0 → slack_markdown_parser-2.3.1}/docs/spec.md +0 -0
  13. {slack_markdown_parser-2.3.0 → slack_markdown_parser-2.3.1}/setup.cfg +0 -0
  14. {slack_markdown_parser-2.3.0 → slack_markdown_parser-2.3.1}/slack_markdown_parser/py.typed +0 -0
  15. {slack_markdown_parser-2.3.0 → slack_markdown_parser-2.3.1}/slack_markdown_parser.egg-info/SOURCES.txt +0 -0
  16. {slack_markdown_parser-2.3.0 → slack_markdown_parser-2.3.1}/slack_markdown_parser.egg-info/dependency_links.txt +0 -0
  17. {slack_markdown_parser-2.3.0 → slack_markdown_parser-2.3.1}/slack_markdown_parser.egg-info/requires.txt +0 -0
  18. {slack_markdown_parser-2.3.0 → slack_markdown_parser-2.3.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.3.1] - 2026-04-10
10
+
11
+ ### Fixed
12
+
13
+ - Stopped `preserve_visual_blank_lines` from inserting visual-only blank-line placeholders inside fenced code blocks.
14
+ - Kept fallback plain text stable when visual blank-line placeholders are enabled alongside parser-added spacing markers around emphasis or inline code.
15
+
9
16
  ## [2.3.0] - 2026-04-10
10
17
 
11
18
  ### Changed
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: slack-markdown-parser
3
- Version: 2.3.0
3
+ Version: 2.3.1
4
4
  Summary: Convert LLM Markdown into Slack Block Kit markdown/table messages
5
5
  Author: darkgaldragon
6
6
  License-Expression: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "slack-markdown-parser"
7
- version = "2.3.0"
7
+ version = "2.3.1"
8
8
  description = "Convert LLM Markdown into Slack Block Kit markdown/table messages"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -1,6 +1,6 @@
1
1
  """slack-markdown-parser public package API."""
2
2
 
3
- __version__ = "2.3.0"
3
+ __version__ = "2.3.1"
4
4
  __license__ = "MIT"
5
5
 
6
6
  from .converter import (
@@ -153,6 +153,18 @@ def _normalize_markdown_block_plain_text(text: str) -> str:
153
153
  return re.sub(r"<(https?://[^>\s|]+)>", r"\1", text)
154
154
 
155
155
 
156
+ def _build_markdown_block_plain_text(
157
+ text: str, synthetic_space_indices: Optional[List[int]] = None
158
+ ) -> str:
159
+ """Build fallback/plain text for a markdown block before visual-only rewrites."""
160
+ return _normalize_markdown_block_plain_text(
161
+ _strip_synthetic_spaces_from_plain_text(
162
+ strip_zero_width_spaces(text),
163
+ synthetic_space_indices,
164
+ )
165
+ )
166
+
167
+
156
168
  def _strip_synthetic_spaces_from_plain_text(
157
169
  text: str, synthetic_space_indices: Optional[List[int]] = None
158
170
  ) -> str:
@@ -165,7 +177,9 @@ def _strip_synthetic_spaces_from_plain_text(
165
177
  )
166
178
 
167
179
 
168
- def _inject_visual_blank_line_placeholders(text: str) -> tuple[str, List[int]]:
180
+ def _inject_visual_blank_line_placeholders_in_chunk(
181
+ text: str,
182
+ ) -> tuple[str, List[int]]:
169
183
  """Replace internal blank lines with NBSP-only lines for Slack rendering."""
170
184
  if not text or "\n" not in text:
171
185
  return text, []
@@ -226,6 +240,31 @@ def _inject_visual_blank_line_placeholders(text: str) -> tuple[str, List[int]]:
226
240
  return "".join(rebuilt_parts), synthetic_indices
227
241
 
228
242
 
243
+ def _inject_visual_blank_line_placeholders(text: str) -> tuple[str, List[int]]:
244
+ """Replace internal blank lines outside fenced code blocks."""
245
+ if not text or "\n" not in text:
246
+ return text, []
247
+
248
+ rebuilt_parts: List[str] = []
249
+ synthetic_indices: List[int] = []
250
+ offset = 0
251
+
252
+ for is_fenced, chunk in _split_fenced_code_chunks(text):
253
+ if is_fenced:
254
+ rebuilt_parts.append(chunk)
255
+ offset += len(chunk)
256
+ continue
257
+
258
+ rewritten_chunk, chunk_indices = (
259
+ _inject_visual_blank_line_placeholders_in_chunk(chunk)
260
+ )
261
+ rebuilt_parts.append(rewritten_chunk)
262
+ synthetic_indices.extend(offset + idx for idx in chunk_indices)
263
+ offset += len(rewritten_chunk)
264
+
265
+ return "".join(rebuilt_parts), synthetic_indices
266
+
267
+
229
268
  def _strip_synthetic_blank_line_placeholders(
230
269
  text: str, synthetic_blank_line_indices: Optional[List[int]] = None
231
270
  ) -> str:
@@ -1171,6 +1210,7 @@ def convert_markdown_to_slack_blocks(
1171
1210
  continue
1172
1211
 
1173
1212
  formatted, synthetic_indices = _format_markdown_with_spacing_metadata(content)
1213
+ plain_text = _build_markdown_block_plain_text(formatted, synthetic_indices)
1174
1214
  synthetic_blank_line_indices: List[int] = []
1175
1215
  if preserve_visual_blank_lines:
1176
1216
  formatted, synthetic_blank_line_indices = (
@@ -1178,6 +1218,7 @@ def convert_markdown_to_slack_blocks(
1178
1218
  )
1179
1219
  if formatted.strip():
1180
1220
  block = _AnnotatedSlackBlock({"type": "markdown", "text": formatted})
1221
+ block._plain_text = plain_text
1181
1222
  block._synthetic_space_indices = synthetic_indices
1182
1223
  block._synthetic_blank_line_indices = synthetic_blank_line_indices
1183
1224
  blocks.append(block)
@@ -1246,19 +1287,21 @@ def blocks_to_plain_text(blocks: List[Dict[str, Any]]) -> str:
1246
1287
  block_type = block.get("type") if isinstance(block, dict) else None
1247
1288
 
1248
1289
  if block_type == "markdown":
1249
- text = block.get("text", "")
1250
- if text:
1251
- parts.append(
1252
- _normalize_markdown_block_plain_text(
1290
+ text = getattr(block, "_plain_text", None) or ""
1291
+ if not text:
1292
+ raw_text = block.get("text", "")
1293
+ if raw_text:
1294
+ text = _normalize_markdown_block_plain_text(
1253
1295
  _strip_synthetic_blank_line_placeholders(
1254
1296
  _strip_synthetic_spaces_from_plain_text(
1255
- strip_zero_width_spaces(text),
1297
+ strip_zero_width_spaces(raw_text),
1256
1298
  getattr(block, "_synthetic_space_indices", None),
1257
1299
  ),
1258
1300
  getattr(block, "_synthetic_blank_line_indices", None),
1259
- ),
1301
+ )
1260
1302
  )
1261
- )
1303
+ if text:
1304
+ parts.append(text)
1262
1305
  elif block_type == "table":
1263
1306
  rows = block.get("rows") or []
1264
1307
  for row in rows:
@@ -1288,15 +1331,17 @@ def build_fallback_text_from_blocks(blocks: List[Dict[str, Any]]) -> str:
1288
1331
  continue
1289
1332
 
1290
1333
  if block.get("type") == "markdown":
1291
- text = _normalize_markdown_block_plain_text(
1292
- _strip_synthetic_blank_line_placeholders(
1293
- _strip_synthetic_spaces_from_plain_text(
1294
- strip_zero_width_spaces(block.get("text", "")),
1295
- getattr(block, "_synthetic_space_indices", None),
1334
+ text = getattr(block, "_plain_text", None) or ""
1335
+ if not text:
1336
+ text = _normalize_markdown_block_plain_text(
1337
+ _strip_synthetic_blank_line_placeholders(
1338
+ _strip_synthetic_spaces_from_plain_text(
1339
+ strip_zero_width_spaces(block.get("text", "")),
1340
+ getattr(block, "_synthetic_space_indices", None),
1341
+ ),
1342
+ getattr(block, "_synthetic_blank_line_indices", None),
1296
1343
  ),
1297
- getattr(block, "_synthetic_blank_line_indices", None),
1298
- ),
1299
- )
1344
+ )
1300
1345
  if text.strip():
1301
1346
  plain_parts.append(text)
1302
1347
  elif block.get("type") == "table":
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: slack-markdown-parser
3
- Version: 2.3.0
3
+ Version: 2.3.1
4
4
  Summary: Convert LLM Markdown into Slack Block Kit markdown/table messages
5
5
  Author: darkgaldragon
6
6
  License-Expression: MIT