Browse Source

fixed lists

imwald
Silberengel 4 months ago
parent
commit
76878800f3
  1. 47
      src/components/Note/MarkdownArticle/MarkdownArticle.tsx

47
src/components/Note/MarkdownArticle/MarkdownArticle.tsx

@ -444,7 +444,8 @@ function parseMarkdownContent( @@ -444,7 +444,8 @@ function parseMarkdownContent(
// Add text before pattern
if (pattern.index > lastIndex) {
const text = content.slice(lastIndex, pattern.index)
if (text) {
// Skip whitespace-only text to avoid empty spans between block elements
if (text && text.trim()) {
// Process text for inline formatting (bold, italic, etc.)
// But skip if this text is part of a table (tables are handled as block patterns)
const isInTable = blockLevelPatterns.some(p =>
@ -597,10 +598,11 @@ function parseMarkdownContent( @@ -597,10 +598,11 @@ function parseMarkdownContent(
</li>
)
} else if (pattern.type === 'numbered-list-item') {
const { text } = pattern.data
const { text, number } = pattern.data
const listContent = parseInlineMarkdown(text, `numbered-${patternIdx}`, footnotes)
const itemNumber = number ? parseInt(number, 10) : undefined
parts.push(
<li key={`numbered-${patternIdx}`} className="list-decimal list-inside my-1">
<li key={`numbered-${patternIdx}`} className="leading-tight" value={itemNumber}>
{listContent}
</li>
)
@ -730,7 +732,8 @@ function parseMarkdownContent( @@ -730,7 +732,8 @@ function parseMarkdownContent(
// Add remaining text
if (lastIndex < content.length) {
const text = content.slice(lastIndex)
if (text) {
// Skip whitespace-only text to avoid empty spans
if (text && text.trim()) {
// Process text for inline formatting
// But skip if this text is part of a table
const isInTable = blockLevelPatterns.some(p =>
@ -750,11 +753,26 @@ function parseMarkdownContent( @@ -750,11 +753,26 @@ function parseMarkdownContent(
return { nodes: formattedContent, hashtagsInContent, footnotes }
}
// Filter out empty spans before wrapping lists
const filteredParts = parts.filter(part => {
if (React.isValidElement(part) && part.type === 'span') {
const children = part.props.children
// Filter out spans with only whitespace or empty content
if (typeof children === 'string' && !children.trim()) {
return false
}
if (Array.isArray(children) && children.every(child => typeof child === 'string' && !child.trim())) {
return false
}
}
return true
})
// Wrap list items in <ul> or <ol> tags
const wrappedParts: React.ReactNode[] = []
let partIdx = 0
while (partIdx < parts.length) {
const part = parts[partIdx]
while (partIdx < filteredParts.length) {
const part = filteredParts[partIdx]
// Check if this is a list item
if (React.isValidElement(part) && part.type === 'li') {
// Determine if it's a bullet or numbered list
@ -765,8 +783,8 @@ function parseMarkdownContent( @@ -765,8 +783,8 @@ function parseMarkdownContent(
// Collect consecutive list items of the same type
const listItems: React.ReactNode[] = [part]
partIdx++
while (partIdx < parts.length) {
const nextPart = parts[partIdx]
while (partIdx < filteredParts.length) {
const nextPart = filteredParts[partIdx]
if (React.isValidElement(nextPart) && nextPart.type === 'li') {
const nextIsBullet = nextPart.key && nextPart.key.toString().startsWith('bullet-')
const nextIsNumbered = nextPart.key && nextPart.key.toString().startsWith('numbered-')
@ -790,7 +808,7 @@ function parseMarkdownContent( @@ -790,7 +808,7 @@ function parseMarkdownContent(
)
} else {
wrappedParts.push(
<ol key={`ol-${partIdx}`} className="list-decimal list-inside my-2 space-y-1">
<ol key={`ol-${partIdx}`} className="list-decimal list-outside my-2 ml-6">
{listItems}
</ol>
)
@ -1351,6 +1369,17 @@ export default function MarkdownArticle({ @@ -1351,6 +1369,17 @@ export default function MarkdownArticle({
return (
<>
<style>{`
.prose ol[class*="list-decimal"] {
list-style-type: decimal !important;
}
.prose ol[class*="list-decimal"] li {
display: list-item !important;
list-style-position: outside !important;
line-height: 1.25 !important;
margin-bottom: 0 !important;
}
`}</style>
<div className={`prose prose-zinc max-w-none dark:prose-invert break-words overflow-wrap-anywhere ${className || ''}`}>
{/* Metadata */}
{!hideMetadata && metadata.title && <h1 className="break-words">{metadata.title}</h1>}

Loading…
Cancel
Save