@@ -5,7 +5,56 @@ import path from 'path'
55import { createMarkdownRenderer } from 'vitepress'
66import { dovecotSetting , frontmatterIter , loadData } from './utility.js'
77
8- export function dovecotMdExtend ( md ) {
8+ let md_conf = false
9+ export async function dovecotMdInit ( ) {
10+ if ( md_conf ) {
11+ return md_conf
12+ }
13+
14+ md_conf = {
15+ doveadm : ( await loadData ( 'doveadm' ) ) . doveadm ,
16+ events : ( await loadData ( 'events' ) ) . events ,
17+ links : await ( async ( ) => {
18+ const links = { }
19+ const rewrites = globalThis . VITEPRESS_CONFIG . rewrites . map
20+
21+ frontmatterIter ( Object . keys ( rewrites ) , function ( f , data ) {
22+ if ( ! data . dovecotlinks ) {
23+ return
24+ }
25+
26+ for ( const [ k , v ] of Object . entries ( data . dovecotlinks ) ) {
27+ if ( links [ k ] ) {
28+ throw new Error ( "Duplicate Dovecot Link key: " + k )
29+ }
30+
31+ links [ k ] = {
32+ url : resolveURL ( rewrites [ f ] . substring ( 0 , rewrites [ f ] . lastIndexOf ( '.' ) ) + '.html' )
33+ }
34+
35+ if ( ( typeof v ) == 'object' ) {
36+ links [ k ] . text = v . text
37+ if ( v . hash ) {
38+ links [ k ] . url += '#' + v . hash
39+ }
40+ } else {
41+ links [ k ] . text = v
42+ }
43+ }
44+ } )
45+
46+ return {
47+ ...links , ...( ( await loadData ( 'links_overrides' ) ) . links_overrides )
48+ }
49+ } ) ( ) ,
50+ settings : ( await loadData ( 'settings' ) ) . settings ,
51+ updates : ( await loadData ( 'updates' ) ) . updates
52+ }
53+
54+ return md_conf
55+ }
56+
57+ export async function dovecotMdExtend ( md ) {
958 md . use ( containerPlugin , 'todo' , {
1059 render : function ( tokens , idx ) {
1160 if ( tokens [ idx ] . nesting === 1 ) {
@@ -16,7 +65,7 @@ export function dovecotMdExtend(md) {
1665 }
1766 } )
1867 md . use ( deflistPlugin )
19- md . use ( dovecot_markdown )
68+ md . use ( dovecot_markdown , await dovecotMdInit ( ) )
2069
2170 return md
2271}
@@ -26,7 +75,7 @@ export async function getVitepressMd() {
2675 if ( vitepress_md === null ) {
2776 const config = globalThis . VITEPRESS_CONFIG
2877
29- vitepress_md = dovecotMdExtend ( await createMarkdownRenderer (
78+ vitepress_md = await dovecotMdExtend ( await createMarkdownRenderer (
3079 config . srcDir ,
3180 config . markdown ,
3281 config . site . base ,
@@ -40,7 +89,7 @@ export async function getVitepressMd() {
4089/* This is a dovecot markdown extension to support the "[[...]]" syntax.
4190 * Much of this is copied from existing markdown-it plugins. See, e.g.,
4291 * https://github.com/markdown-it/markdown-it-sub/blob/master/index.mjs */
43- function dovecot_markdown ( md ) {
92+ function dovecot_markdown ( md , opts ) {
4493 function process_brackets ( state , silent ) {
4594 const max = state . posMax
4695 const start = state . pos
@@ -130,8 +179,6 @@ function dovecot_markdown(md) {
130179 let page = mode
131180 switch ( mode ) {
132181 case 'doveadm' :
133- initDoveadm ( )
134-
135182 if ( ! opts . doveadm [ env . inner ] ) {
136183 if ( ! Object . values ( opts . doveadm ) . find ( ( x ) => ( x . man == 'doveadm-' + env . inner ) ) ) {
137184 handle_error ( 'doveadm link missing: ' + env . inner )
@@ -141,8 +188,6 @@ function dovecot_markdown(md) {
141188 break
142189
143190 case 'event' :
144- initEvents ( )
145-
146191 if ( ! opts . events [ env . inner ] ) {
147192 handle_error ( 'event link missing: ' + env . inner )
148193 return '<code><a>'
@@ -152,8 +197,6 @@ function dovecot_markdown(md) {
152197
153198 case 'setting' :
154199 case 'setting_text' :
155- initSettings ( )
156-
157200 /* Settings names can have brackets, so we need to unescape
158201 * input for purposes of searching settings keys. */
159202 const search_str = env . inner . replaceAll ( '>' , '>' )
@@ -175,14 +218,12 @@ function dovecot_markdown(md) {
175218 let url = '#'
176219 env . inner = false
177220
178- initDovecotLinks ( )
179-
180- if ( ! opts . dovecotlinks [ parts [ 1 ] ] ) {
221+ if ( ! opts . links [ parts [ 1 ] ] ) {
181222 handle_error ( 'Dovecot link missing: ' + parts [ 1 ] )
182223 return '<a>'
183224 }
184225
185- const d = opts . dovecotlinks [ parts [ 1 ] ]
226+ const d = opts . links [ parts [ 1 ] ]
186227 env . inner = parts [ 2 ] ? parts [ 2 ] : ( d . text ? d . text : false )
187228
188229 return '<a href="' + d . url + '">'
@@ -287,8 +328,6 @@ function dovecot_markdown(md) {
287328 case 'changed' :
288329 case 'deprecated' :
289330 case 'removed' :
290- initUpdates ( )
291-
292331 if ( ! opts . updates [ env . args ] ) {
293332 handle_error ( 'Missing updates entry for: ' + env . args )
294333 return env . args
@@ -369,56 +408,6 @@ function dovecot_markdown(md) {
369408 console . error ( msg )
370409 }
371410
372- function initDoveadm ( ) {
373- if ( ! opts . doveadm ) {
374- opts . doveadm = loadData ( 'doveadm' ) . doveadm
375- }
376- }
377-
378- function initDovecotLinks ( ) {
379- if ( opts . dovecotlinks ) {
380- return
381- }
382-
383- const links = { }
384- const rewrites = globalThis . VITEPRESS_CONFIG . rewrites . map
385-
386- frontmatterIter ( Object . keys ( rewrites ) , function ( f , data ) {
387- if ( ! data . dovecotlinks ) {
388- return
389- }
390-
391- for ( const [ k , v ] of Object . entries ( data . dovecotlinks ) ) {
392- if ( links [ k ] ) {
393- throw new Error ( "Duplicate Dovecot Link key: " + k )
394- }
395-
396- links [ k ] = {
397- url : resolveURL ( rewrites [ f ] . substring ( 0 , rewrites [ f ] . lastIndexOf ( '.' ) ) + '.html' )
398- }
399-
400- if ( ( typeof v ) == 'object' ) {
401- links [ k ] . text = v . text
402- if ( v . hash ) {
403- links [ k ] . url += '#' + v . hash
404- }
405- } else {
406- links [ k ] . text = v
407- }
408- }
409- } )
410-
411- opts . dovecotlinks = {
412- ...links , ...( loadData ( 'links_overrides' ) . links_overrides )
413- }
414- }
415-
416- function initEvents ( ) {
417- if ( ! opts . events ) {
418- opts . events = loadData ( 'events' ) . events
419- }
420- }
421-
422411 function initManFiles ( ) {
423412 if ( ! opts . man ) {
424413 opts . man = dovecotSetting ( 'man_paths' ) . flatMap ( ( x ) => {
@@ -444,37 +433,17 @@ function dovecot_markdown(md) {
444433 }
445434 }
446435
447- function initSettings ( ) {
448- if ( ! opts . settings ) {
449- opts . settings = loadData ( 'settings' ) . settings
450- }
451- }
452-
453- function initUpdates ( ) {
454- if ( ! opts . updates ) {
455- opts . updates = loadData ( 'updates' ) . updates
456- }
457- }
458-
459- function resolveURL ( url ) {
460- if ( ! ( 'url_rewrite' in opts ) ) {
461- opts . url_rewrite = dovecotSetting ( 'url_rewrite' )
462- }
463-
464- const new_url =
465- ( opts . base . endsWith ( '/' ) ? opts . base . slice ( 0 , - 1 ) : opts . base ) +
466- '/' + url
467- return ( opts . url_rewrite ) ? opts . url_rewrite ( new_url ) : new_url
468- }
469-
470- const opts = {
471- base : globalThis . VITEPRESS_CONFIG . site . base
472- }
473-
474436 md . inline . ruler . after ( 'emphasis' , 'dovecot_brackets' , process_brackets )
475437 md . renderer . rules . dovecot_open = dovecot_open
476438 md . renderer . rules . dovecot_body = dovecot_body
477439 md . renderer . rules . dovecot_close = dovecot_close
440+ }
478441
479- opts . resolveURL = resolveURL
442+ export function resolveURL ( url ) {
443+ const base = globalThis . VITEPRESS_CONFIG . site . base
444+ const url_rewrite = dovecotSetting ( 'url_rewrite' )
445+ const new_url =
446+ ( base . endsWith ( '/' ) ? base . slice ( 0 , - 1 ) : base ) +
447+ '/' + url
448+ return ( url_rewrite ) ? url_rewrite ( new_url ) : new_url
480449}
0 commit comments