Skip to content

Commit f0def4a

Browse files
committed
Replaces markdown component w/ existing component
Moves markdown web component into shared Moves markdown-related functions to a dedicated file
1 parent cc11bbd commit f0def4a

File tree

12 files changed

+67
-87
lines changed

12 files changed

+67
-87
lines changed

package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17951,7 +17951,6 @@
1795117951
"@swc/core": "1.7.28",
1795217952
"@twbs/fantasticon": "3.0.0",
1795317953
"@types/eslint__js": "8.42.3",
17954-
"@types/markdown-it": "^14.1.2",
1795517954
"@types/mocha": "10.0.8",
1795617955
"@types/node": "18.15.0",
1795717956
"@types/react": "17.0.82",

src/annotations/autolinks.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@ import { debug } from '../system/decorators/log';
1515
import { encodeUrl } from '../system/encoding';
1616
import { join, map } from '../system/iterable';
1717
import { Logger } from '../system/logger';
18+
import { escapeMarkdown } from '../system/markdown';
1819
import type { MaybePausedResult } from '../system/promise';
19-
import { capitalize, encodeHtmlWeak, escapeMarkdown, escapeRegex, getSuperscript } from '../system/string';
20+
import { capitalize, encodeHtmlWeak, escapeRegex, getSuperscript } from '../system/string';
2021
import { configuration } from '../system/vscode/configuration';
2122

2223
const emptyAutolinkMap = Object.freeze(new Map<string, Autolink>());

src/git/formatters/commitFormatter.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,10 @@ import { emojify } from '../../emojis';
2323
import { arePlusFeaturesEnabled } from '../../plus/gk/utils';
2424
import type { ShowInCommitGraphCommandArgs } from '../../plus/webviews/graph/protocol';
2525
import { join, map } from '../../system/iterable';
26+
import { escapeMarkdown } from '../../system/markdown';
2627
import { isPromise } from '../../system/promise';
2728
import type { TokenOptions } from '../../system/string';
28-
import { encodeHtmlWeak, escapeMarkdown, getSuperscript } from '../../system/string';
29+
import { encodeHtmlWeak, getSuperscript } from '../../system/string';
2930
import { configuration } from '../../system/vscode/configuration';
3031
import type { ContactPresence } from '../../vsls/vsls';
3132
import type { PreviousLineComparisonUrisResult } from '../gitProvider';

src/git/remotes/github.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ import type { Brand, Unbrand } from '../../system/brand';
99
import { fromNow } from '../../system/date';
1010
import { memoize } from '../../system/decorators/memoize';
1111
import { encodeUrl } from '../../system/encoding';
12-
import { equalsIgnoreCase, escapeMarkdown, unescapeMarkdown } from '../../system/string';
12+
import { escapeMarkdown, unescapeMarkdown } from '../../system/markdown';
13+
import { equalsIgnoreCase } from '../../system/string';
1314
import { getIssueOrPullRequestMarkdownIcon } from '../models/issue';
1415
import { isSha } from '../models/reference';
1516
import type { Repository } from '../models/repository';

src/git/remotes/gitlab.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ import type { Brand, Unbrand } from '../../system/brand';
88
import { fromNow } from '../../system/date';
99
import { memoize } from '../../system/decorators/memoize';
1010
import { encodeUrl } from '../../system/encoding';
11-
import { equalsIgnoreCase, escapeMarkdown, unescapeMarkdown } from '../../system/string';
11+
import { escapeMarkdown, unescapeMarkdown } from '../../system/markdown';
12+
import { equalsIgnoreCase } from '../../system/string';
1213
import { getIssueOrPullRequestMarkdownIcon } from '../models/issue';
1314
import { isSha } from '../models/reference';
1415
import type { Repository } from '../models/repository';

src/system/markdown.ts

Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,39 @@
1+
const escapeMarkdownRegex = /[\\*_{}[\]()#+\-.!]/g;
2+
const unescapeMarkdownRegex = /\\([\\`*_{}[\]()#+\-.!])/g;
3+
4+
const escapeMarkdownHeaderRegex = /^===/gm;
5+
const unescapeMarkdownHeaderRegex = /^\u200b===/gm;
6+
7+
// const sampleMarkdown = '## message `not code` *not important* _no underline_ \n> don\'t quote me \n- don\'t list me \n+ don\'t list me \n1. don\'t list me \nnot h1 \n=== \nnot h2 \n---\n***\n---\n___';
8+
const markdownQuotedRegex = /\r?\n/g;
9+
const markdownBacktickRegex = /`/g;
10+
11+
export function escapeMarkdown(s: string, options: { quoted?: boolean; inlineBackticks?: boolean } = {}): string {
12+
s = s
13+
// Escape markdown
14+
.replace(escapeMarkdownRegex, '\\$&')
15+
// Escape markdown header (since the above regex won't match it)
16+
.replace(escapeMarkdownHeaderRegex, '\u200b===');
17+
18+
if (options.inlineBackticks) {
19+
s = escapeMarkdownCodeBlocks(s);
20+
} else {
21+
s = s.replace(markdownBacktickRegex, '\\$&');
22+
}
23+
if (!options.quoted) return s;
24+
25+
// Keep under the same block-quote but with line breaks
26+
return s.trim().replace(markdownQuotedRegex, '\t\\\n> ');
27+
}
28+
129
/**
230
* escapes markdown code blocks
331
*/
4-
function escapeTripleBackticks(s: string) {
32+
export function escapeMarkdownCodeBlocks(s: string) {
533
const tripleBackticks = '```';
634
const escapedTripleBackticks = '\\`\\`\\`';
7-
let str = '';
35+
36+
let result = '';
837
let allowed = true;
938
let quotesOpened = false;
1039
let buffer = '';
@@ -19,9 +48,9 @@ function escapeTripleBackticks(s: string) {
1948
if (quotesOpened) {
2049
quotesOpened = false;
2150
if (allowed) {
22-
str += `${tripleBackticks}${buffer}${tripleBackticks}`;
51+
result += `${tripleBackticks}${buffer}${tripleBackticks}`;
2352
} else {
24-
str += `${escapedTripleBackticks}${buffer}${escapedTripleBackticks}`;
53+
result += `${escapedTripleBackticks}${buffer}${escapedTripleBackticks}`;
2554
allowed = true;
2655
}
2756
buffer = '';
@@ -35,10 +64,24 @@ function escapeTripleBackticks(s: string) {
3564
if (quotesOpened) {
3665
buffer += char;
3766
} else {
38-
str += char;
67+
result += char;
3968
}
4069
}
41-
return str;
70+
71+
if (quotesOpened) {
72+
// Handle unclosed code block
73+
result += allowed ? tripleBackticks + buffer : escapedTripleBackticks + buffer;
74+
}
75+
76+
return result;
4277
}
4378

44-
export { escapeTripleBackticks };
79+
export function unescapeMarkdown(s: string): string {
80+
return (
81+
s
82+
// Unescape markdown
83+
.replace(unescapeMarkdownRegex, '$1')
84+
// Unescape markdown header
85+
.replace(unescapeMarkdownHeaderRegex, '===')
86+
);
87+
}

src/system/string.ts

Lines changed: 0 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import type {
66
} from '@gk-nzaytsev/fast-string-truncated-width';
77
import getTruncatedStringWidth from '@gk-nzaytsev/fast-string-truncated-width';
88
import { CharCode } from '../constants';
9-
import { escapeTripleBackticks } from './markdown';
109

1110
export { fromBase64, base64 } from '@env/base64';
1211

@@ -131,44 +130,6 @@ export function encodeHtmlWeak(s: string | undefined): string | undefined {
131130
});
132131
}
133132

134-
const escapeMarkdownRegex = /[\\*_{}[\]()#+\-.!]/g;
135-
const unescapeMarkdownRegex = /\\([\\`*_{}[\]()#+\-.!])/g;
136-
137-
const escapeMarkdownHeaderRegex = /^===/gm;
138-
const unescapeMarkdownHeaderRegex = /^\u200b===/gm;
139-
140-
// const sampleMarkdown = '## message `not code` *not important* _no underline_ \n> don\'t quote me \n- don\'t list me \n+ don\'t list me \n1. don\'t list me \nnot h1 \n=== \nnot h2 \n---\n***\n---\n___';
141-
const markdownQuotedRegex = /\r?\n/g;
142-
const markdownBacktickRegex = /`/g;
143-
144-
export function escapeMarkdown(s: string, options: { quoted?: boolean; inlineBackticks?: boolean } = {}): string {
145-
s = s
146-
// Escape markdown
147-
.replace(escapeMarkdownRegex, '\\$&')
148-
// Escape markdown header (since the above regex won't match it)
149-
.replace(escapeMarkdownHeaderRegex, '\u200b===');
150-
151-
if (options.inlineBackticks) {
152-
s = escapeTripleBackticks(s);
153-
} else {
154-
s = s.replace(markdownBacktickRegex, '\\$&');
155-
}
156-
if (!options.quoted) return s;
157-
158-
// Keep under the same block-quote but with line breaks
159-
return s.trim().replace(markdownQuotedRegex, '\t\\\n> ');
160-
}
161-
162-
export function unescapeMarkdown(s: string): string {
163-
return (
164-
s
165-
// Unescape markdown
166-
.replace(unescapeMarkdownRegex, '$1')
167-
// Unescape markdown header
168-
.replace(unescapeMarkdownHeaderRegex, '===')
169-
);
170-
}
171-
172133
export function escapeRegex(s: string) {
173134
return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
174135
}

src/webviews/apps/plus/graph/GraphWrapper.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ import { createCommandLink } from '../../shared/commands';
7171
import { GlButton } from '../../shared/components/button.react';
7272
import { CodeIcon } from '../../shared/components/code-icon.react';
7373
import { GlConnect } from '../../shared/components/integrations/connect.react';
74+
import { GlMarkdown } from '../../shared/components/markdown/markdown.react';
7475
import { MenuDivider, MenuItem, MenuLabel, MenuList } from '../../shared/components/menu/react';
7576
import { PopMenu } from '../../shared/components/overlays/pop-menu/react';
7677
import { GlPopover } from '../../shared/components/overlays/popover.react';
@@ -83,7 +84,6 @@ import type { SearchNavigationEventDetail } from '../../shared/components/search
8384
import type { DateTimeFormat } from '../../shared/date';
8485
import { formatDate, fromNow } from '../../shared/date';
8586
import { GlGraphHover } from './hover/graphHover.react';
86-
import { Markdown } from './markdown/markdown';
8787
import type { GraphMinimapDaySelectedEventDetail } from './minimap/minimap';
8888
import { GlGraphMinimapContainer } from './minimap/minimap-container.react';
8989
import { GlGraphSideBar } from './sidebar/sidebar.react';
@@ -1606,7 +1606,7 @@ export function GraphWrapper({
16061606
columnsSettings={columns}
16071607
contexts={context}
16081608
// @ts-expect-error returnType of formatCommitMessage callback expects to be string, but it works fine with react element
1609-
formatCommitMessage={e => <Markdown>{e}</Markdown>}
1609+
formatCommitMessage={e => <GlMarkdown markdown={e}></GlMarkdown>}
16101610
cssVariables={styleProps?.cssVariables}
16111611
dimMergeCommits={graphConfig?.dimMergeCommits}
16121612
downstreamsByUpstream={downstreams}

src/webviews/apps/plus/graph/hover/graphHover.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ import { debounce } from '../../../../../system/function';
88
import { getSettledValue, isPromise } from '../../../../../system/promise';
99
import { GlElement } from '../../../shared/components/element';
1010
import type { GlPopover } from '../../../shared/components/overlays/popover.react';
11+
import '../../../shared/components/markdown/markdown';
1112
import '../../../shared/components/overlays/popover';
12-
import './markdown';
1313

1414
declare global {
1515
interface HTMLElementTagNameMap {

src/webviews/apps/plus/graph/markdown/markdown.tsx

Lines changed: 0 additions & 32 deletions
This file was deleted.

0 commit comments

Comments
 (0)