Skip to content

Commit bc97283

Browse files
committed
release: v1.2.0
- Badge paragraphs: flex-wrap layout with gap-2 instead of stacked line-height spacing - Translate deprecated align= attributes to Tailwind text-center/left/right classes
1 parent db3df5a commit bc97283

3 files changed

Lines changed: 39 additions & 2 deletions

File tree

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [1.2.0] - 2026-04-17
9+
10+
### Fixed
11+
12+
- Badge paragraphs now render inline with `flex flex-wrap gap-2 items-center justify-center` instead of stacked with full line-height spacing
13+
- Deprecated `align="center/left/right"` HTML attributes are now translated to Tailwind `text-center/left/right` classes and removed from output
14+
815
## [1.1.0] - 2026-04-17
916

1017
### Fixed

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
44

55
[project]
66
name = "md2html-tailwind4"
7-
version = "1.1.0"
7+
version = "1.2.0"
88
description = "A Python package that converts Markdown to HTML using Tailwind CSS 4 for styling."
99
authors = [
1010
{ name = "White Neuron Co., Ltd.", email = "contact@whiteneuron.com" },

src/md2html_tailwind4/converter.py

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,10 @@ def add_tailwind_classes(self, soup):
5353
h6['class'] = 'text-sm font-semibold uppercase tracking-wide mt-4 mb-2 text-neutral-700 dark:text-neutral-300'
5454

5555
for p in soup.find_all('p'):
56-
p['class'] = 'mb-4 text-base leading-7 text-pretty text-justify text-neutral-800 dark:text-neutral-200'
56+
if self._is_badge_paragraph(p):
57+
p['class'] = 'flex flex-wrap gap-2 items-center justify-center mb-4'
58+
else:
59+
p['class'] = 'mb-4 text-base leading-7 text-pretty text-justify text-neutral-800 dark:text-neutral-200'
5760

5861
for ul in soup.find_all('ul'):
5962
ul['class'] = 'list-disc list-outside pl-6 mb-4 space-y-1 text-base leading-7 text-justify text-neutral-800 dark:text-neutral-200'
@@ -99,6 +102,17 @@ def add_tailwind_classes(self, soup):
99102
for hr in soup.find_all('hr'):
100103
hr['class'] = 'my-8 border-neutral-300 dark:border-neutral-700'
101104

105+
align_map = {'center': 'text-center', 'right': 'text-right', 'left': 'text-left'}
106+
for tag in soup.find_all(align=True):
107+
align_val = tag.get('align', '').lower()
108+
tailwind_class = align_map.get(align_val)
109+
if tailwind_class:
110+
existing = tag.get('class', '')
111+
if isinstance(existing, list):
112+
existing = ' '.join(existing)
113+
tag['class'] = f'{existing} {tailwind_class}'.strip()
114+
del tag['align']
115+
102116
def convert_tables(self, soup):
103117
for table in soup.find_all('table'):
104118
rows = table.find_all('tr')
@@ -193,6 +207,22 @@ def _style_as_responsive_table(self, soup, table):
193207
def create_full_html(self, soup):
194208
return str(soup)
195209

210+
@staticmethod
211+
def _is_badge_paragraph(p):
212+
"""Return True if all meaningful children of a <p> are badge links (<a><img>) or <br> tags."""
213+
for child in p.children:
214+
name = getattr(child, 'name', None)
215+
if name == 'br':
216+
continue
217+
if name == 'a':
218+
a_children = [c for c in child.children if getattr(c, 'name', None) or str(c).strip()]
219+
if len(a_children) == 1 and getattr(a_children[0], 'name', None) == 'img':
220+
continue
221+
if not name and not str(child).strip():
222+
continue
223+
return False
224+
return True
225+
196226
@staticmethod
197227
def _inject_markdown_attr(text):
198228
"""Inject markdown="1" into HTML block tags so md_in_html processes inner content."""

0 commit comments

Comments
 (0)