From a618ef983a10ab4d301329aac6baaaec05724662 Mon Sep 17 00:00:00 2001 From: Barbara Valdez <34872381+barbaravaldez@users.noreply.github.com> Date: Fri, 4 Nov 2022 19:00:19 -0700 Subject: [PATCH] Display tables in html (#20640) --- .../browser/cellViews/code.component.ts | 5 ++++- .../browser/cellViews/textCell.component.ts | 18 +++++++++++++++++- .../notebook/browser/htmlMarkdownConverter.ts | 13 +++++++++++-- .../notebook/browser/notebook.component.ts | 5 ++++- .../notebook/browser/notebook.contribution.ts | 5 +++++ .../notebook/browser/turndownPluginGfm.ts | 8 ++++++++ 6 files changed, 49 insertions(+), 5 deletions(-) diff --git a/src/sql/workbench/contrib/notebook/browser/cellViews/code.component.ts b/src/sql/workbench/contrib/notebook/browser/cellViews/code.component.ts index 5ca8f46812..1b434016ac 100644 --- a/src/sql/workbench/contrib/notebook/browser/cellViews/code.component.ts +++ b/src/sql/workbench/contrib/notebook/browser/cellViews/code.component.ts @@ -99,7 +99,6 @@ export class CodeComponent extends CellView implements OnInit, OnChanges { private _editorModel: ITextModel; private _activeCellId: string; private _layoutEmitter = new Emitter(); - constructor( @Inject(IWorkbenchThemeService) private themeService: IWorkbenchThemeService, @Inject(IInstantiationService) private _instantiationService: IInstantiationService, @@ -140,6 +139,10 @@ export class CodeComponent extends CellView implements OnInit, OnChanges { } } + public refreshCell(): void { + this.updateModel(); + } + public override getEditor(): QueryTextEditor { return this._editor; } diff --git a/src/sql/workbench/contrib/notebook/browser/cellViews/textCell.component.ts b/src/sql/workbench/contrib/notebook/browser/cellViews/textCell.component.ts index 4a1c1a60d6..92aa42e865 100644 --- a/src/sql/workbench/contrib/notebook/browser/cellViews/textCell.component.ts +++ b/src/sql/workbench/contrib/notebook/browser/cellViews/textCell.component.ts @@ -157,6 +157,16 @@ export class TextCellComponent extends CellView implements OnInit, OnChanges { })); } + public reloadTables(): void { + this._htmlMarkdownConverter = this._instantiationService.createInstance(HTMLMarkdownConverter, this.notebookUri); + if (this.previewMode) { + this.updateCellSource(); + } else { + this.updateMarkdownCellSource(); + } + this.markdowncodeCell.forEach(code => code.refreshCell()); + } + public get cellEditors(): ICellEditorProvider[] { let editors: ICellEditorProvider[] = []; if (this.markdowncodeCell) { @@ -356,7 +366,13 @@ export class TextCellComponent extends CellView implements OnInit, OnChanges { private updateCellSource(): void { let textOutputElement = this.output.nativeElement; - let newCellSource: string = this._htmlMarkdownConverter.convert(textOutputElement.innerHTML); + let newCellSource = this._htmlMarkdownConverter.convert(textOutputElement.innerHTML); + this.cellModel.source = newCellSource; + this._changeRef.detectChanges(); + } + + private updateMarkdownCellSource(): void { + let newCellSource = this._htmlMarkdownConverter.convert(this.markdownResult.element.innerHTML); this.cellModel.source = newCellSource; this._changeRef.detectChanges(); } diff --git a/src/sql/workbench/contrib/notebook/browser/htmlMarkdownConverter.ts b/src/sql/workbench/contrib/notebook/browser/htmlMarkdownConverter.ts index 6a937cd070..9f16c75d93 100644 --- a/src/sql/workbench/contrib/notebook/browser/htmlMarkdownConverter.ts +++ b/src/sql/workbench/contrib/notebook/browser/htmlMarkdownConverter.ts @@ -36,7 +36,7 @@ const markdownReplacements = [ export class HTMLMarkdownConverter { private turndownService: TurndownService; - constructor(private notebookUri: URI, @IConfigurationService private configurationService: IConfigurationService,) { + constructor(private notebookUri: URI, @IConfigurationService private configurationService: IConfigurationService) { this.turndownService = new TurndownService({ 'emDelimiter': '_', 'bulletListMarker': '-', 'headingStyle': 'atx', blankReplacement: blankReplacement }); this.setTurndownOptions(); } @@ -45,9 +45,18 @@ export class HTMLMarkdownConverter { return this.turndownService.turndown(html, { gfm: true }); } + private setTableTurndownOptions() { + if (this.configurationService.getValue('notebook.renderTablesInHtml')) { + this.turndownService.keep(['table', 'tr', 'th', 'td']); + this.turndownService.use(turndownPluginGfm.gfmHtmlTables); + } else { + this.turndownService.use(turndownPluginGfm.gfm); + } + } + private setTurndownOptions() { this.turndownService.keep(['style']); - this.turndownService.use(turndownPluginGfm.gfm); + this.setTableTurndownOptions(); this.turndownService.addRule('pre', { filter: 'pre', replacement: function (content, node) { diff --git a/src/sql/workbench/contrib/notebook/browser/notebook.component.ts b/src/sql/workbench/contrib/notebook/browser/notebook.component.ts index 66fe347f38..e6590a95f4 100644 --- a/src/sql/workbench/contrib/notebook/browser/notebook.component.ts +++ b/src/sql/workbench/contrib/notebook/browser/notebook.component.ts @@ -107,12 +107,15 @@ export class NotebookComponent extends AngularDisposable implements OnInit, OnDe @Inject(ICapabilitiesService) private capabilitiesService: ICapabilitiesService, @Inject(ITextFileService) private textFileService: ITextFileService, @Inject(ILogService) private readonly logService: ILogService, - @Inject(IConfigurationService) private _configurationService: IConfigurationService + @Inject(IConfigurationService) private _configurationService: IConfigurationService, ) { super(); this.doubleClickEditEnabled = this._configurationService.getValue('notebook.enableDoubleClickEdit'); this._register(this._configurationService.onDidChangeConfiguration(e => { this.doubleClickEditEnabled = this._configurationService.getValue('notebook.enableDoubleClickEdit'); + if (e.affectsConfiguration('notebook.renderTablesInHtml')) { + this.textCells.forEach(cell => cell.reloadTables()); + } })); this._register(RedoCommand.addImplementation(PRIORITY, 'notebook-cells-undo-redo', () => { // Prevent the undo/redo from happening in other notebooks and to prevent the execution of undo/redo in the cell. diff --git a/src/sql/workbench/contrib/notebook/browser/notebook.contribution.ts b/src/sql/workbench/contrib/notebook/browser/notebook.contribution.ts index 2a8c08870c..fc18671383 100644 --- a/src/sql/workbench/contrib/notebook/browser/notebook.contribution.ts +++ b/src/sql/workbench/contrib/notebook/browser/notebook.contribution.ts @@ -357,6 +357,11 @@ configurationRegistry.registerConfiguration({ 'minimum': 10, 'description': localize('notebook.maxRichTextUndoHistory', "The maximum number of changes stored in the undo history for the notebook Rich Text editor.") }, + 'notebook.renderTablesInHtml': { + 'type': 'boolean', + 'default': false, + 'description': localize('notebook.renderTablesInHtml', "Display and save tables in HTML format in text cells instead of converting to markdown tables.") + }, 'notebook.useAbsoluteFilePaths': { 'type': 'boolean', 'default': false, diff --git a/src/sql/workbench/contrib/notebook/browser/turndownPluginGfm.ts b/src/sql/workbench/contrib/notebook/browser/turndownPluginGfm.ts index 62f705e59d..e1bd185186 100644 --- a/src/sql/workbench/contrib/notebook/browser/turndownPluginGfm.ts +++ b/src/sql/workbench/contrib/notebook/browser/turndownPluginGfm.ts @@ -178,3 +178,11 @@ export function gfm(turndownService) { taskListItems ]); } + +export function gfmHtmlTables(turndownService) { + turndownService.use([ + highlightedCodeBlock, + strikethrough, + taskListItems + ]); +}