Skip to content

Commit

Permalink
feat: implement limit without consider image
Browse files Browse the repository at this point in the history
close: #14
  • Loading branch information
bytemain committed Feb 28, 2024
1 parent 8f78c4d commit ca904fa
Show file tree
Hide file tree
Showing 6 changed files with 120 additions and 70 deletions.
54 changes: 54 additions & 0 deletions src/github/renderer/make-mark.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { fromMarkdown } from 'mdast-util-from-markdown';
import { Content, Parent } from 'mdast-util-from-markdown/lib/index';
import { gfmFromMarkdown, gfmToMarkdown } from 'mdast-util-gfm';
import { toMarkdown } from 'mdast-util-to-markdown';
import { gfm } from 'micromark-extension-gfm';

export function parseMarkdown(text: string) {
const tree = fromMarkdown(trimLeadingWS(text), {
extensions: [gfm()],
mdastExtensions: [gfmFromMarkdown()],
});
return tree;
}

function trimLeadingWS(str: string) {
/*
Get the initial indentation
But ignore new line characters
*/
const matcher = /^[\r\n]?(\s+)/;
if (matcher.test(str)) {
/*
Replace the initial whitespace
globally and over multiple lines
*/
return str.replace(new RegExp('^' + str.match(matcher)![1], 'gm'), '');
} else {
// Regex doesn't match so return the original string
return str;
}
}

export function walk(root: Parent, cb: (token: Content) => boolean | void) {
root.children.forEach((node) => {
if (node) {
const skip = cb(node);
if (!skip) {
if ((node as Parent).children) {
walk(node as Parent, cb);
}
}
}
});
}

export function makeMarkdown(tree: Parent) {
return toMarkdown(tree, {
extensions: [gfmToMarkdown()],
listItemIndent: 'one',
rule: '-',
fence: '`',
fences: true,
});
}
6 changes: 5 additions & 1 deletion src/github/templates/utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import capitalize from 'lodash/capitalize';

import { StringBuilder, limitTextByPosition } from '@/utils/string-builder';
import {
StringBuilder,
limitTextByPosition,
tryReplaceImageToNull,
} from '@/utils/string-builder';

import { render } from '../renderer';

Expand Down
72 changes: 7 additions & 65 deletions src/github/utils.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,11 @@
import { EmitterWebhookEventName } from '@octokit/webhooks';
import { fromMarkdown } from 'mdast-util-from-markdown';
import {
Root,
Content,
Parent,
Link,
Text,
} from 'mdast-util-from-markdown/lib/index';
import { gfmFromMarkdown, gfmToMarkdown } from 'mdast-util-gfm';
import { toMarkdown } from 'mdast-util-to-markdown';
import { gfm } from 'micromark-extension-gfm';
import { Link, Text } from 'mdast-util-from-markdown/lib/index';

import { markdown } from '@/im/message';
import { ISetting } from '@/kv/types';
import { send } from '@opensumi/dingtalk-bot/lib/utils';

import { makeMarkdown, parseMarkdown, walk } from './renderer/make-mark';
import { MarkdownContent } from './types';

function securityInterception(text: string) {
Expand Down Expand Up @@ -47,45 +38,6 @@ function checkLinkIsLiteral(link: Link) {
}
}

export function walk(root: Parent, cb: (token: Content) => boolean | void) {
root.children.forEach((node) => {
if (node) {
const skip = cb(node);
if (!skip) {
if ((node as Parent).children) {
walk(node as Parent, cb);
}
}
}
});
}

function trimLeadingWS(str: string) {
/*
Get the initial indentation
But ignore new line characters
*/
const matcher = /^[\r\n]?(\s+)/;
if (matcher.test(str)) {
/*
Replace the initial whitespace
globally and over multiple lines
*/
return str.replace(new RegExp('^' + str.match(matcher)![1], 'gm'), '');
} else {
// Regex doesn't match so return the original string
return str;
}
}

function parseMarkdown(text: string) {
const tree = fromMarkdown(trimLeadingWS(text), {
extensions: [gfm()],
mdastExtensions: [gfmFromMarkdown()],
});
return tree;
}

export function replaceGitHubUrlToMarkdown(
text: string,
options: ReplaceOptions,
Expand Down Expand Up @@ -134,27 +86,13 @@ export function replaceGitHubUrlToMarkdown(
return true;
}
});
text = toMarkdown(tree, {
extensions: [gfmToMarkdown()],
listItemIndent: 'one',
rule: '-',
});

return text;
}

export function toDingtalkMarkdown(tree: Root) {
return toMarkdown(tree, {
extensions: [gfmToMarkdown()],
listItemIndent: 'one',
fence: '`',
fences: true,
});
}

export function standardizeMarkdown(text: string) {
const tree = parseMarkdown(text);
return toDingtalkMarkdown(tree);
return makeMarkdown(tree);
}

export async function sendContentToDing(
Expand Down Expand Up @@ -211,6 +149,10 @@ export async function sendToDing(
}

export function replaceGitHubText(text: string) {
if (!text.includes('<img')) {
return text;
}

let tmp = text;
let regexResult: RegExpExecArray | null = null;
do {
Expand Down
31 changes: 31 additions & 0 deletions src/utils/string-builder.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { render } from '@/github/renderer';
import { makeMarkdown, parseMarkdown, walk } from '@/github/renderer/make-mark';
import { replaceGitHubText } from '@/github/utils';

export class StringBuilder {
Expand Down Expand Up @@ -50,7 +51,37 @@ export class StringBuilder {

const LIMIT_MIN_LINE = 5;

export function tryReplaceImageToNull(text: string) {
text = replaceGitHubText(text);

const ast = parseMarkdown(text);

let imageCount = 0;

walk(ast, (node) => {
if (node.type === 'image') {
imageCount++;
node.url = '';
node.alt = '';
node.title = '';
return true;
}
});

const result = makeMarkdown(ast);

return { result, imageCount };
}

export function limitTextByPosition(text: string, position: number) {
// replace all image url to null
const { result, imageCount } = tryReplaceImageToNull(text);

// if images count less than 8, we only process the non-image text
if (imageCount < 8) {
text = result;
}

const arrayOfLines = text.replace(/\r\n|\n\r|\n|\r/g, '\n').split('\n');

let count = 0;
Expand Down
9 changes: 9 additions & 0 deletions test/github/__snapshots__/utils.test.ts.snap
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`github utils can replace image to null 1`] = `
{
"imageCount": 1,
"result": "![]()
看起来这个分支有个报错关于 TerminalClient 的,有可能是 init 时机有点问题
",
}
`;

exports[`github utils can transform image 1`] = `
"![](https://user-images.githubusercontent.com/2226423/153811718-2babbfa7-e63f-4ec7-9fd3-9f450beaad9b.png)
看起来这个分支有个报错关于 TerminalClient 的,有可能是 init 时机有点问题"
Expand Down
18 changes: 14 additions & 4 deletions test/github/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,16 @@ import {
parseGitHubUrl,
standardizeMarkdown,
} from '@/github/utils';
import { StringBuilder, limitTextByPosition } from '@/utils/string-builder';
import {
StringBuilder,
limitTextByPosition,
tryReplaceImageToNull,
} from '@/utils/string-builder';
import * as DingUtils from '@opensumi/dingtalk-bot/lib/utils';

const commentWithImg = `<img width="954" alt="image" src="https://user-images.githubusercontent.com/2226423/153811718-2babbfa7-e63f-4ec7-9fd3-9f450beaad9b.png">
看起来这个分支有个报错关于 TerminalClient 的,有可能是 init 时机有点问题`;

describe('github utils', () => {
it('can limit lines', () => {
const text = `line1\nline2\nline3\n`;
Expand All @@ -17,9 +24,7 @@ describe('github utils', () => {
});

it('can transform image', () => {
const comment = `<img width="954" alt="image" src="https://user-images.githubusercontent.com/2226423/153811718-2babbfa7-e63f-4ec7-9fd3-9f450beaad9b.png">
看起来这个分支有个报错关于 TerminalClient 的,有可能是 init 时机有点问题`;
const data = new StringBuilder(comment);
const data = new StringBuilder(commentWithImg);
expect(data.build()).toMatchSnapshot();
});

Expand Down Expand Up @@ -293,4 +298,9 @@ https://github.com/opensumi/core/blob/3455b10620badfe7b03a02d66136d3226b7891b8/p
expect(result).toContain(`hi\\~`);
console.log(`it ~ result:`, result);
});

it('can replace image to null', () => {
const d = tryReplaceImageToNull(commentWithImg);
expect(d).toMatchSnapshot();
});
});

0 comments on commit ca904fa

Please sign in to comment.