@mdit-vue/shared 0.7.0 → 0.7.1

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mdit-vue/shared",
3
- "version": "0.7.0",
3
+ "version": "0.7.1",
4
4
  "description": "Shared utils and types of mdit-vue",
5
5
  "keywords": [
6
6
  "markdown-it",
@@ -17,6 +17,7 @@
17
17
  },
18
18
  "license": "MIT",
19
19
  "author": "meteorlxy <meteor.lxy@foxmail.com>",
20
+ "type": "module",
20
21
  "exports": {
21
22
  ".": {
22
23
  "types": "./dist/index.d.ts",
@@ -27,22 +28,25 @@
27
28
  "main": "./dist/index.cjs",
28
29
  "module": "./dist/index.mjs",
29
30
  "types": "./dist/index.d.ts",
31
+ "files": [
32
+ "./dist"
33
+ ],
30
34
  "scripts": {
31
35
  "build": "unbuild",
32
36
  "test": "vitest"
33
37
  },
34
38
  "dependencies": {
35
- "@mdit-vue/types": "0.7.0",
39
+ "@mdit-vue/types": "0.7.1",
36
40
  "@types/markdown-it": "^12.2.3",
37
41
  "markdown-it": "^13.0.1"
38
42
  },
39
43
  "devDependencies": {
40
- "c8": "^7.11.3",
41
- "unbuild": "^0.7.4",
44
+ "c8": "^7.12.0",
45
+ "unbuild": "^0.7.6",
42
46
  "vitest": "^0.18.1"
43
47
  },
44
48
  "publishConfig": {
45
49
  "access": "public"
46
50
  },
47
- "gitHead": "dd30ddd75ca461f775ccc35556132851ebc5e58a"
51
+ "gitHead": "b4b8bc6c054ea2dd9ad9ec7a37a58b5a2147b2bd"
48
52
  }
package/CHANGELOG.md DELETED
@@ -1,35 +0,0 @@
1
- # Change Log
2
-
3
- All notable changes to this project will be documented in this file.
4
- See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
-
6
- # [0.7.0](https://github.com/mdit-vue/mdit-vue/compare/v0.6.0...v0.7.0) (2022-07-18)
7
-
8
- **Note:** Version bump only for package @mdit-vue/shared
9
-
10
- # [0.6.0](https://github.com/mdit-vue/mdit-vue/compare/v0.5.0...v0.6.0) (2022-07-11)
11
-
12
- ### Features
13
-
14
- - **types:** extract types from shared package ([5fc56ce](https://github.com/mdit-vue/mdit-vue/commit/5fc56ce6439159584e09e13ca9a6e87abe8f4389))
15
-
16
- # [0.5.0](https://github.com/mdit-vue/mdit-vue/compare/v0.4.0...v0.5.0) (2022-07-06)
17
-
18
- **Note:** Version bump only for package @mdit-vue/shared
19
-
20
- # [0.4.0](https://github.com/mdit-vue/mdit-vue/compare/v0.3.1...v0.4.0) (2022-07-02)
21
-
22
- **Note:** Version bump only for package @mdit-vue/shared
23
-
24
- # [0.3.0](https://github.com/mdit-vue/mdit-vue/compare/v0.2.0...v0.3.0) (2022-06-25)
25
-
26
- ### Features
27
-
28
- - **plugin-toc:** add toc plugin ([e64cc2c](https://github.com/mdit-vue/mdit-vue/commit/e64cc2ce3bbc89999d373f8a00fb3a049d6af58f))
29
- - **shared:** add html escape and unescape utils ([e1103c2](https://github.com/mdit-vue/mdit-vue/commit/e1103c21998aec77c67cdefd3cbb4994c127124c))
30
-
31
- # [0.2.0](https://github.com/mdit-vue/mdit-vue/compare/v0.1.1...v0.2.0) (2022-06-23)
32
-
33
- ### Features
34
-
35
- - **shared:** add shared package ([9e36bdc](https://github.com/mdit-vue/mdit-vue/commit/9e36bdce8635ae048e8b0f2cc2d02cc0448ad09f))
package/build.config.ts DELETED
@@ -1,11 +0,0 @@
1
- import { defineBuildConfig } from 'unbuild';
2
-
3
- export default defineBuildConfig({
4
- clean: true,
5
- declaration: true,
6
- entries: ['src/index'],
7
- rollup: {
8
- emitCJS: true,
9
- inlineDependencies: false,
10
- },
11
- });
@@ -1,18 +0,0 @@
1
- const htmlEscapeMap = {
2
- '&': '&amp;',
3
- '<': '&lt;',
4
- '>': '&gt;',
5
- "'": '&#39;',
6
- '"': '&quot;',
7
- };
8
-
9
- const htmlEscapeRegexp = /[&<>'"]/g;
10
-
11
- /**
12
- * Escape html chars
13
- */
14
- export const htmlEscape = (str: string): string =>
15
- str.replace(
16
- htmlEscapeRegexp,
17
- (char) => htmlEscapeMap[char as keyof typeof htmlEscapeMap],
18
- );
@@ -1,23 +0,0 @@
1
- const htmlUnescapeMap = {
2
- '&amp;': '&',
3
- '&#38;': '&',
4
- '&lt;': '<',
5
- '&#60;': '<',
6
- '&gt;': '>',
7
- '&#62;': '>',
8
- '&apos;': "'",
9
- '&#39;': "'",
10
- '&quot;': '"',
11
- '&#34;': '"',
12
- };
13
-
14
- const htmlUnescapeRegexp = /&(amp|#38|lt|#60|gt|#62|apos|#39|quot|#34);/g;
15
-
16
- /**
17
- * Unescape html chars
18
- */
19
- export const htmlUnescape = (str: string): string =>
20
- str.replace(
21
- htmlUnescapeRegexp,
22
- (char) => htmlUnescapeMap[char as keyof typeof htmlUnescapeMap],
23
- );
package/src/index.ts DELETED
@@ -1,5 +0,0 @@
1
- export * from './html-escape';
2
- export * from './html-unescape';
3
- export * from './resolve-headers-from-tokens';
4
- export * from './resolve-title-from-token';
5
- export * from './slugify';
@@ -1,102 +0,0 @@
1
- import type { MarkdownItHeader } from '@mdit-vue/types';
2
- import type Token from 'markdown-it/lib/token';
3
- import { resolveTitleFromToken } from './resolve-title-from-token';
4
- import type { ResolveTitleOptions } from './resolve-title-from-token';
5
-
6
- export interface ResolveHeadersOptions extends ResolveTitleOptions {
7
- /**
8
- * Heading level that going to be resolved
9
- */
10
- level: number[];
11
-
12
- /**
13
- * A custom slugification function
14
- *
15
- * Would be ignored if the `id` attr of the token is set.
16
- */
17
- slugify: (str: string) => string;
18
-
19
- /**
20
- * A function for formatting headings
21
- */
22
- format?: (str: string) => string;
23
- }
24
-
25
- /**
26
- * Resolve headers from markdown-it tokens
27
- */
28
- export const resolveHeadersFromTokens = (
29
- tokens: Token[],
30
- {
31
- level,
32
- shouldAllowHtml,
33
- shouldEscapeText,
34
- slugify,
35
- format,
36
- }: ResolveHeadersOptions,
37
- ): MarkdownItHeader[] => {
38
- // store the result of headers
39
- const headers: MarkdownItHeader[] = [];
40
-
41
- // a temp headers stack for generating the headers tree
42
- const stack: MarkdownItHeader[] = [];
43
-
44
- // push a header to the headers tree
45
- const push = (header: MarkdownItHeader): void => {
46
- while (stack.length !== 0 && header.level <= stack[0].level) {
47
- stack.shift();
48
- }
49
-
50
- if (stack.length === 0) {
51
- headers.push(header);
52
- stack.push(header);
53
- } else {
54
- stack[0].children.push(header);
55
- stack.unshift(header);
56
- }
57
- };
58
-
59
- tokens.forEach((_, idx) => {
60
- const token = tokens[idx];
61
-
62
- // if the token type does not match, skip
63
- if (token?.type !== 'heading_open') {
64
- return;
65
- }
66
-
67
- // get the level from the tag, h1 -> 1
68
- const headerLevel = Number.parseInt(token.tag.slice(1), 10);
69
-
70
- // if the level should not be extracted, skip
71
- if (!level.includes(headerLevel)) {
72
- return;
73
- }
74
-
75
- // the next token of 'heading_open' contains the heading content
76
- const nextToken = tokens[idx + 1];
77
-
78
- // if the next token does not exist, skip
79
- if (!nextToken) {
80
- return;
81
- }
82
-
83
- const title = resolveTitleFromToken(nextToken, {
84
- shouldAllowHtml,
85
- shouldEscapeText,
86
- });
87
-
88
- // the id of the heading anchor is the slugify result of markdown-it-anchor
89
- // if the id does not exist, slugify the title ourselves
90
- const slug = token.attrGet('id') ?? slugify(title);
91
-
92
- // push the header to tree
93
- push({
94
- level: headerLevel,
95
- title: format?.(title) ?? title,
96
- slug,
97
- children: [],
98
- });
99
- });
100
-
101
- return headers;
102
- };
@@ -1,64 +0,0 @@
1
- import type Token from 'markdown-it/lib/token';
2
- import { htmlEscape } from './html-escape';
3
-
4
- export interface ResolveTitleOptions {
5
- /**
6
- * Should allow inline HTML tags or not.
7
- *
8
- * If the result is going to be used as Vue template, it should allow inline
9
- * HTML tags so that Vue custom components would be kept.
10
- */
11
- shouldAllowHtml: boolean;
12
-
13
- /**
14
- * Should escape the text content or not.
15
- *
16
- * If the result is going to be used in HTML directly, it should be escaped
17
- * so that the text content won't be wrongly treated as HTML tags.
18
- */
19
- shouldEscapeText: boolean;
20
- }
21
-
22
- /**
23
- * Resolve header title from markdown-it token
24
- *
25
- * Typically using the next token of `heading_open` token
26
- */
27
- export const resolveTitleFromToken = (
28
- token: Token,
29
- { shouldAllowHtml, shouldEscapeText }: ResolveTitleOptions,
30
- ): string => {
31
- // children of the token contains the parsed result of the heading title
32
- const children = token.children ?? [];
33
-
34
- // type of tokens to be included in the heading title
35
- const titleTokenTypes = ['text', 'emoji', 'code_inline'];
36
-
37
- // include 'html_inline' or not
38
- if (shouldAllowHtml) {
39
- titleTokenTypes.push('html_inline');
40
- }
41
-
42
- // filter the token type to be included in the title
43
- const titleTokens = children.filter(
44
- (item) =>
45
- titleTokenTypes.includes(item.type) &&
46
- // filter permalink symbol that generated by markdown-it-anchor
47
- !item.meta?.isPermalinkSymbol,
48
- );
49
-
50
- // get title from tokens
51
- return titleTokens
52
- .reduce((result, item) => {
53
- if (shouldEscapeText) {
54
- // escape the content of 'code_inline' and 'text'
55
- if (item.type === 'code_inline' || item.type === 'text') {
56
- return `${result}${htmlEscape(item.content)}`;
57
- }
58
- }
59
-
60
- // keep the content of 'emoji' and 'html_inline'
61
- return `${result}${item.content}`;
62
- }, '')
63
- .trim();
64
- };
package/src/slugify.ts DELETED
@@ -1,25 +0,0 @@
1
- // eslint-disable-next-line no-control-regex
2
- const rControl = /[\u0000-\u001f]/g;
3
- const rSpecial = /[\s~`!@#$%^&*()\-_+=[\]{}|\\;:"'“”‘’<>,.?/]+/g;
4
- const rCombining = /[\u0300-\u036F]/g;
5
-
6
- /**
7
- * Default slugification function
8
- */
9
- export const slugify = (str: string): string =>
10
- str
11
- .normalize('NFKD')
12
- // Remove accents
13
- .replace(rCombining, '')
14
- // Remove control characters
15
- .replace(rControl, '')
16
- // Replace special characters
17
- .replace(rSpecial, '-')
18
- // Remove continuos separators
19
- .replace(/-{2,}/g, '-')
20
- // Remove prefixing and trailing separators
21
- .replace(/^-+|-+$/g, '')
22
- // ensure it doesn't start with a number (#121)
23
- .replace(/^(\d)/, '_$1')
24
- // lowercase
25
- .toLowerCase();
@@ -1,14 +0,0 @@
1
- import { describe, expect, it } from 'vitest';
2
- import { htmlEscape } from '../src';
3
-
4
- const testCases = [['&<>\'"', '&amp;&lt;&gt;&#39;&quot;']];
5
-
6
- describe('shared > html-escape', () => {
7
- describe('should escape special chars', () => {
8
- testCases.forEach(([source, expected]) => {
9
- it(source, () => {
10
- expect(htmlEscape(source)).toBe(expected);
11
- });
12
- });
13
- });
14
- });
@@ -1,21 +0,0 @@
1
- import { describe, expect, it } from 'vitest';
2
- import { htmlUnescape } from '../src';
3
-
4
- const testCases = [
5
- ['&amp;&#38;&lt;&#60;&gt;&#62;&apos;&#39;&quot;&#34;', '&&<<>>\'\'""'],
6
- ['&amp;lt;', '&lt;'],
7
- [
8
- '&amp;lt;script&amp;gt;&amp;lt;/script&amp;gt;',
9
- '&lt;script&gt;&lt;/script&gt;',
10
- ],
11
- ];
12
-
13
- describe('shared > html-unescape', () => {
14
- describe('should unescape special chars', () => {
15
- testCases.forEach(([source, expected]) => {
16
- it(source, () => {
17
- expect(htmlUnescape(source)).toBe(expected);
18
- });
19
- });
20
- });
21
- });
@@ -1,35 +0,0 @@
1
- import { describe, expect, it } from 'vitest';
2
- import { slugify } from '../src';
3
-
4
- const testCases: [string, string][] = [
5
- ['Привет', 'привет'],
6
- ['Лед üäöß', 'лед-uaoß'],
7
- ['hangul 가', 'hangul-가'],
8
- ['ع', 'ع'],
9
- ['džℍΩ', 'dzhω'],
10
- ['カi⁹', 'カi9'],
11
- // ㌀ -> アパート'
12
- ['㌀', decodeURIComponent('%E3%82%A2%E3%83%8F%E3%82%9A%E3%83%BC%E3%83%88')],
13
- ['¼', '_1⁄4'],
14
- ['džℍΩカi⁹¼', 'dzhωカi91⁄4'],
15
- ['Iлtèrnåtïonɑlíƶatï߀ԉ', 'iлternationɑliƶati߀ԉ'],
16
- [
17
- 'Båcòл ípѕùm ðoɭ߀r ѕït aϻèt âùþê aԉᏧ߀üïlɭê ƃëéf culρá fïlèt ϻiǥnòn cuρiᏧatat ut êлim tòлɢùê.',
18
- 'bacoл-ipѕum-ðoɭ߀r-ѕit-aϻet-auþe-aԉꮷ߀uilɭe-ƃeef-culρa-filet-ϻiǥnon-cuρiꮷatat-ut-eлim-toлɢue',
19
- ],
20
- ['ᴎᴑᴅᴇȷʂ', 'ᴎᴑᴅᴇȷʂ'],
21
- ['hambúrguer', 'hamburguer'],
22
- ['hŒllœ', 'hœllœ'],
23
- ['Fußball', 'fußball'],
24
- ['ABCDEFGHIJKLMNOPQRSTUVWXYZé', 'abcdefghijklmnopqrstuvwxyze'],
25
- ];
26
-
27
- describe('shared > slugify', () => {
28
- describe('should slugify string correctly', () => {
29
- testCases.forEach(([source, expected]) => {
30
- it(`${source} => ${expected}`, () => {
31
- expect(slugify(source)).toBe(expected);
32
- });
33
- });
34
- });
35
- });