-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Fix bullet rendering #3804
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Fix bullet rendering #3804
Changes from all commits
93118cd
10d6e63
b1d0683
0e34c4b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,65 @@ | ||
| /* Markdown Table Styles */ | ||
| .markdown-table { | ||
| border-collapse: collapse; | ||
| width: 100%; | ||
| margin: 1em 0; | ||
| font-size: 14px; | ||
| box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); | ||
| border-radius: 8px; | ||
| overflow: hidden; | ||
| } | ||
|
|
||
| .markdown-table th { | ||
| background: linear-gradient(135deg, #4a90e2 0%, #357abd 100%); | ||
| color: white; | ||
| font-weight: bold; | ||
| text-align: center; | ||
| padding: 12px 8px; | ||
| border: none; | ||
| } | ||
|
|
||
| .markdown-table td { | ||
| padding: 12px 8px; | ||
| text-align: center; | ||
| border: 1px solid #e0e0e0; | ||
| } | ||
|
|
||
| .markdown-table tr:nth-child(even) { | ||
| background-color: #f8f9fa; | ||
| } | ||
|
|
||
| .markdown-table tr:nth-child(odd) { | ||
| background-color: #ffffff; | ||
| } | ||
|
|
||
| .markdown-table tr:hover { | ||
| background-color: #e3f2fd; | ||
| transition: background-color 0.2s ease; | ||
| } | ||
|
|
||
| .markdown-table tbody tr:last-child td { | ||
| border-bottom: none; | ||
| } | ||
|
|
||
| /* Responsive Design */ | ||
| @media (max-width: 768px) { | ||
| .markdown-table { | ||
| font-size: 12px; | ||
| } | ||
|
|
||
| .markdown-table th, | ||
| .markdown-table td { | ||
| padding: 8px 4px; | ||
| } | ||
| } | ||
|
|
||
| @media (max-width: 480px) { | ||
| .markdown-table { | ||
| font-size: 11px; | ||
| } | ||
|
|
||
| .markdown-table th, | ||
| .markdown-table td { | ||
| padding: 6px 2px; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -67,12 +67,12 @@ export const other = { | |||||||||||||||||||||
| spaceLine: /^ +$/gm, | ||||||||||||||||||||||
| notSpaceStart: /^\S*/, | ||||||||||||||||||||||
| endingNewline: /\n$/, | ||||||||||||||||||||||
| listItemRegex: (bull: string) => new RegExp(`^( {0,3}${bull})((?:[\t ][^\\n]*)?(?:\\n|$))`), | ||||||||||||||||||||||
| nextBulletRegex: (indent: number) => new RegExp(`^ {0,${Math.min(3, indent - 1)}}(?:[*+-]|\\d{1,9}[.)])((?:[ \t][^\\n]*)?(?:\\n|$))`), | ||||||||||||||||||||||
| hrRegex: (indent: number) => new RegExp(`^ {0,${Math.min(3, indent - 1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`), | ||||||||||||||||||||||
| fencesBeginRegex: (indent: number) => new RegExp(`^ {0,${Math.min(3, indent - 1)}}(?:\`\`\`|~~~)`), | ||||||||||||||||||||||
| headingBeginRegex: (indent: number) => new RegExp(`^ {0,${Math.min(3, indent - 1)}}#`), | ||||||||||||||||||||||
| htmlBeginRegex: (indent: number) => new RegExp(`^ {0,${Math.min(3, indent - 1)}}<(?:[a-z].*>|!--)`, 'i'), | ||||||||||||||||||||||
| listItemRegex: (bull: string) => new RegExp(`^( {0,4}${bull})((?:[\t ][^\\n]*)?(?:\\n|$))`), | ||||||||||||||||||||||
| nextBulletRegex: (indent: number) => /^ {0,4}(?:[*+-]|\d{1,9}[.)])((?:[ \t][^\n]*)?(?:\n|$))/, | ||||||||||||||||||||||
| hrRegex: (indent: number) => /^ {0,4}((?:- *){3,}|(?:_ *){3,}|(?:\* *){3,})(?:\n+|$)/, | ||||||||||||||||||||||
| fencesBeginRegex: (indent: number) => /^ {0,4}(?:```|~~~)/, | ||||||||||||||||||||||
| headingBeginRegex: (indent: number) => /^ {0,4}#/, | ||||||||||||||||||||||
| htmlBeginRegex: (indent: number) => /^ {0,4}<(?:[a-z].*>|!--)/i, | ||||||||||||||||||||||
|
Comment on lines
+71
to
+75
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The
Suggested change
|
||||||||||||||||||||||
| }; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| /** | ||||||||||||||||||||||
|
|
@@ -112,7 +112,7 @@ const def = edit(/^ {0,3}\[(label)\]: *(?:\n[ \t]*)?([^<\s][^\s]*|<.*?>)(?:(?: + | |||||||||||||||||||||
| .replace('title', /(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/) | ||||||||||||||||||||||
| .getRegex(); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| const list = edit(/^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/) | ||||||||||||||||||||||
| const list = edit(/^( {0,4}bull)([ \t][^\n]+?)?(?:\n|$)/) | ||||||||||||||||||||||
| .replace(/bull/g, bullet) | ||||||||||||||||||||||
| .getRegex(); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
|
|
||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| import type { MarkedExtension } from './MarkedOptions.ts'; | ||
| import type { Tokens } from './Tokens.ts'; | ||
|
|
||
| export const tableExtension: MarkedExtension = { | ||
| renderer: { | ||
| table(token: Tokens.Table): string { | ||
| let header = ''; | ||
|
|
||
| // header | ||
| let cell = ''; | ||
| for (let j = 0; j < token.header.length; j++) { | ||
| cell += this.tablecell(token.header[j]); | ||
| } | ||
| header += this.tablerow({ text: cell }); | ||
|
|
||
| let body = ''; | ||
| for (let j = 0; j < token.rows.length; j++) { | ||
| const row = token.rows[j]; | ||
|
|
||
| cell = ''; | ||
| for (let k = 0; k < row.length; k++) { | ||
| cell += this.tablecell(row[k]); | ||
| } | ||
|
|
||
| body += this.tablerow({ text: cell }); | ||
| } | ||
| if (body) body = `<tbody>${body}</tbody>`; | ||
|
|
||
| return '<table class="markdown-table">\n' | ||
| + '<thead>\n' | ||
| + header | ||
| + '</thead>\n' | ||
| + body | ||
| + '</table>\n'; | ||
| }, | ||
| tablerow({ text }: Tokens.TableRow): string { | ||
| return `<tr class="markdown-table-row">\n${text}</tr>\n`; | ||
| }, | ||
| tablecell(token: Tokens.TableCell): string { | ||
| const content = this.parser.parseInline(token.tokens); | ||
| const type = token.header ? 'th' : 'td'; | ||
| const tag = token.align | ||
| ? `<${type} align="${token.align}">` | ||
| : `<${type}>`; | ||
| return tag + content + `</${type}>\n`; | ||
| }, | ||
| }, | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| // Test case for issue #2832 - bullet rendering with 4-space indentation | ||
| import { marked } from './lib/marked.esm.js'; | ||
|
|
||
| const testCases = [ | ||
| { | ||
| name: 'Empty nested item with 4-space indentation', | ||
| markdown: `- title | ||
| - desc | ||
| -`, | ||
| }, | ||
| { | ||
| name: 'Empty nested item with 2-space indentation', | ||
| markdown: `- title | ||
| - desc | ||
| -`, | ||
| }, | ||
| ]; | ||
|
|
||
| testCases.forEach((testCase) => { | ||
| console.log(`\n=== ${testCase.name} ===`); | ||
| console.log('Input:'); | ||
| console.log(JSON.stringify(testCase.markdown)); | ||
| console.log('\nOutput:'); | ||
| try { | ||
| const result = marked.parse(testCase.markdown); | ||
| console.log(result); | ||
| } catch(error) { | ||
| console.error('Error:', error.message); | ||
| } | ||
| }); | ||
|
Comment on lines
+1
to
+30
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This test file is a great addition to verify the fix. However, it currently only logs the output to the console, requiring manual verification. To make it a robust, automated test, you should convert it to use a test framework like |
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
tableExtensionobject is duplicated here and insrc/tableExtension.ts. This creates a maintenance burden, as changes would need to be applied in two places. It would be better to have a single source of truth. Consider compilingsrc/tableExtension.tsto JavaScript and importing it here to avoid code duplication.