@brillout/docpress 0.6.7 → 0.6.9

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.
@@ -27,6 +27,6 @@ html:not(.navigation-fullscreen) #navigation-fullscreen-close {
27
27
  }
28
28
 
29
29
  html.navigation-fullscreen #page-content {
30
- /* Make `Ctrl-F` browser search only crawl the navigation menu */
30
+ /* Make `Ctrl-F` browser search only crawl the navigation */
31
31
  visibility: hidden;
32
32
  }
@@ -32,7 +32,7 @@ function toggleNavExpend() {
32
32
 
33
33
  function updateColumnWidth() {
34
34
  const navMinWidth = 299
35
- const navH1Groups = Array.from(document.querySelectorAll('#navigation-content-main .nav-h1-group'))
35
+ const navH1Groups = Array.from(document.querySelectorAll('#navigation-content-main .nav-items-level-1-group'))
36
36
  const numberOfColumnsMax = navH1Groups.length
37
37
 
38
38
  const widthAvailable = getViewportWidth()
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "@brillout/docpress",
3
- "version": "0.6.7",
3
+ "version": "0.6.9",
4
+ "type": "module",
4
5
  "scripts": {
5
6
  "// Build vite.config.ts and +config.ts": "",
6
7
  "build": "rm -rf dist/ && tsc --project tsconfig.config.json",
@@ -14,19 +15,29 @@
14
15
  "release:breaking-change": "release-me minor"
15
16
  },
16
17
  "dependencies": {
17
- "@mdx-js/mdx": "^3.0.1",
18
- "@mdx-js/react": "^3.0.1",
19
- "@mdx-js/rollup": "^3.0.1",
20
- "@shikijs/transformers": "^1.2.0",
18
+ "@brillout/picocolors": "^1.0.10",
19
+ "@mdx-js/mdx": "3.0.1",
20
+ "@mdx-js/react": "3.0.1",
21
+ "@mdx-js/rollup": "3.0.1",
22
+ "@shikijs/transformers": "1.2.0",
21
23
  "@vitejs/plugin-react-swc": "^3.3.2",
22
- "balloon-css": "^1.2.0",
23
- "rehype-pretty-code": "^0.13.0",
24
- "remark-gfm": "^4.0.0",
25
- "shiki": "^1.2.0",
26
- "twemoji": "^13.1.0",
24
+ "balloon-css": "1.2.0",
25
+ "rehype-pretty-code": "0.13.0",
26
+ "remark-gfm": "4.0.0",
27
+ "shiki": "1.2.0",
28
+ "twemoji": "13.1.1",
27
29
  "vike-contributors": "^0.0.9"
28
30
  },
29
- "type": "module",
31
+ "peerDependencies": {
32
+ "@types/node": "*",
33
+ "@types/react": "*",
34
+ "@types/react-dom": "*",
35
+ "react": "^18.0.0",
36
+ "react-dom": "^18.0.0",
37
+ "typescript": "*",
38
+ "vike": "^0.4.162",
39
+ "vite": "^5.2.0"
40
+ },
30
41
  "exports": {
31
42
  "./renderer/onRenderHtml": "./renderer/onRenderHtml.tsx",
32
43
  "./renderer/client": "./renderer/client.ts",
@@ -58,16 +69,6 @@
58
69
  ]
59
70
  }
60
71
  },
61
- "peerDependencies": {
62
- "@types/node": "*",
63
- "@types/react": "*",
64
- "@types/react-dom": "*",
65
- "react": "^18.0.0",
66
- "react-dom": "^18.0.0",
67
- "typescript": "*",
68
- "vike": "^0.4.162",
69
- "vite": "^5.2.0"
70
- },
71
72
  "devDependencies": {
72
73
  "@brillout/release-me": "^0.1.13",
73
74
  "@types/node": "^15.12.1",
@@ -75,12 +76,12 @@
75
76
  "@types/react-dom": "^17.0.6",
76
77
  "react": "^18.2.0",
77
78
  "react-dom": "^18.2.0",
78
- "typescript": "^4.9.4",
79
- "vike": "^0.4.166",
79
+ "typescript": "^5.4.3",
80
+ "vike": "^0.4.167",
80
81
  "vite": "^5.2.2"
81
82
  },
82
- "license": "MIT",
83
83
  "repository": "https://github.com/brillout/docpress",
84
+ "license": "MIT",
84
85
  "publishConfig": {
85
86
  "access": "public"
86
87
  }
@@ -1,20 +1,19 @@
1
- export { markdownHeadingsVitePlugin }
2
- export type { MarkdownHeading }
1
+ export { parsePageSections }
2
+ export type { PageSection }
3
3
 
4
4
  import { assert } from './utils/assert.js'
5
5
  import { determineSectionUrlHash } from './utils/determineSectionUrlHash.js'
6
6
  import os from 'os'
7
7
 
8
- type MarkdownHeading = {
9
- title: string
10
- headingId: string | null
11
- headingLevel: number
12
- titleAddendum?: string
8
+ type PageSection = {
9
+ pageSectionTitle: string
10
+ pageSectionId: string | null
11
+ pageSectionLevel: number
13
12
  }
14
13
 
15
- function markdownHeadingsVitePlugin() {
14
+ function parsePageSections() {
16
15
  return {
17
- name: 'mdx-headings',
16
+ name: '@brillout/docpress:parsePageSections',
18
17
  enforce: 'pre',
19
18
  transform: async (code: string, id: string) => {
20
19
  if (!id.endsWith('+Page.mdx')) {
@@ -27,7 +26,7 @@ function markdownHeadingsVitePlugin() {
27
26
  }
28
27
 
29
28
  function transform(code: string) {
30
- const headings: MarkdownHeading[] = []
29
+ const pageSections: PageSection[] = []
31
30
  let isCodeBlock = false
32
31
  let codeNew = code
33
32
  .split('\n')
@@ -46,52 +45,49 @@ function transform(code: string) {
46
45
  }
47
46
 
48
47
  if (line.startsWith('#')) {
49
- const { headingId, headingLevel, title, headingHtml } = parseMarkdownHeading(line)
50
- headings.push({ headingId, headingLevel, title })
48
+ const { pageSectionId, pageSectionLevel, pageSectionTitle, headingHtml } = parsePageSection(line)
49
+ pageSections.push({ pageSectionId, pageSectionLevel, pageSectionTitle })
51
50
  return headingHtml
52
51
  }
53
52
 
54
53
  return line
55
54
  })
56
55
  .join('\n')
57
- const headingsExportCode = `export const headings = [${headings
58
- .map((heading) => JSON.stringify(heading))
56
+ const exportCode = `export const pageSectionsExport = [${pageSections
57
+ .map((pageSection) => JSON.stringify(pageSection))
59
58
  .join(', ')}];`
60
- codeNew += `\n\n${headingsExportCode}\n`
59
+ codeNew += `\n\n${exportCode}\n`
61
60
  return codeNew
62
61
  }
63
62
 
64
- function parseMarkdownHeading(line: string): MarkdownHeading & { headingHtml: string } {
63
+ function parsePageSection(line: string): PageSection & { headingHtml: string } {
65
64
  const [lineBegin, ...lineWords] = line.split(' ')
66
65
  assert(lineBegin.split('#').join('') === '', { line, lineWords })
67
- const headingLevel = lineBegin.length
66
+ const pageSectionLevel = lineBegin.length
68
67
 
69
68
  const titleMdx = lineWords.join(' ')
70
69
  assert(!titleMdx.startsWith(' '), { line, lineWords })
71
70
  assert(titleMdx, { line, lineWords })
72
71
 
73
- const headingMdx = {
74
- title: titleMdx,
75
- anchor: titleMdx,
76
- }
72
+ let pageSectionTitle = titleMdx
73
+ let anchor = titleMdx
77
74
  {
78
- // Support custom anchor like: `## title{#custom-anchor}`
75
+ // Support custom anchor: `## Some Title{#custom-anchor}`
79
76
  const customAnchor = /(?<={#).*(?=})/g.exec(titleMdx)?.[0]
80
77
  if (customAnchor) {
81
- headingMdx.anchor = customAnchor
82
- headingMdx.title = titleMdx.replace(/{#.*}/g, '')
78
+ anchor = customAnchor
79
+ pageSectionTitle = titleMdx.replace(/{#.*}/g, '')
83
80
  }
84
81
  }
85
- const headingId = determineSectionUrlHash(headingMdx.anchor)
86
- const title = headingMdx.title
82
+ const pageSectionId = determineSectionUrlHash(anchor)
87
83
 
88
- const titleParsed = parseTitle(title)
89
- assert(headingId === null || headingId.length > 0)
90
- const headingAttrId = headingId === null ? '' : ` id="${headingId}"`
91
- const headingHtml = `<h${headingLevel}${headingAttrId}>${titleParsed}</h${headingLevel}>`
84
+ const titleParsed = parseTitle(pageSectionTitle)
85
+ assert(pageSectionId === null || pageSectionId.length > 0)
86
+ const headingId = pageSectionId === null ? '' : ` id="${pageSectionId}"`
87
+ const headingHtml = `<h${pageSectionLevel}${headingId}>${titleParsed}</h${pageSectionLevel}>`
92
88
 
93
- const heading = { headingLevel, title, headingId, headingHtml }
94
- return heading
89
+ const pageSection = { pageSectionLevel, pageSectionTitle, pageSectionId, headingHtml }
90
+ return pageSection
95
91
  }
96
92
 
97
93
  function parseTitle(titleMarkdown: string): string {
package/parseTitle.ts CHANGED
@@ -1,91 +1,8 @@
1
1
  export { parseTitle }
2
- export { getHeadingsWithProcessedTitle }
2
+ export { withEmoji }
3
3
 
4
4
  import React from 'react'
5
- import type { HeadingDefinition, HeadingDetachedDefinition, Heading, HeadingDetached } from './types/Heading'
6
- import { assert, Emoji, EmojiName } from './utils/server'
7
-
8
- function getHeadingsWithProcessedTitle(config: {
9
- headings: HeadingDefinition[]
10
- headingsDetached: HeadingDetachedDefinition[]
11
- }): {
12
- headingsProcessed: Heading[]
13
- headingsDetachedProcessed: HeadingDetached[]
14
- } {
15
- const headingsWithoutBreadcrumb: Omit<Heading, 'headingsBreadcrumb'>[] = config.headings.map(
16
- (heading: HeadingDefinition) => {
17
- const titleProcessed: JSX.Element = parseTitle(heading.title)
18
-
19
- const titleInNav = heading.titleInNav || heading.title
20
- let titleInNavProcessed: JSX.Element
21
- titleInNavProcessed = parseTitle(titleInNav)
22
- if ('titleEmoji' in heading) {
23
- assert(heading.titleEmoji)
24
- titleInNavProcessed = withEmoji(heading.titleEmoji, titleInNavProcessed)
25
- }
26
-
27
- const headingProcessed: Omit<Heading, 'headingsBreadcrumb'> = {
28
- ...heading,
29
- title: titleProcessed,
30
- titleInNav: titleInNavProcessed,
31
- }
32
- return headingProcessed
33
- },
34
- )
35
-
36
- const headingsProcessed: Heading[] = []
37
- headingsWithoutBreadcrumb.forEach((heading) => {
38
- const headingsBreadcrumb = getHeadingsBreadcrumb(heading, headingsProcessed)
39
- headingsProcessed.push({
40
- ...heading,
41
- headingsBreadcrumb,
42
- })
43
- })
44
-
45
- const headingsDetachedProcessed = config.headingsDetached.map((headingsDetached) => {
46
- const { url, title } = headingsDetached
47
- assert(
48
- headingsProcessed.find((heading) => heading.url === url) === undefined,
49
- `remove ${headingsDetached.url} from headingsDetached`,
50
- )
51
- const titleProcessed = typeof title === 'string' ? parseTitle(title) : title
52
- return {
53
- ...headingsDetached,
54
- level: 2 as const,
55
- title: titleProcessed,
56
- titleInNav: titleProcessed,
57
- headingsBreadcrumb: null,
58
- }
59
- })
60
-
61
- assertHeadingsUrl([...headingsProcessed, ...headingsDetachedProcessed])
62
- return { headingsProcessed, headingsDetachedProcessed }
63
- }
64
-
65
- function getHeadingsBreadcrumb(heading: Omit<Heading, 'headingsBreadcrumb'>, headings: Heading[]) {
66
- const headingsBreadcrumb: Heading[] = []
67
- let levelCurrent = heading.level
68
- headings
69
- .slice()
70
- .reverse()
71
- .forEach((parentCandidate) => {
72
- const isParent = parentCandidate.level < levelCurrent
73
- if (isParent) {
74
- levelCurrent = parentCandidate.level
75
- headingsBreadcrumb.push(parentCandidate)
76
- }
77
- })
78
- return headingsBreadcrumb
79
- }
80
-
81
- function assertHeadingsUrl(headings: { url?: null | string }[]) {
82
- headings.forEach((heading) => {
83
- if (heading.url) {
84
- const { url } = heading
85
- assert(url.startsWith('/'))
86
- }
87
- })
88
- }
5
+ import { Emoji, EmojiName } from './utils/server'
89
6
 
90
7
  function parseTitle(title: string): JSX.Element {
91
8
  type Part = { nodeType: 'text' | 'code'; content: string }
@@ -34,11 +34,15 @@ async function onRenderHtml(pageContextOriginal: PageContextOriginal) {
34
34
  <head>
35
35
  <meta charset="UTF-8" />
36
36
  <link rel="icon" href="${pageContextResolved.meta.faviconUrl}" />
37
- <title>${pageContextResolved.meta.title}</title>
37
+ <title>${pageContextResolved.documentTitle}</title>
38
38
  ${descriptionTag}
39
39
  <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no" />
40
40
  ${docSearchCSS}
41
- ${getOpenGraphTags(pageContextOriginal.urlPathname, pageContextResolved.meta)}
41
+ ${getOpenGraphTags(
42
+ pageContextOriginal.urlPathname,
43
+ pageContextResolved.documentTitle,
44
+ pageContextResolved.meta,
45
+ )}
42
46
  </head>
43
47
  <body>
44
48
  <div id="page-view">${dangerouslySkipEscape(pageHtml)}</div>
@@ -49,9 +53,10 @@ async function onRenderHtml(pageContextOriginal: PageContextOriginal) {
49
53
 
50
54
  function getOpenGraphTags(
51
55
  url: string,
52
- meta: { title: string; tagline: string; websiteUrl: string; twitterHandle: string; bannerUrl?: string },
56
+ documentTitle: string,
57
+ meta: { tagline: string; websiteUrl: string; twitterHandle: string; bannerUrl?: string },
53
58
  ) {
54
- const { title, tagline, websiteUrl, twitterHandle, bannerUrl } = meta
59
+ const { tagline, websiteUrl, twitterHandle, bannerUrl } = meta
55
60
 
56
61
  assert(url.startsWith('/'))
57
62
  if (!bannerUrl) return ''
@@ -59,7 +64,7 @@ function getOpenGraphTags(
59
64
  // See view-source:https://vitejs.dev/
60
65
  return escapeInject`
61
66
  <meta property="og:type" content="website">
62
- <meta property="og:title" content="${title}">
67
+ <meta property="og:title" content="${documentTitle}">
63
68
  <meta property="og:image" content="${bannerUrl}">
64
69
  <meta property="og:url" content="${websiteUrl}">
65
70
  <meta property="og:description" content="${tagline}">
package/types/Heading.ts CHANGED
@@ -1,49 +1,53 @@
1
- export { Heading }
2
- export { HeadingDetached }
1
+ export { HeadingResolved }
2
+ export { HeadingDetachedResolved }
3
3
  export { HeadingDetachedDefinition }
4
4
  export { HeadingDefinition }
5
5
 
6
6
  import type { EmojiName } from '../utils/server'
7
7
 
8
- type Heading = Omit<HeadingDefinition, 'title' | 'titleInNav'> & {
8
+ type NavItemLevel =
9
+ | NaItemDefinitionLevel
10
+ | {
11
+ level: 3
12
+ url: null | string
13
+ }
14
+ type NaItemDefinitionLevel =
15
+ | ({ level: 1; titleEmoji: EmojiName } & IsNavCategory)
16
+ | ({ level: 4 } & IsNavCategory)
17
+ | {
18
+ level: 2
19
+ sectionTitles?: string[]
20
+ url: null | string
21
+ }
22
+ type IsNavCategory = {
23
+ url?: undefined
24
+ titleDocument?: undefined
25
+ titleInNav?: undefined
26
+ }
27
+
28
+ type HeadingResolved = HeadingCommon & {
29
+ level: number
9
30
  title: JSX.Element
10
31
  titleInNav: JSX.Element
11
- headingsBreadcrumb: (Heading | HeadingDetached)[]
12
- sectionTitles?: string[]
32
+ linkBreadcrumb: JSX.Element[]
13
33
  }
14
- type HeadingDetached = Omit<Heading, 'level' | 'headingsBreadcrumb'> & {
34
+ type HeadingDetachedResolved = Omit<HeadingResolved, 'level' | 'linkBreadcrumb'> & {
15
35
  level: 2
16
- headingsBreadcrumb: null
36
+ linkBreadcrumb: null
17
37
  }
18
38
  type HeadingDetachedDefinition = {
19
39
  url: string
20
40
  title: string | JSX.Element
21
- sectionTitles?: string[]
22
41
  }
23
- type HeadingDefinition = HeadingBase &
24
- (
25
- | ({ level: 1; titleEmoji: EmojiName } & HeadingAbstract)
26
- | ({ level: 4 } & HeadingAbstract)
27
- | {
28
- level: 2
29
- sectionTitles?: string[]
30
- url: null | string
31
- }
32
- | {
33
- level: 3
34
- url: null | string
35
- }
36
- )
37
- type HeadingBase = {
38
- title: string
39
- level: number
42
+ type HeadingDefinition = HeadingCommon &
43
+ NaItemDefinitionLevel & {
44
+ title: string
45
+ // TODO: rename to titleNav
46
+ titleInNav?: string
47
+ }
48
+ type HeadingCommon = {
40
49
  url?: null | string
50
+ sectionTitles?: string[]
51
+ // TODO: remove? Both Vike and Telefunc set it to the same value than docpress.config.js#projectInfo.projectName
41
52
  titleDocument?: string
42
- titleInNav?: string
43
- // titleSize?: string
44
- }
45
- type HeadingAbstract = {
46
- url?: undefined
47
- titleDocument?: undefined
48
- titleInNav?: undefined
49
53
  }
package/types.d.ts CHANGED
@@ -3,5 +3,5 @@
3
3
  declare module '*.mdx' {
4
4
  const value: () => JSX.Element
5
5
  export default value
6
- export const headings: { level: number; title: string; id: string; titleAddendum?: string }[]
6
+ export const headings: { level: number; title: string; id: string }[]
7
7
  }
package/vite.config.ts CHANGED
@@ -2,7 +2,7 @@ import mdx from '@mdx-js/rollup'
2
2
  import react from '@vitejs/plugin-react-swc'
3
3
  import vike from 'vike/plugin'
4
4
  import { UserConfig } from 'vite'
5
- import { markdownHeadingsVitePlugin } from './markdownHeadingsVitePlugin.js'
5
+ import { parsePageSections } from './parsePageSections.js'
6
6
  import rehypePrettyCode from 'rehype-pretty-code'
7
7
  import remarkGfm from 'remark-gfm'
8
8
  import { transformerNotationDiff } from '@shikijs/transformers'
@@ -15,7 +15,7 @@ const remarkPlugins = [remarkGfm]
15
15
  const config: UserConfig = {
16
16
  root,
17
17
  plugins: [
18
- markdownHeadingsVitePlugin(),
18
+ parsePageSections(),
19
19
  mdx({ rehypePlugins, remarkPlugins }),
20
20
  // @vitejs/plugin-react-swc needs to be added *after* the mdx plugins
21
21
  react(),
@@ -1,13 +0,0 @@
1
- export { markdownHeadingsVitePlugin };
2
- export type { MarkdownHeading };
3
- type MarkdownHeading = {
4
- title: string;
5
- headingId: string | null;
6
- headingLevel: number;
7
- titleAddendum?: string;
8
- };
9
- declare function markdownHeadingsVitePlugin(): {
10
- name: string;
11
- enforce: string;
12
- transform: (code: string, id: string) => Promise<string | undefined>;
13
- };