Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 6 additions & 13 deletions .vitepress/config.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,12 @@
import gitCommitInfo from 'git-commit-info'
import path from 'path'
import { defineConfig } from 'vitepress'
import { pagefindPlugin } from 'vitepress-plugin-pagefind'
import { generateSidebar } from 'vitepress-sidebar'
import { dovecotMdExtend, initDovecotMd } from '../lib/markdown.js'
import { frontmatterIter } from '../lib/utility.js'
import { getExcludes } from '../lib/utility.js'

const base = '/2.4'

// No need to include the "dummy" index files, used to build titles
// for the sidebar, into the final documentation bundles
const excludes = []
await frontmatterIter(function (f, data) {
if (data.exclude) {
excludes.push(path.relative('docs/', f))
}
})

// Need to bootstrap configuration for Dovecot markdown driver (specifically,
// loading all data files to allow existence checking), or else the markdown
// processing will begin before Dovecot link markup is enabled
Expand All @@ -27,8 +17,11 @@ export default defineConfig({
description: "Dovecot CE Documentation",
lang: "en-us",

srcDir: "docs",
srcExclude: excludes,
srcDir: ".",
srcExclude: [ '*.md' ].concat(getExcludes()),
rewrites: {
'docs/:path(.*)': ':path',
},

base: base,
sitemap: {
Expand Down
16 changes: 0 additions & 16 deletions .vitepress/local.js.dist
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,6 @@ export const data_paths = {
// doveadm: '../data/doveadm.js',
}

// A listing of source files (.md) for the documentation.
// Paths are relative to project base.
//
// Supports fast-glob: https://github.com/mrmlnc/fast-glob#pattern-syntax
//
// Default: [ 'docs/**/*.md' ]
export const source_paths = []

// A listing of files to watch to refresh data loaders in dev mode.
// See: https://vitepress.dev/guide/data-loading#data-from-local-files
// Paths are relative to project base.
Expand All @@ -30,14 +22,6 @@ export const source_paths = []
// Default: [ 'docs/**/*.md', 'docs/**/*.inc', 'data/**/*' ]
export const watch_paths = []

// A listing of source path translations.
//
// This is the same format as VitePress' 'rewrite' setting:
// https://vitepress.dev/reference/site-config#rewrites
//
// Default: { 'docs/:path(.*)': ':path' }
export const source_path_translations = {}

// A listing of paths containing man files.
// Paths are relative to project base.
//
Expand Down
1 change: 1 addition & 0 deletions data/updates.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export const updates = {
auth_server_common_secured: '2.4.0',
dcrypt_same_cipher_algo_added: '2.4.0',
dict_idle_timeout_added: '2.4.0',
dict_protocol_v4: '2.4.0',
dict_slow_warn_added: '2.4.0',
doveadm_ex_expired_code: '2.4.0',
doveadm_mailbox_commands_user: '2.4.0',
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ dovecotlinks:
This document describes Dovecot Dict protocol v3.2 which is supported in
Dovecot v2.3.17+.

Dovecot Core v2.4.0 changed the version to v4, but it's otherwise compatible
with v3.2
[[changed,dict_protocol_v4]] Dict protocol version was updated to v4, but
it's otherwise compatible with v3.2.
:::

Dovecot's dict protocol is a line based protocol between the dict client and
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
42 changes: 40 additions & 2 deletions lib/markdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import fg from 'fast-glob'
import deflistPlugin from 'markdown-it-deflist'
import path from 'path'
import { createMarkdownRenderer } from 'vitepress'
import { loadData, loadDovecotLinks, manFiles, markdownExtension, pluginFiles, resolveURL } from './utility.js'
import { frontmatterIter, loadData, manFiles, markdownExtension, pluginFiles, resolveURL } from './utility.js'

let md_conf = null
export async function initDovecotMd(base) {
Expand All @@ -15,8 +15,8 @@ export async function initDovecotMd(base) {
...{
base: base,
doveadm: (await loadData('doveadm')).doveadm,
dovecotlinks: await loadDovecotLinks(base),
events: (await loadData('events')).events,
linkoverrides: (await loadData('links_overrides')).links_overrides,
man: (await manFiles()).flatMap((x) => {
return fg.sync(x).map((y) => {
const str = path.basename(y)
Expand Down Expand Up @@ -202,6 +202,8 @@ function dovecot_markdown(md, opts) {
let url = '#'
env.inner = false

initDovecotLinks()

if (!opts.dovecotlinks[parts[1]]) {
handle_error('Dovecot link missing: ' + parts[1])
return '<a>'
Expand Down Expand Up @@ -388,6 +390,42 @@ function dovecot_markdown(md, opts) {
console.error(msg)
}

function initDovecotLinks() {
if (opts.dovecotlinks) {
return
}

const links = {}
const rewrites = globalThis.VITEPRESS_CONFIG.rewrites.map

frontmatterIter(Object.keys(rewrites), function (f, data) {
if (!data.dovecotlinks) {
return
}

for (const [k, v] of Object.entries(data.dovecotlinks)) {
if (links[k]) {
throw new Error("Duplicate Dovecot Link key: " + k)
}

links[k] = {
url: resolveURL(rewrites[f].substring(0, rewrites[f].lastIndexOf('.')) + '.html', opts.base)
}

if ((typeof v) == 'object') {
links[k].text = v.text
if (v.hash) {
links[k].url += '#' + v.hash
}
} else {
links[k].text = v
}
}
})

opts.dovecotlinks = { ...links, ...opts.linkoverrides }
}

md.inline.ruler.after('emphasis', 'dovecot_brackets', process_brackets)
md.renderer.rules.dovecot_open = dovecot_open
md.renderer.rules.dovecot_body = dovecot_body
Expand Down
87 changes: 22 additions & 65 deletions lib/utility.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@
import fg from 'fast-glob'
import fs from 'fs'
import matter from 'gray-matter'
import { dirname } from 'path';
import { compile, match } from 'path-to-regexp'
import { fileURLToPath } from 'url';
import { dirname } from 'path'
import { fileURLToPath } from 'url'

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
Expand Down Expand Up @@ -67,13 +66,6 @@ export async function loadData(id) {
}
}

export async function sourceFiles() {
/* Check for config override file. */
const lconf = await loadLocalConf()

return lconf?.source_paths ?? [ 'docs/**/*.md' ]
}

export async function watchFiles() {
/* Check for config override file. */
const lconf = await loadLocalConf()
Expand Down Expand Up @@ -104,68 +96,33 @@ export async function pluginFiles() {
[ 'docs/core/plugins/*.md' ]
}

export async function frontmatterIter(callback) {
const sf = await sourceFiles()
const files = sf.flatMap((x) => fg.sync(x))

/* Check for config override file. */
const lconf = await loadLocalConf()
const spt_conf = lconf?.source_path_translations ??
{ 'docs/:path': ':path' }

const spt = Object.entries(spt_conf).map(([from, to]) => ({
toPath: compile(`/${to}`, { validate: false }),
matchUrl: match(from)
}))
export function getExcludes(srcDirs = [ 'docs' ]) {
const excludes = []

for (let f of files) {
const str = fs.readFileSync(f, 'utf8')
const data = matter(str).data

for (const { matchUrl, toPath } of spt) {
const res = matchUrl(f)
if (res) {
f = toPath(res.params).slice(1)
break
frontmatterIter(
srcDirs.flatMap((x) => fg.sync(x + '/**/*.md')),
function (f, data) {
/* Exclude all pages with "exclude" frontmatter present. */
if (data.exclude) {
excludes.push(f)
}
}
)

callback(f, data)
}
return excludes
}

export async function loadDovecotLinks(base) {
const links = {}

await frontmatterIter(function (f, data) {
if (!data.dovecotlinks) {
return
}

for (const [k,v] of Object.entries(data.dovecotlinks)) {
if (links[k]) {
throw new Error("Duplicate Dovecot Link key: " + k)
}

links[k] = {
url: resolveURL(f.substring(0, f.lastIndexOf('.')) + '.html', base)
}

if ((typeof v) == 'object') {
links[k].text = v.text
if (v.hash) {
links[k].url += '#' + v.hash
}
} else {
links[k].text = v
}
export function frontmatterIter(files, callback) {
for (let f of files) {
try {
const str = fs.readFileSync(f, 'utf8')
callback(f, matter(str).data)
} catch (err) {
/* Ignore file not exist errors, since they can occur for
* dynamically generated paths (e.g. Release Notes). */
if (err.code !== 'ENOENT') throw err
}
})

const data = await loadData('links_overrides')

/* Merge the two lists together. */
return { ...links, ...data.links_overrides }
}
}

export function resolveURL(url, base) {
Expand Down
10 changes: 0 additions & 10 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
"markdown-it-deflist": "^3.0.0",
"markdown-it-mathjax3": "^4.3.2",
"pagefind": "^1.1.1",
"path-to-regexp": "^8.1.0",
"pdc": "^0.2.3",
"remark-definition-list": "^2.0.0",
"remark-man": "^9.0.0",
Expand Down
Loading