@diplodoc/transform 4.54.0 → 4.57.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/dist/css/_yfm-only.css.map +1 -1
  2. package/dist/css/_yfm-only.min.css.map +1 -1
  3. package/dist/css/base.css +81 -14
  4. package/dist/css/base.css.map +3 -3
  5. package/dist/css/base.min.css +1 -1
  6. package/dist/css/base.min.css.map +3 -3
  7. package/dist/css/print.css.map +1 -1
  8. package/dist/css/yfm.css +81 -14
  9. package/dist/css/yfm.css.map +3 -3
  10. package/dist/css/yfm.min.css +1 -1
  11. package/dist/css/yfm.min.css.map +3 -3
  12. package/dist/js/_yfm-only.js.map +1 -1
  13. package/dist/js/_yfm-only.min.js.map +1 -1
  14. package/dist/js/base.js +47 -8
  15. package/dist/js/base.js.map +3 -3
  16. package/dist/js/base.min.js +1 -1
  17. package/dist/js/base.min.js.map +4 -4
  18. package/dist/js/yfm.js +47 -8
  19. package/dist/js/yfm.js.map +3 -3
  20. package/dist/js/yfm.min.js +1 -1
  21. package/dist/js/yfm.min.js.map +4 -4
  22. package/lib/constants.d.ts +2 -0
  23. package/lib/constants.js +5 -0
  24. package/lib/constants.js.map +1 -0
  25. package/lib/md.js +4 -2
  26. package/lib/md.js.map +1 -1
  27. package/lib/plugins/anchors/constants.d.ts +2 -0
  28. package/lib/plugins/anchors/constants.js +19 -1
  29. package/lib/plugins/anchors/constants.js.map +1 -1
  30. package/lib/plugins/anchors/index.d.ts +1 -0
  31. package/lib/plugins/anchors/index.js +22 -5
  32. package/lib/plugins/anchors/index.js.map +1 -1
  33. package/lib/plugins/code.js +26 -1
  34. package/lib/plugins/code.js.map +1 -1
  35. package/lib/plugins/notes/constants.d.ts +2 -1
  36. package/lib/plugins/notes/constants.js.map +1 -1
  37. package/lib/plugins/notes/index.js +1 -8
  38. package/lib/plugins/notes/index.js.map +1 -1
  39. package/lib/sanitize.js +30 -1
  40. package/lib/sanitize.js.map +1 -1
  41. package/lib/typings.d.ts +6 -1
  42. package/package.json +3 -3
  43. package/src/js/anchor.ts +18 -0
  44. package/src/js/base.ts +1 -0
  45. package/src/js/code.ts +14 -23
  46. package/src/js/utils.ts +20 -0
  47. package/src/scss/_anchor.scss +38 -8
  48. package/src/scss/_common.scss +22 -8
  49. package/src/transform/constants.ts +3 -0
  50. package/src/transform/md.ts +3 -0
  51. package/src/transform/plugins/anchors/constants.ts +21 -0
  52. package/src/transform/plugins/anchors/index.ts +52 -8
  53. package/src/transform/plugins/code.ts +34 -1
  54. package/src/transform/plugins/notes/constants.ts +3 -1
  55. package/src/transform/plugins/notes/index.ts +1 -10
  56. package/src/transform/sanitize.ts +33 -1
  57. package/src/transform/typings.ts +23 -1
@@ -68,10 +68,43 @@ function termReplace(str: string, env: EnvTerm, escape: (str: string) => string)
68
68
  return termCode || str;
69
69
  }
70
70
 
71
+ function addLineNumbers(code: string): string {
72
+ const lines = code.split('\n');
73
+ const lineCount = lines.length;
74
+ const maxDigits = String(lineCount).length;
75
+
76
+ // Remove trailing empty line if it exists
77
+ const hasTrailingNewline = code.endsWith('\n');
78
+ const linesToProcess = hasTrailingNewline ? lines.slice(0, -1) : lines;
79
+
80
+ return (
81
+ linesToProcess
82
+ .map((line, index) => {
83
+ const lineNumber = String(index + 1).padStart(maxDigits, ' ');
84
+ return `<span class="yfm-line-number">${lineNumber}</span>${line}`;
85
+ })
86
+ .join('\n') + (hasTrailingNewline ? '\n' : '')
87
+ );
88
+ }
89
+
71
90
  const code: MarkdownItPluginCb = (md) => {
72
91
  const superCodeRenderer = md.renderer.rules.fence;
73
92
  md.renderer.rules.fence = function (tokens, idx, options, env, self) {
74
- const superCode = superCodeRenderer?.(tokens, idx, options, env, self);
93
+ const token = tokens[idx];
94
+ const showLineNumbers = token.info.includes('showLineNumbers');
95
+
96
+ let superCode = superCodeRenderer?.(tokens, idx, options, env, self);
97
+
98
+ if (superCode && showLineNumbers) {
99
+ // Extract the code content from the pre/code tags
100
+ const codeMatch = superCode.match(/<pre[^>]*><code[^>]*>([\s\S]*?)<\/code><\/pre>/);
101
+ if (codeMatch) {
102
+ const codeContent = codeMatch[1];
103
+ const codeWithLineNumbers = addLineNumbers(codeContent);
104
+ superCode = superCode.replace(codeContent, codeWithLineNumbers);
105
+ }
106
+ }
107
+
75
108
  const superCodeWithTerms =
76
109
  superCode && env?.terms ? termReplace(superCode, env, md.utils.escapeRE) : superCode;
77
110
 
@@ -1,4 +1,6 @@
1
- export const TITLES: Record<string, Record<string, string>> = {
1
+ import {Lang} from '../typings';
2
+
3
+ export const TITLES: Record<Lang, Record<string, string>> = {
2
4
  ru: {
3
5
  info: 'Примечание',
4
6
  tip: 'Совет',
@@ -10,15 +10,6 @@ import {TITLES} from './constants';
10
10
  const ALERT_RE = /^{% note (alert|info|tip|warning)\s*(?:"(.*?)")? %}$/;
11
11
  const WRONG_NOTES = /^{% note (.*)%}/;
12
12
 
13
- function getTitle(type: string, originLang: keyof typeof TITLES) {
14
- let lang = originLang;
15
-
16
- if (!lang || !Object.keys(TITLES).includes(lang)) {
17
- lang = 'ru';
18
- }
19
-
20
- return TITLES[lang][type];
21
- }
22
13
  const matchCloseToken: MatchTokenFunction = (tokens, i) => {
23
14
  return (
24
15
  tokens[i].type === 'paragraph_open' &&
@@ -90,7 +81,7 @@ const index: MarkdownItPluginCb = (md, {lang, notesAutotitle, path: optPath, log
90
81
  titleOpen.block = true;
91
82
  titleClose.block = true;
92
83
 
93
- const autotitle = notesAutotitle ? getTitle(type, lang) : '';
84
+ const autotitle = notesAutotitle ? TITLES[lang][type] : '';
94
85
 
95
86
  titleInline.content = match[2] === undefined ? autotitle : match[2];
96
87
  titleInline.children = [];
@@ -1,4 +1,4 @@
1
- import sanitizeHtml from 'sanitize-html';
1
+ import sanitizeHtml, {Attributes, Tag} from 'sanitize-html';
2
2
  // @ts-ignore
3
3
  import cssfilter from 'cssfilter';
4
4
  import * as cheerio from 'cheerio';
@@ -176,6 +176,7 @@ const svgTags = [
176
176
  'view',
177
177
  'vkern',
178
178
  'animate',
179
+ 'use',
179
180
  ];
180
181
 
181
182
  const htmlAttrs = [
@@ -501,6 +502,34 @@ const allowedTags = Array.from(
501
502
  );
502
503
  const allowedAttributes = Array.from(new Set([...htmlAttrs, ...svgAttrs, ...yfmHtmlAttrs]));
503
504
 
505
+ // For hrefs within "use" only allow local links to ids that start with "#"
506
+ const useTagTransformer = (tagName: string, attribs: Attributes): Tag => {
507
+ const cleanHref = (href: string) => {
508
+ if (href.startsWith('#')) {
509
+ return href;
510
+ } else {
511
+ return null;
512
+ }
513
+ };
514
+ const cleanAttrs = (attrs: Attributes): Attributes => {
515
+ const HREF_ATTRIBUTES = ['xlink:href', 'href'];
516
+ return Object.fromEntries(
517
+ Object.entries(attrs)
518
+ .map(([key, value]) => {
519
+ if (HREF_ATTRIBUTES.includes(key)) {
520
+ return [key, cleanHref(value)];
521
+ }
522
+ return [key, value];
523
+ })
524
+ .filter(([_, value]) => value !== null),
525
+ );
526
+ };
527
+ return {
528
+ tagName,
529
+ attribs: cleanAttrs(attribs),
530
+ };
531
+ };
532
+
504
533
  export interface SanitizeOptions extends sanitizeHtml.IOptions {
505
534
  cssWhiteList?: CssWhiteList;
506
535
  disableStyleSanitizer?: boolean;
@@ -526,6 +555,9 @@ export const defaultOptions: SanitizeOptions = {
526
555
  allowVulnerableTags: true,
527
556
  parser: defaultParseOptions,
528
557
  cssWhiteList: defaultCssWhitelist,
558
+ transformTags: {
559
+ use: useTagTransformer,
560
+ },
529
561
  };
530
562
 
531
563
  function sanitizeStyleTags(dom: cheerio.CheerioAPI, cssWhiteList: CssWhiteList) {
@@ -29,6 +29,24 @@ export type Heading = {
29
29
  items?: Heading[];
30
30
  };
31
31
 
32
+ export type Lang =
33
+ | 'ru'
34
+ | 'en'
35
+ | 'ar'
36
+ | 'cs'
37
+ | 'fr'
38
+ | 'es'
39
+ | 'he'
40
+ | 'bg'
41
+ | 'et'
42
+ | 'el'
43
+ | 'pt'
44
+ | 'zh'
45
+ | 'zh-tw'
46
+ | 'kk'
47
+ | 'tr'
48
+ | 'uz';
49
+
32
50
  export interface OptionsType {
33
51
  tokens?: boolean;
34
52
  vars?: Record<string, string>;
@@ -67,6 +85,10 @@ export interface OptionsType {
67
85
  * Set value to `false` to disable it
68
86
  */
69
87
  enableMarkdownAttrs?: boolean;
88
+ supportGithubAnchors?: boolean;
89
+ disableCommonAnchors?: boolean;
90
+ useCommonAnchorButtons?: boolean;
91
+ lang?: Lang;
70
92
  [x: string]: unknown;
71
93
  }
72
94
 
@@ -89,7 +111,7 @@ export type EnvType<Extras extends {} = {}> = {
89
111
  export interface MarkdownItPluginOpts {
90
112
  path: string;
91
113
  log: Logger;
92
- lang: 'ru' | 'en' | 'es' | 'fr' | 'cs' | 'ar' | 'he';
114
+ lang: Lang;
93
115
  root: string;
94
116
  rootPublicPath: string;
95
117
  isLintRun: boolean;