-
Notifications
You must be signed in to change notification settings - Fork 645
Update new line identifier in MarkdownViewer and MarkdownEditor #3987
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
Changes from all commits
5bc7368
39766cb
9a0741a
1d03932
9d07bf4
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,5 @@ | ||
| --- | ||
| "@primer/react": patch | ||
| --- | ||
|
|
||
| MarkdownEditor & MarkdownViewer: Update new line identifier for formatting markdown |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,98 @@ | ||
| import {parseListItem, listItemToString, ListItem} from '../../drafts/MarkdownEditor/_useListEditing' | ||
|
|
||
| describe('parseListItem', () => { | ||
| it('should return null for a line that is not a list item', () => { | ||
| expect(parseListItem('This is a test line')).toBeNull() | ||
| }) | ||
|
|
||
| it('should parse a line that is a numbered list item', () => { | ||
| expect(parseListItem('1. This is a test line')).toEqual({ | ||
| leadingWhitespace: '', | ||
| text: 'This is a test line', | ||
| delimeter: 1, | ||
| middleWhitespace: ' ', | ||
| taskBox: null, | ||
| }) | ||
| }) | ||
|
|
||
| it('should parse a line that is a numbered list item and multiple spaces within', () => { | ||
| expect(parseListItem('1. This is a test line')).toEqual({ | ||
| leadingWhitespace: '', | ||
| text: 'This is a test line', | ||
| delimeter: 1, | ||
| middleWhitespace: ' ', | ||
| taskBox: null, | ||
| }) | ||
| }) | ||
|
|
||
| it('should parse a line that is a bulleted list item', () => { | ||
| expect(parseListItem('* This is a test line')).toEqual({ | ||
| leadingWhitespace: '', | ||
| text: 'This is a test line', | ||
| delimeter: '*', | ||
| middleWhitespace: ' ', | ||
| taskBox: null, | ||
| }) | ||
| }) | ||
|
|
||
| it('should parse a line that is a task list item', () => { | ||
| expect(parseListItem('- [x] This is a test line')).toEqual({ | ||
| leadingWhitespace: '', | ||
| text: 'This is a test line', | ||
| delimeter: '-', | ||
| middleWhitespace: ' ', | ||
| taskBox: '[x]', | ||
| }) | ||
|
|
||
| // Up to 4 spaces are supported | ||
| expect(parseListItem('- [x] This is a test line')).toEqual({ | ||
| leadingWhitespace: '', | ||
| text: 'This is a test line', | ||
| delimeter: '-', | ||
| middleWhitespace: ' ', | ||
| taskBox: '[x]', | ||
| }) | ||
|
|
||
| // 5 spaces are not supported | ||
| expect(parseListItem('- [x] This is a test line')).toEqual({ | ||
| leadingWhitespace: '', | ||
| text: ' [x] This is a test line', | ||
| delimeter: '-', | ||
| middleWhitespace: ' ', | ||
| taskBox: null, | ||
| }) | ||
|
|
||
| // Tabs are supported | ||
| expect(parseListItem('- [x] This is a test line')).toEqual({ | ||
| leadingWhitespace: '', | ||
| text: 'This is a test line', | ||
| delimeter: '-', | ||
| middleWhitespace: ' ', | ||
| taskBox: '[x]', | ||
| }) | ||
| }) | ||
| }) | ||
|
|
||
| describe('listItemToString', () => { | ||
| it('should convert a list item to a string', () => { | ||
| const item = { | ||
| leadingWhitespace: '', | ||
| text: 'This is a test line', | ||
| delimeter: 1, | ||
| middleWhitespace: ' ', | ||
| taskBox: null, | ||
| } | ||
| expect(listItemToString(item)).toBe('1. This is a test line') | ||
| }) | ||
|
|
||
| it('should convert a task list item to a string', () => { | ||
| const item = { | ||
| leadingWhitespace: '', | ||
| text: 'This is a test line', | ||
| delimeter: '-', | ||
| middleWhitespace: ' ', | ||
| taskBox: '[x]', | ||
| } as ListItem | ||
| expect(listItemToString(item)).toBe('- [x] This is a test line') | ||
| }) | ||
| }) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| import {parseCodeFenceBegin, isCodeFenceEnd} from '../../drafts/MarkdownViewer/_useListInteraction' | ||
|
|
||
| describe('parseCodeFenceBegin', () => { | ||
| it('should return null for a line without a code fence', () => { | ||
| expect(parseCodeFenceBegin('This is a test line without a code fence')).toBeNull() | ||
| }) | ||
|
|
||
| it('should return the code fence for a line with a code fence', () => { | ||
| expect(parseCodeFenceBegin('```This is a test line with a code fence')).toBe('```') | ||
| }) | ||
|
|
||
| it('should return the code fence for a line with a code fence and leading spaces', () => { | ||
| expect(parseCodeFenceBegin(' ~~~This is a test line with a code fence and leading spaces')).toBe('~~~') | ||
| }) | ||
|
|
||
| it('should return null for a line with more than 3 leading spaces before the code fence', () => { | ||
| expect( | ||
| parseCodeFenceBegin(' ```This is a test line with more than 3 leading spaces before the code fence'), | ||
| ).toBeNull() | ||
| }) | ||
| }) | ||
|
|
||
| describe('isCodeFenceEnd', () => { | ||
| it('should return true for a line that ends a code fence', () => { | ||
| expect(isCodeFenceEnd('```', '```')).toBe(true) | ||
| }) | ||
|
|
||
| it('should return false for a line that does not end a code fence', () => { | ||
| expect(isCodeFenceEnd('This is a test line', '```')).toBe(false) | ||
| }) | ||
|
|
||
| it('should return true for a line that ends a code fence with leading spaces', () => { | ||
| expect(isCodeFenceEnd(' ~~~', '~~~')).toBe(true) | ||
| }) | ||
|
|
||
| it('should return true for a line that ends a code fence with different new line characteres', () => { | ||
| expect(isCodeFenceEnd('~~~', '~~~')).toBe(true) | ||
| }) | ||
|
|
||
| it('should return false for a line with more than 3 leading spaces before the code fence end', () => { | ||
| expect(isCodeFenceEnd(' ```', '```')).toBe(false) | ||
| }) | ||
| }) |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -60,9 +60,9 @@ export const parseListItem = (line: string): ListItem | null => { | |||||
| } | ||||||
|
|
||||||
| export const listItemToString = (item: ListItem) => | ||||||
| `${item.leadingWhitespace}${typeof item.delimeter === 'number' ? `${item.delimeter}.` : item.delimeter}${ | ||||||
| item.middleWhitespace | ||||||
| }${item.taskBox || ''} ${item.text}` | ||||||
| typeof item.delimeter === 'number' | ||||||
|
Contributor
Author
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. I've split this on 2 lines for readability + different handling : in the case of numbered list, i chose to ignore the "middle" spacing and format the MD correctly - because it is displayed in the correct way, ignoring the extra spaces
Contributor
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. Not sure I totally understand this. Aren't those extra spaces always rendered as a single space? I figure we'd want to keep the user's raw markdown as close as possible to what they actually wrote when we modify it.
Contributor
Author
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. Yes, this changes the number of spaces for lists that are numbered. I intentionally did this - not sure it's correct but it was a subjective thinking that lists with numbers , given they're also displayed with single space, might as well be "fixed"
Contributor
Author
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. |
||||||
| ? `${item.leadingWhitespace}${`${item.delimeter}.`}${item.middleWhitespace}${item.text}` | ||||||
|
Contributor
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. [nit] extra string nesting is unnecessary here
Suggested change
|
||||||
| : `${item.leadingWhitespace}${item.delimeter}${item.middleWhitespace}${item.taskBox || ''} ${item.text}` | ||||||
|
|
||||||
| /** | ||||||
| * Provides support for list editing in the Markdown editor. This includes inserting new | ||||||
|
|
@@ -79,7 +79,7 @@ export const useListEditing = ({emitChange}: UseListEditingSettings): UseListEdi | |||||
|
|
||||||
| // Strip off the leading newline by adding 1 | ||||||
| const followingText = textarea.value.slice(currentLineEnd + 1) | ||||||
| const followingLines = followingText.split('\n') | ||||||
| const followingLines = followingText.split(/\r?\n/) | ||||||
|
|
||||||
| const followingNumericListItems: Array<NumericListItem> = [] | ||||||
| let prevItemNumber = currentLineItem.delimeter | ||||||
|
|
||||||
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.
👏