mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-13 19:48:37 -05:00
WYSIWYG Span Style Fixes, Refactor, and Tests (#13011)
* Refactor into own class, add tests * Add more tests * Test fixes * Test fix hopefully * Tests D vs C drive
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import TurndownService = require('turndown');
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import * as path from 'vs/base/common/path';
|
||||
import * as turndownPluginGfm from 'sql/workbench/contrib/notebook/browser/turndownPluginGfm';
|
||||
|
||||
export class HTMLMarkdownConverter {
|
||||
private turndownService: TurndownService;
|
||||
|
||||
constructor(private notebookUri: URI) {
|
||||
this.turndownService = new TurndownService({ 'emDelimiter': '_', 'bulletListMarker': '-', 'headingStyle': 'atx' });
|
||||
this.setTurndownOptions();
|
||||
}
|
||||
|
||||
public convert(html: string): string {
|
||||
return this.turndownService.turndown(html, { gfm: true });
|
||||
}
|
||||
|
||||
private setTurndownOptions() {
|
||||
this.turndownService.keep(['u', 'mark']);
|
||||
this.turndownService.use(turndownPluginGfm.gfm);
|
||||
this.turndownService.addRule('pre', {
|
||||
filter: 'pre',
|
||||
replacement: function (content, node) {
|
||||
return '\n```\n' + node.textContent + '\n```\n';
|
||||
}
|
||||
});
|
||||
this.turndownService.addRule('caption', {
|
||||
filter: 'caption',
|
||||
replacement: function (content, node) {
|
||||
return `${node.outerHTML}
|
||||
`;
|
||||
}
|
||||
});
|
||||
this.turndownService.addRule('span', {
|
||||
filter: 'span',
|
||||
replacement: function (content, node) {
|
||||
let beginString = '';
|
||||
let endString = '';
|
||||
// TODO: handle other background colors and more styles
|
||||
if (node?.style?.backgroundColor === 'yellow') {
|
||||
beginString = '<mark>' + beginString;
|
||||
endString += '</mark>';
|
||||
}
|
||||
if (node?.style?.fontWeight === 'bold') {
|
||||
beginString = '**' + beginString;
|
||||
endString += '**';
|
||||
}
|
||||
if (node?.style?.fontStyle === 'italic') {
|
||||
beginString = '_' + beginString;
|
||||
endString += '_';
|
||||
}
|
||||
if (node?.style?.textDecorationLine === 'underline') {
|
||||
beginString = '<u>' + beginString;
|
||||
endString += '</u>';
|
||||
}
|
||||
return beginString + node.textContent + endString;
|
||||
}
|
||||
});
|
||||
this.turndownService.addRule('img', {
|
||||
filter: 'img',
|
||||
replacement: (content, node) => {
|
||||
if (node?.src) {
|
||||
let imgPath = URI.parse(node.src);
|
||||
const notebookFolder: string = this.notebookUri ? path.join(path.dirname(this.notebookUri.fsPath), path.sep) : '';
|
||||
let relativePath = findPathRelativeToContent(notebookFolder, imgPath);
|
||||
if (relativePath) {
|
||||
return ``;
|
||||
}
|
||||
}
|
||||
return ``;
|
||||
}
|
||||
});
|
||||
this.turndownService.addRule('a', {
|
||||
filter: 'a',
|
||||
replacement: (content, node) => {
|
||||
//On Windows, if notebook is not trusted then the href attr is removed for all non-web URL links
|
||||
// href contains either a hyperlink or a URI-encoded absolute path. (See resolveUrls method in notebookMarkdown.ts)
|
||||
const notebookLink = node.href ? URI.parse(node.href) : URI.file(node.title);
|
||||
const notebookFolder = this.notebookUri ? path.join(path.dirname(this.notebookUri.fsPath), path.sep) : '';
|
||||
let relativePath = findPathRelativeToContent(notebookFolder, notebookLink);
|
||||
if (relativePath) {
|
||||
return `[${node.innerText}](${relativePath})`;
|
||||
}
|
||||
return `[${node.innerText}](${node.href})`;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function findPathRelativeToContent(notebookFolder: string, contentPath: URI | undefined): string {
|
||||
if (notebookFolder) {
|
||||
if (contentPath?.scheme === 'file') {
|
||||
let relativePath = path.relative(notebookFolder, contentPath.fsPath);
|
||||
//if path contains whitespaces then it's not identified as a link
|
||||
relativePath = relativePath.replace(/\s/g, '%20');
|
||||
if (relativePath.startsWith(path.join('..', path.sep) || path.join('.', path.sep))) {
|
||||
return relativePath;
|
||||
} else {
|
||||
// if the relative path does not contain ./ at the beginning, we need to add it so it's recognized as a link
|
||||
return `.${path.join(path.sep, relativePath)}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
Reference in New Issue
Block a user