dd700bdbc67a1b73b412b5ca9bcb061c32e0823f56a9b22d2aef267ae40139cf4b82d332b3ced1ba4511a26ddffbe5a47b1fb65942544b0163f095c5d3c147 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. /*---------------------------------------------------------------------------------------------
  2. * Copyright (c) Microsoft Corporation. All rights reserved.
  3. * Licensed under the MIT License. See License.txt in the project root for license information.
  4. *--------------------------------------------------------------------------------------------*/
  5. import { illegalArgument } from './errors.js';
  6. import { escapeIcons } from './iconLabels.js';
  7. import { escapeRegExpCharacters } from './strings.js';
  8. export class MarkdownString {
  9. constructor(value = '', isTrustedOrOptions = false) {
  10. var _a, _b, _c;
  11. this.value = value;
  12. if (typeof this.value !== 'string') {
  13. throw illegalArgument('value');
  14. }
  15. if (typeof isTrustedOrOptions === 'boolean') {
  16. this.isTrusted = isTrustedOrOptions;
  17. this.supportThemeIcons = false;
  18. this.supportHtml = false;
  19. }
  20. else {
  21. this.isTrusted = (_a = isTrustedOrOptions.isTrusted) !== null && _a !== void 0 ? _a : undefined;
  22. this.supportThemeIcons = (_b = isTrustedOrOptions.supportThemeIcons) !== null && _b !== void 0 ? _b : false;
  23. this.supportHtml = (_c = isTrustedOrOptions.supportHtml) !== null && _c !== void 0 ? _c : false;
  24. }
  25. }
  26. appendText(value, newlineStyle = 0 /* MarkdownStringTextNewlineStyle.Paragraph */) {
  27. this.value += escapeMarkdownSyntaxTokens(this.supportThemeIcons ? escapeIcons(value) : value)
  28. .replace(/([ \t]+)/g, (_match, g1) => ' '.repeat(g1.length))
  29. .replace(/\>/gm, '\\>')
  30. .replace(/\n/g, newlineStyle === 1 /* MarkdownStringTextNewlineStyle.Break */ ? '\\\n' : '\n\n');
  31. return this;
  32. }
  33. appendMarkdown(value) {
  34. this.value += value;
  35. return this;
  36. }
  37. appendCodeblock(langId, code) {
  38. this.value += '\n```';
  39. this.value += langId;
  40. this.value += '\n';
  41. this.value += code;
  42. this.value += '\n```\n';
  43. return this;
  44. }
  45. appendLink(target, label, title) {
  46. this.value += '[';
  47. this.value += this._escape(label, ']');
  48. this.value += '](';
  49. this.value += this._escape(String(target), ')');
  50. if (title) {
  51. this.value += ` "${this._escape(this._escape(title, '"'), ')')}"`;
  52. }
  53. this.value += ')';
  54. return this;
  55. }
  56. _escape(value, ch) {
  57. const r = new RegExp(escapeRegExpCharacters(ch), 'g');
  58. return value.replace(r, (match, offset) => {
  59. if (value.charAt(offset - 1) !== '\\') {
  60. return `\\${match}`;
  61. }
  62. else {
  63. return match;
  64. }
  65. });
  66. }
  67. }
  68. export function isEmptyMarkdownString(oneOrMany) {
  69. if (isMarkdownString(oneOrMany)) {
  70. return !oneOrMany.value;
  71. }
  72. else if (Array.isArray(oneOrMany)) {
  73. return oneOrMany.every(isEmptyMarkdownString);
  74. }
  75. else {
  76. return true;
  77. }
  78. }
  79. export function isMarkdownString(thing) {
  80. if (thing instanceof MarkdownString) {
  81. return true;
  82. }
  83. else if (thing && typeof thing === 'object') {
  84. return typeof thing.value === 'string'
  85. && (typeof thing.isTrusted === 'boolean' || thing.isTrusted === undefined)
  86. && (typeof thing.supportThemeIcons === 'boolean' || thing.supportThemeIcons === undefined);
  87. }
  88. return false;
  89. }
  90. export function escapeMarkdownSyntaxTokens(text) {
  91. // escape markdown syntax tokens: http://daringfireball.net/projects/markdown/syntax#backslash
  92. return text.replace(/[\\`*_{}[\]()#+\-!]/g, '\\$&');
  93. }
  94. export function escapeDoubleQuotes(input) {
  95. return input.replace(/"/g, '"');
  96. }
  97. export function removeMarkdownEscapes(text) {
  98. if (!text) {
  99. return text;
  100. }
  101. return text.replace(/\\([\\`*_{}[\]()#+\-.!])/g, '$1');
  102. }
  103. export function parseHrefAndDimensions(href) {
  104. const dimensions = [];
  105. const splitted = href.split('|').map(s => s.trim());
  106. href = splitted[0];
  107. const parameters = splitted[1];
  108. if (parameters) {
  109. const heightFromParams = /height=(\d+)/.exec(parameters);
  110. const widthFromParams = /width=(\d+)/.exec(parameters);
  111. const height = heightFromParams ? heightFromParams[1] : '';
  112. const width = widthFromParams ? widthFromParams[1] : '';
  113. const widthIsFinite = isFinite(parseInt(width));
  114. const heightIsFinite = isFinite(parseInt(height));
  115. if (widthIsFinite) {
  116. dimensions.push(`width="${width}"`);
  117. }
  118. if (heightIsFinite) {
  119. dimensions.push(`height="${height}"`);
  120. }
  121. }
  122. return { href, dimensions };
  123. }