Skip to content

Commit

Permalink
Add support for markdown-style links in line messages
Browse files Browse the repository at this point in the history
  • Loading branch information
ryanwjackson committed Dec 29, 2024
1 parent df636c6 commit 8abc5e8
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 5 deletions.
10 changes: 10 additions & 0 deletions packages/mermaid/src/diagrams/common/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,16 @@ export const katexRegex = /\$\$(.*)\$\$/g;
*/
export const hasKatex = (text: string): boolean => (text.match(katexRegex)?.length ?? 0) > 0;

export const markdownLinkRegex = /\[([^\]]+)]\(([^)]+)\)/;

/**
* Detect markdown links
*
* @param text - The text to test
* @returns Whether or not the text has markdown links
*/
export const hasMarkdownLink = (text: string): boolean => markdownLinkRegex.test(text);

/**
* Computes the minimum dimensions needed to display a div containing MathML
*
Expand Down
4 changes: 4 additions & 0 deletions packages/mermaid/src/diagrams/sequence/styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ const getStyles = (options) =>
stroke: none;
}
.link {
fill: #0000EE;
}
.labelBox {
stroke: ${options.labelBoxBorderColor};
fill: ${options.labelBoxBkgColor};
Expand Down
81 changes: 76 additions & 5 deletions packages/mermaid/src/diagrams/sequence/svgDraw.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import common, { calculateMathMLDimensions, hasKatex, renderKatex } from '../common/common.js';
import common, {
calculateMathMLDimensions,
hasKatex,
renderKatex,
hasMarkdownLink,
markdownLinkRegex,
} from '../common/common.js';
import * as svgDrawCommon from '../common/svgDrawCommon.js';
import { ZERO_WIDTH_SPACE, parseFontSize } from '../../utils.js';
import { sanitizeUrl } from '@braintree/sanitize-url';
Expand Down Expand Up @@ -127,6 +133,65 @@ export const drawKatex = async function (elem, textData, msgModel = null) {
return [textElem];
};

export const drawLink = function (elem, label, url) {
elem
.append('a')
.attr('xlink:href', sanitizeUrl(url))
.attr('xlink:show', 'new')
.attr('target', '_blank')
.attr('rel', 'noopener noreferrer')
.append('tspan')
.attr('class', 'link')
.text(label);
};

export const drawMarkdownLinkText = function (elem, text) {
// Split text into segments - links and text between links
const segments = [];
let remainingText = text;
let match;

// Markdown link regex: [text](url)
const linkRegex = markdownLinkRegex;

while ((match = remainingText.match(linkRegex))) {
// Push text before link if exists
if (match.index > 0) {
segments.push({
type: 'text',
content: remainingText.substring(0, match.index),
});
}

// Push link
segments.push({
type: 'link',
text: match[1],
url: match[2],
});

// Update remaining text
remainingText = remainingText.substring(match.index + match[0].length);
}

// Push remaining text if any
if (remainingText) {
segments.push({
type: 'text',
content: remainingText,
});
}

// Append all segments
segments.forEach((segment) => {
if (segment.type === 'link') {
drawLink(elem, segment.text, segment.url);
} else {
elem.append('tspan').text(segment.content);
}
});
};

export const drawText = function (elem, textData) {
let prevTextHeight = 0;
let textHeight = 0;
Expand Down Expand Up @@ -234,13 +299,19 @@ export const drawText = function (elem, textData) {
}

const text = line || ZERO_WIDTH_SPACE;
let textSpan;
if (textData.tspan) {
const span = textElem.append('tspan');
span.attr('x', textData.x);
textSpan = textElem.append('tspan');
textSpan.attr('x', textData.x);
if (textData.fill !== undefined) {
span.attr('fill', textData.fill);
textSpan.attr('fill', textData.fill);
}
span.text(text);
} else {
textSpan = textElem;
}

if (hasMarkdownLink(text)) {
drawMarkdownLinkText(textSpan, text);
} else {
textElem.text(text);
}
Expand Down

0 comments on commit 8abc5e8

Please sign in to comment.