|
1 |
| -import { Position } from 'unist' |
| 1 | +import { isComment, COMMENT_CONTENT_REGEX } from './regexp' |
| 2 | +import { Comment } from './types' |
| 3 | + |
| 4 | +import { Position, Node, Parent } from 'unist' |
2 | 5 | import { AST } from 'eslint'
|
3 | 6 | // `SourceLocation` is not exported from estree, but it is actually working
|
4 | 7 | // eslint-disable-next-line import/named
|
@@ -78,3 +81,66 @@ export const first = <T>(items: T[] | ReadonlyArray<T>) => items && items[0]
|
78 | 81 |
|
79 | 82 | export const last = <T>(items: T[] | ReadonlyArray<T>) =>
|
80 | 83 | items && items[items.length - 1]
|
| 84 | + |
| 85 | +export const normalizeJsxNode = (node: Node, parent?: Parent) => { |
| 86 | + const value = node.value as string |
| 87 | + |
| 88 | + if (isComment(value)) { |
| 89 | + return node |
| 90 | + } |
| 91 | + |
| 92 | + const matched = value.match(COMMENT_CONTENT_REGEX) |
| 93 | + |
| 94 | + if (!matched) { |
| 95 | + return node |
| 96 | + } |
| 97 | + |
| 98 | + const comments: Comment[] = [] |
| 99 | + const { |
| 100 | + position: { |
| 101 | + start: { line, column, offset: startOffset }, |
| 102 | + }, |
| 103 | + } = node |
| 104 | + |
| 105 | + return Object.assign(node, { |
| 106 | + data: { |
| 107 | + ...node.data, |
| 108 | + jsxType: 'JSXElementWithHTMLComments', |
| 109 | + comments, |
| 110 | + // jsx in paragraph is considered as plain html in mdx, what means html style comments are valid |
| 111 | + // TODO: in this case, jsx style comments could be a mistake |
| 112 | + inline: !!parent && parent.type !== 'root', |
| 113 | + }, |
| 114 | + value: value.replace( |
| 115 | + COMMENT_CONTENT_REGEX, |
| 116 | + (matched: string, $0: string, $1: string, $2: string, offset: number) => { |
| 117 | + const endOffset = offset + matched.length |
| 118 | + const startLines = value.slice(0, offset).split('\n') |
| 119 | + const endLines = value.slice(0, endOffset).split('\n') |
| 120 | + const fixed = `{/${'*'.repeat($0.length - 2)}${$1}${'*'.repeat( |
| 121 | + $2.length - 2, |
| 122 | + )}/}` |
| 123 | + const startLineOffset = startLines.length - 1 |
| 124 | + const endLineOffset = endLines.length - 1 |
| 125 | + comments.push({ |
| 126 | + fixed, |
| 127 | + loc: { |
| 128 | + start: { |
| 129 | + line: line + startLineOffset, |
| 130 | + column: |
| 131 | + last(startLines).length + (startLineOffset ? 0 : column - 1), |
| 132 | + offset: startOffset + offset, |
| 133 | + }, |
| 134 | + end: { |
| 135 | + line: line + endLineOffset - 1, |
| 136 | + column: last(endLines).length + (endLineOffset ? 0 : column - 1), |
| 137 | + offset: startOffset + endOffset, |
| 138 | + }, |
| 139 | + }, |
| 140 | + origin: matched, |
| 141 | + }) |
| 142 | + return fixed |
| 143 | + }, |
| 144 | + ), |
| 145 | + }) |
| 146 | +} |
0 commit comments