Skip to content

Add Markdown Link Converter Script#8650

Open
arman-boyakhchyan wants to merge 1 commit intoDevExpress:26_1from
arman-boyakhchyan:markdown-link-converter-26-1
Open

Add Markdown Link Converter Script#8650
arman-boyakhchyan wants to merge 1 commit intoDevExpress:26_1from
arman-boyakhchyan:markdown-link-converter-26-1

Conversation

@arman-boyakhchyan
Copy link
Copy Markdown
Contributor

No description provided.

@arman-boyakhchyan arman-boyakhchyan self-assigned this Apr 8, 2026
Copilot AI review requested due to automatic review settings April 8, 2026 09:26
Comment thread tools/convert-links.js
}

const indent = indentMatch[0];
const commentRegex = new RegExp(`^${escapeForRegex(indent)}(?:<!--\s*tab:\s*index\.html\s*-->|<!--\s*HTML\s*-->)\s*$`, 'i');
Comment thread tools/convert-links.js
}

const indent = indentMatch[0];
const commentRegex = new RegExp(`^${escapeForRegex(indent)}(?:<!--\s*tab:\s*index\.html\s*-->|<!--\s*HTML\s*-->)\s*$`, 'i');
Comment thread tools/convert-links.js
}

const indent = indentMatch[0];
const commentRegex = new RegExp(`^${escapeForRegex(indent)}(?:<!--\s*tab:\s*index\.html\s*-->|<!--\s*HTML\s*-->)\s*$`, 'i');
Comment thread tools/convert-links.js
}

const indent = indentMatch[0];
const commentRegex = new RegExp(`^${escapeForRegex(indent)}(?:<!--\s*tab:\s*index\.html\s*-->|<!--\s*HTML\s*-->)\s*$`, 'i');
Comment thread tools/convert-links.js
}

const indent = indentMatch[0];
const commentRegex = new RegExp(`^${escapeForRegex(indent)}(?:<!--\s*tab:\s*index\.html\s*-->|<!--\s*HTML\s*-->)\s*$`, 'i');
Comment thread tools/convert-links.js
}

const indent = indentMatch[0];
const commentRegex = new RegExp(`^${escapeForRegex(indent)}(?:<!--\s*tab:\s*index\.html\s*-->|<!--\s*HTML\s*-->)\s*$`, 'i');
Comment thread tools/convert-links.js
}

const indent = indentMatch[0];
const commentRegex = new RegExp(`^${escapeForRegex(indent)}(?:<!--\s*tab:\s*index\.html\s*-->|<!--\s*HTML\s*-->)\s*$`, 'i');
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a repository-local CLI script intended to convert HTML <a target="_blank" href="...">...</a> links into Markdown links and wires it into package.json as an npm script.

Changes:

  • Introduces tools/convert-links.js to rewrite qualifying HTML anchor tags into Markdown link syntax.
  • Adds a convert-links npm script entry in package.json to run the converter.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

File Description
tools/convert-links.js New converter script to rewrite certain HTML links into Markdown format.
package.json Adds an npm script entry to run the new converter.

Comment thread package.json
"rename-topics": "ts-node ./tools/updateFolder.ts",
"rename-uid": "ts-node ./tools/rename-uid.ts ./api-reference uid-map.json"
"rename-uid": "ts-node ./tools/rename-uid.ts ./api-reference uid-map.json",
"convert-links": "ts-node ./tools/convert-links.js"
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new npm script runs a .js file via ts-node. By default, ts-node does not execute plain JavaScript unless it is configured with allowJs, so this script can fail in a clean environment. Either run it with node or rename the file to .ts and keep ts-node consistent with the other tools/*.ts scripts.

Suggested change
"convert-links": "ts-node ./tools/convert-links.js"
"convert-links": "node ./tools/convert-links.js"

Copilot uses AI. Check for mistakes.
Comment thread tools/convert-links.js
Comment on lines +52 to +71
function getFilePaths(targetPath) {
const stats = fs.statSync(targetPath);

if (stats.isFile()) {
return [targetPath];
}

if (!stats.isDirectory()) {
return [];
}

return fs.readdirSync(targetPath, { withFileTypes: true }).flatMap((entry) => {
const entryPath = path.join(targetPath, entry.name);

if (entry.isDirectory()) {
return getFilePaths(entryPath);
}

return entry.isFile() ? [entryPath] : [];
});
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This script recursively enumerates all files under the provided path and reads them as UTF-8. If the user passes the repo root, it will traverse directories like images/, applications/, and even .git/, which is very slow and can also corrupt non-text files if a match happens to occur. Consider skipping well-known non-doc directories and/or filtering to documentation extensions (for example, only .md/.mdx).

Copilot uses AI. Check for mistakes.
Comment thread tools/convert-links.js
Comment on lines +74 to +82
function convertFile(filePath) {
const content = fs.readFileSync(filePath, 'utf-8');
const updatedContent = content.replace(linkRegex, (match, href, innerHtml, offset) => {
if (isInsideTableCell(content, offset) || isInsideCodeSnippet(content, offset)) {
return match;
}

return `[${innerHtml}](${href})`;
});
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because there is no extension filtering, the converter will also rewrite HTML sample files under applications/** that contain <a ... target="_blank">...</a> (often with nested tags like <b>), producing invalid Markdown inside .html files. Limit conversion to Markdown files (or make the allowed extensions explicit via CLI args) to avoid breaking sample applications.

Copilot uses AI. Check for mistakes.
Comment thread tools/convert-links.js
Comment on lines +1 to +8
let fs = require('fs');
let path = require('path');

const specifiedPath = process.argv[2];
const linkRegex = /<a\b(?=[^>]*\btarget=["']_blank["'])[^>]*\bhref=["']([^"']*)["'][^>]*>([\s\S]*?)<\/a>/gi;

function isInsideTableCell(content, offset) {
const before = content.slice(0, offset).toLowerCase();
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This tool uses CommonJS require and untyped function signatures, while the existing scripts in tools/ are TypeScript (tools/updateFolder.ts, tools/rename-uid.ts) and are executed via ts-node. For consistency and easier maintenance, consider converting this script to TypeScript (ES imports + basic types) or, if it stays JavaScript, run it with node and keep tools/ scripts consistently authored/executed.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants