2023-04-23 23:33:15 +02:00
import { readFileSync , readFile , mkdirpSync , writeFileSync , remove , copy , pathExistsSync , pathExists } from 'fs-extra' ;
2021-12-19 09:53:19 +02:00
import { rootDir } from '../tool-utils' ;
2021-07-10 12:16:13 +02:00
import { pressCarouselItems } from './utils/pressCarousel' ;
import { getMarkdownIt , loadMustachePartials , markdownToPageHtml , renderMustache } from './utils/render' ;
2023-04-23 23:33:15 +02:00
import { AssetUrls , Env , Locale , Partials , PlanPageParams , TemplateParams } from './utils/types' ;
2022-04-07 16:35:15 +02:00
import { createFeatureTableMd , getPlans , loadStripeConfig } from '@joplin/lib/utils/joplinCloud' ;
2022-06-03 13:31:42 +02:00
import { stripOffFrontMatter } from './utils/frontMatter' ;
2021-12-19 09:53:19 +02:00
import { dirname , basename } from 'path' ;
2022-02-24 21:35:28 +02:00
import { readmeFileTitle , replaceGitHubByWebsiteLinks } from './utils/parser' ;
2023-04-23 23:33:15 +02:00
import { extractOpenGraphTags , OpenGraphTags } from './utils/openGraph' ;
2022-04-09 13:32:19 +02:00
import { readCredentialFileJson } from '@joplin/lib/utils/credentialFiles' ;
2022-06-03 13:31:42 +02:00
import { getNewsDateString } from './utils/news' ;
2023-10-30 13:32:14 +02:00
import { Translations } from '../utils/translation' ;
2023-04-23 23:33:15 +02:00
import { setLocale } from '@joplin/lib/locale' ;
2022-11-28 18:16:32 +02:00
import applyTranslations from './utils/applyTranslations' ;
2023-03-21 19:29:22 +02:00
import { loadSponsors } from '../utils/loadSponsors' ;
2023-04-23 23:33:15 +02:00
import convertLinksToLocale from './utils/convertLinksToLocale' ;
2023-09-22 16:35:02 +02:00
import { copyFile } from 'fs/promises' ;
2021-12-17 19:37:01 +02:00
2022-04-09 13:32:19 +02:00
interface BuildConfig {
env : Env ;
}
const buildConfig = readCredentialFileJson < BuildConfig > ( 'website-build.json' , {
env : Env.Prod ,
} ) ;
2023-04-23 23:33:15 +02:00
const enGbLocale : Locale = {
htmlTranslations : { } ,
lang : 'en-gb' ,
pathPrefix : '' ,
} ;
2021-07-10 12:16:13 +02:00
const glob = require ( 'glob' ) ;
const path = require ( 'path' ) ;
2022-11-13 13:37:05 +02:00
const md5File = require ( 'md5-file' ) ;
2021-12-19 09:53:19 +02:00
const docDir = ` ${ dirname ( dirname ( dirname ( dirname ( __dirname ) ) ) ) } /joplin-website/docs ` ;
2023-10-30 13:32:14 +02:00
if ( ! pathExistsSync ( docDir ) ) throw new Error ( ` "docs" directory does not exist: ${ docDir } ` ) ;
2021-12-19 09:53:19 +02:00
2021-07-10 12:16:13 +02:00
const websiteAssetDir = ` ${ rootDir } /Assets/WebsiteAssets ` ;
2021-12-21 20:53:36 +02:00
const readmeDir = ` ${ rootDir } /readme ` ;
2021-12-17 19:37:01 +02:00
const mainTemplateHtml = readFileSync ( ` ${ websiteAssetDir } /templates/main-new.mustache ` , 'utf8' ) ;
const frontTemplateHtml = readFileSync ( ` ${ websiteAssetDir } /templates/front.mustache ` , 'utf8' ) ;
const plansTemplateHtml = readFileSync ( ` ${ websiteAssetDir } /templates/plans.mustache ` , 'utf8' ) ;
2023-07-05 16:18:29 +02:00
const brandTemplateHtml = readFileSync ( ` ${ websiteAssetDir } /templates/brand.mustache ` , 'utf8' ) ;
2022-04-09 13:32:19 +02:00
const stripeConfig = loadStripeConfig ( buildConfig . env , ` ${ rootDir } /packages/server/stripeConfig.json ` ) ;
2021-07-10 12:16:13 +02:00
const partialDir = ` ${ websiteAssetDir } /templates/partials ` ;
2021-12-18 17:45:59 +02:00
const discussLink = 'https://discourse.joplinapp.org/c/news/9' ;
2023-10-30 13:32:14 +02:00
// let tocMd_: string = null;
// const tocHtml_: Record<string, string> = {};
// const tocRegex_ = /<!-- TOC -->([^]*)<!-- TOC -->/;
// function tocMd() {
// if (tocMd_) return tocMd_;
// const md = readFileSync(`${rootDir}/README.md`, 'utf8');
// const toc = md.match(tocRegex_);
// tocMd_ = toc[1];
// return tocMd_;
// }
2021-07-10 12:16:13 +02:00
const donateLinksRegex_ = /<!-- DONATELINKS -->([^]*)<!-- DONATELINKS -->/ ;
async function getDonateLinks() {
2021-12-17 19:37:01 +02:00
const md = await readFile ( ` ${ rootDir } /README.md ` , 'utf8' ) ;
2021-07-10 12:16:13 +02:00
const matches = md . match ( donateLinksRegex_ ) ;
if ( ! matches ) throw new Error ( 'Cannot fetch donate links' ) ;
return ` <div class="donate-links"> \ n \ n ${ matches [ 1 ] . trim ( ) } \ n \ n</div> ` ;
}
2023-10-30 13:32:14 +02:00
// function tocHtml(locale: Locale) {
// if (tocHtml_[locale.lang]) return tocHtml_[locale.lang];
// const markdownIt = getMarkdownIt();
// let md = tocMd();
// md = md.replace(/# Table of contents/, '');
// md = replaceGitHubByWebsiteLinks(md);
// md = convertLinksToLocale(md, locale);
// let output = markdownIt.render(md);
// output = `<div>${output}</div>`;
// tocHtml_[locale.lang] = output;
// return output;
// }
2021-07-10 12:16:13 +02:00
2021-10-25 17:49:21 +02:00
const baseUrl = '' ;
const cssBasePath = ` ${ websiteAssetDir } /css ` ;
const cssBaseUrl = ` ${ baseUrl } /css ` ;
const jsBasePath = ` ${ websiteAssetDir } /js ` ;
const jsBaseUrl = ` ${ baseUrl } /js ` ;
2021-07-10 12:16:13 +02:00
2021-10-25 17:49:21 +02:00
async function getAssetUrls ( ) : Promise < AssetUrls > {
2024-04-05 13:16:49 +02:00
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
2023-09-22 16:35:02 +02:00
const scriptsToImport : any [ ] = [
// {
// id: 'tippy',
// sourcePath: rootDir + '/packages/tools/node_modules/tippy.js/dist/tippy-bundle.umd.min.js',
// md5: '',
// filename: '',
// },
// {
// id: 'popper',
// sourcePath: rootDir + '/packages/tools/node_modules/@popperjs/core/dist/umd/popper.min.js',
// md5: '',
// filename: '',
// },
] ;
for ( const s of scriptsToImport ) {
const filename = basename ( s . sourcePath ) ;
const sourceMd5 = await md5File ( s . sourcePath ) ;
const targetPath = ` ${ websiteAssetDir } /js/ ${ filename } ` ;
const targetMd5 = await md5File ( targetPath ) ;
s . md5 = sourceMd5 ;
s . filename = filename ;
// We check the MD5, otherwise it makes nodemon goes into an infinite building loop
if ( sourceMd5 !== targetMd5 ) await copyFile ( s . sourcePath , targetPath ) ;
}
const importedJs : Record < string , string > = { } ;
for ( const s of scriptsToImport ) {
importedJs [ s . id ] = ` ${ jsBaseUrl } / ${ s . filename } ?h= ${ await md5File ( ` ${ websiteAssetDir } /js/ ${ s . filename } ` ) } ` ;
}
2021-10-25 17:49:21 +02:00
return {
css : {
fontawesome : ` ${ cssBaseUrl } /fontawesome-all.min.css?h= ${ await md5File ( ` ${ cssBasePath } /fontawesome-all.min.css ` ) } ` ,
site : ` ${ cssBaseUrl } /site.css?h= ${ await md5File ( ` ${ cssBasePath } /site.css ` ) } ` ,
} ,
js : {
script : ` ${ jsBaseUrl } /script.js?h= ${ await md5File ( ` ${ jsBasePath } /script.js ` ) } ` ,
2023-09-22 16:35:02 +02:00
. . . importedJs ,
2021-10-25 17:49:21 +02:00
} ,
} ;
}
2023-04-23 23:33:15 +02:00
function defaultTemplateParams ( assetUrls : AssetUrls , locale : Locale = null ) : TemplateParams {
if ( ! locale ) locale = enGbLocale ;
2021-07-10 12:16:13 +02:00
return {
2022-04-09 13:32:19 +02:00
env : buildConfig.env ,
2021-10-25 17:49:21 +02:00
baseUrl ,
2021-07-10 12:16:13 +02:00
imageBaseUrl : ` ${ baseUrl } /images ` ,
2021-10-25 17:49:21 +02:00
cssBaseUrl ,
jsBaseUrl ,
2023-10-30 13:32:14 +02:00
// tocHtml: tocHtml(locale),
2021-07-10 12:16:13 +02:00
yyyy : ( new Date ( ) ) . getFullYear ( ) . toString ( ) ,
templateHtml : mainTemplateHtml ,
forumUrl : 'https://discourse.joplinapp.org/' ,
showToc : true ,
showImproveThisDoc : true ,
2021-07-19 11:58:21 +02:00
showJoplinCloudLinks : true ,
2021-07-10 12:16:13 +02:00
navbar : {
isFrontPage : false ,
} ,
2021-10-25 17:49:21 +02:00
assetUrls ,
2022-02-24 21:35:28 +02:00
openGraph : null ,
2023-04-23 23:33:15 +02:00
locale ,
2021-07-10 12:16:13 +02:00
} ;
}
function renderPageToHtml ( md : string , targetPath : string , templateParams : TemplateParams ) {
2023-05-08 13:59:27 +02:00
if ( templateParams . isNews ) templateParams . locale = enGbLocale ;
2021-07-10 12:16:13 +02:00
// Remove the header because it's going to be added back as HTML
md = md . replace ( /# Joplin\n/ , '' ) ;
templateParams = {
2023-04-23 23:33:15 +02:00
. . . defaultTemplateParams ( templateParams . assetUrls , templateParams . locale ) ,
2021-07-10 12:16:13 +02:00
. . . templateParams ,
} ;
2022-03-03 16:06:37 +02:00
templateParams . showBottomLinks = templateParams . showImproveThisDoc ;
2021-12-18 17:45:59 +02:00
2021-07-10 12:16:13 +02:00
const title = [ ] ;
if ( ! templateParams . title ) {
title . push ( 'Joplin - an open source note taking and to-do application with synchronisation capabilities' ) ;
} else {
title . push ( templateParams . title ) ;
title . push ( 'Joplin' ) ;
}
md = replaceGitHubByWebsiteLinks ( md ) ;
2023-04-23 23:33:15 +02:00
md = convertLinksToLocale ( md , templateParams . locale ) ;
2021-07-10 12:16:13 +02:00
if ( templateParams . donateLinksMd ) {
md = ` ${ templateParams . donateLinksMd } \ n \ n ${ md } ` ;
}
templateParams . pageTitle = title . join ( ' | ' ) ;
const html = templateParams . contentHtml ? renderMustache ( templateParams . contentHtml , templateParams ) : markdownToPageHtml ( md , templateParams ) ;
const folderPath = dirname ( targetPath ) ;
2021-12-17 19:37:01 +02:00
mkdirpSync ( folderPath ) ;
2021-07-10 12:16:13 +02:00
2021-12-17 19:37:01 +02:00
writeFileSync ( targetPath , html ) ;
2021-07-10 12:16:13 +02:00
}
function renderFileToHtml ( sourcePath : string , targetPath : string , templateParams : TemplateParams ) {
2022-11-15 18:00:06 +02:00
try {
let md = readFileSync ( sourcePath , 'utf8' ) ;
if ( templateParams . isNews ) {
md = processNewsMarkdown ( md , sourcePath ) ;
}
md = stripOffFrontMatter ( md ) . doc ;
return renderPageToHtml ( md , targetPath , templateParams ) ;
} catch ( error ) {
error . message = ` Could not render file: ${ sourcePath } : ${ error . message } ` ;
throw error ;
2022-03-03 16:06:37 +02:00
}
2021-07-10 12:16:13 +02:00
}
2023-10-30 13:32:14 +02:00
// function makeHomePageMd(readmePath: string) {
// let md = readFileSync(readmePath, 'utf8');
// md = md.replace(tocRegex_, '');
2021-07-10 12:16:13 +02:00
2023-10-30 13:32:14 +02:00
// // HACK: GitHub needs the \| or the inline code won't be displayed correctly inside the table,
// // while MarkdownIt doesn't and will in fact display the \. So we remove it here.
// md = md.replace(/\\\| bash/g, '| bash');
2021-07-10 12:16:13 +02:00
2023-10-30 13:32:14 +02:00
// // We strip-off the donate links because they are added back (with proper
// // classes and CSS).
// md = md.replace(donateLinksRegex_, '');
2022-01-09 19:49:37 +02:00
2023-10-30 13:32:14 +02:00
// return md;
// }
2021-07-10 12:16:13 +02:00
2022-03-03 16:06:37 +02:00
const processNewsMarkdown = ( md : string , mdFilePath : string ) : string = > {
const info = stripOffFrontMatter ( md ) ;
md = info . doc . trim ( ) ;
2023-10-30 13:32:14 +02:00
const dateString = getNewsDateString ( info . header , mdFilePath ) ;
2022-03-03 16:06:37 +02:00
md = md . replace ( /^# (.*)/ , ` # [ $ 1](https://github.com/laurent22/joplin/blob/dev/readme/news/ ${ path . basename ( mdFilePath ) } ) \ n \ n*Published on ** ${ dateString } *** \ n \ n ` ) ;
md += ` \ n \ n* * * \ n \ n[<i class="fab fa-discourse"></i> Discuss on the forum]( ${ discussLink } ) ` ;
return md ;
} ;
2023-10-30 13:32:14 +02:00
// const makeNewsFrontPage = async (sourceFilePaths: string[], targetFilePath: string, templateParams: TemplateParams) => {
// const maxNewsPerPage = 20;
2021-12-17 19:37:01 +02:00
2023-10-30 13:32:14 +02:00
// const frontPageMd: string[] = [];
2021-12-17 19:37:01 +02:00
2023-10-30 13:32:14 +02:00
// for (const mdFilePath of sourceFilePaths) {
// let md = await readFile(mdFilePath, 'utf8');
// md = processNewsMarkdown(md, mdFilePath);
// frontPageMd.push(md);
// if (frontPageMd.length >= maxNewsPerPage) break;
// }
2021-12-17 19:37:01 +02:00
2023-10-30 13:32:14 +02:00
// renderPageToHtml(frontPageMd.join('\n\n* * *\n\n'), targetFilePath, templateParams);
// };
2021-12-17 19:37:01 +02:00
const isNewsFile = ( filePath : string ) : boolean = > {
return filePath . includes ( 'readme/news/' ) ;
} ;
2022-11-28 18:16:32 +02:00
const translatePartials = ( partials : Partials , languageCode : string , translations : Translations ) : Partials = > {
const output : Partials = { } ;
for ( const [ key , value ] of Object . entries ( partials ) ) {
output [ key ] = applyTranslations ( value , languageCode , translations ) ;
}
return output ;
} ;
const updatePageLanguage = ( html : string , lang : string ) : string = > {
return html . replace ( '<html lang="en-gb">' , ` <html lang=" ${ lang } "> ` ) ;
} ;
2023-04-23 23:33:15 +02:00
// TODO: Add function that process links and add prefix.
2021-07-10 12:16:13 +02:00
async function main() {
2023-04-23 23:33:15 +02:00
const supportedLocales : Record < string , Locale > = {
'en_GB' : enGbLocale ,
2023-10-30 13:32:14 +02:00
// 'zh_CN': {
// htmlTranslations: parseTranslations(await parsePoFile(`${websiteAssetDir}/locales/zh_CN.po`)),
// lang: 'zh-cn',
// pathPrefix: 'cn',
// },
// 'fr_FR': {
// htmlTranslations: {},
// lang: 'fr-fr',
// pathPrefix: 'fr',
// },
2022-11-28 18:16:32 +02:00
} ;
2023-07-29 17:52:24 +02:00
// delete supportedLocales['zh_CN'];
// delete supportedLocales['fr_FR'];
2022-11-28 18:16:32 +02:00
setLocale ( 'en_GB' ) ;
2023-10-30 13:32:14 +02:00
await remove ( docDir ) ;
const docBuilderDir = ` ${ rootDir } /packages/doc-builder ` ;
await copy ( ` ${ docBuilderDir } /build ` , docDir ) ;
await copy ( websiteAssetDir , docDir ) ;
2021-07-10 12:16:13 +02:00
2023-08-10 14:14:03 +02:00
const sponsors = process . env . SKIP_SPONSOR_PROCESSING ? { github : [ ] , orgs : [ ] } : await loadSponsors ( ) ;
2021-07-10 12:16:13 +02:00
const partials = await loadMustachePartials ( partialDir ) ;
2021-10-25 17:49:21 +02:00
const assetUrls = await getAssetUrls ( ) ;
2021-07-10 12:16:13 +02:00
2022-01-09 19:49:37 +02:00
const donateLinksMd = await getDonateLinks ( ) ;
2021-07-10 12:16:13 +02:00
2023-04-23 23:33:15 +02:00
for ( const [ localeName , locale ] of Object . entries ( supportedLocales ) ) {
setLocale ( localeName ) ;
2021-07-10 12:16:13 +02:00
2023-04-23 23:33:15 +02:00
const pathPrefix = localeName !== 'en_GB' ? ` / ${ locale . pathPrefix } ` : '' ;
2021-07-10 12:16:13 +02:00
2023-04-23 23:33:15 +02:00
// =============================================================
// HELP PAGE
// =============================================================
2021-07-10 12:16:13 +02:00
2023-10-30 13:32:14 +02:00
// let readmePath = `${rootDir}/README.md`;
// let sourceMarkdownFile = 'README.md';
// let targetDocDir = docDir;
// if (localeName !== 'en_GB') {
// const possibleSource = `${rootDir}/readme/_i18n/${localeName}/README.md`;
// if (await pathExists(possibleSource)) {
// sourceMarkdownFile = possibleSource;
// readmePath = possibleSource;
// } else {
// console.warn(`Cannot find source file: ${possibleSource}`);
// }
// targetDocDir = `${docDir}/${locale.pathPrefix}`;
// }
// const readmeMd = makeHomePageMd(readmePath);
// renderPageToHtml(readmeMd, `${targetDocDir}/help/index.html`, {
// sourceMarkdownFile,
// donateLinksMd,
// partials,
// sponsors,
// assetUrls,
// openGraph: {
// title: 'Joplin documentation',
// description: '',
// url: 'https://joplinapp.org/help/',
// },
// locale,
// });
2022-11-28 18:16:32 +02:00
2023-04-23 23:33:15 +02:00
// =============================================================
// FRONT PAGE
// =============================================================
2022-11-28 18:16:32 +02:00
let templateHtml = updatePageLanguage ( applyTranslations ( frontTemplateHtml , localeName , locale . htmlTranslations ) , locale . lang ) ;
if ( localeName === 'zh_CN' ) templateHtml = templateHtml . replace ( /\/plans/g , '/cn/plans' ) ;
renderPageToHtml ( '' , ` ${ docDir } ${ pathPrefix } /index.html ` , {
templateHtml ,
partials : translatePartials ( partials , localeName , locale . htmlTranslations ) ,
pressCarouselRegular : {
id : 'carouselRegular' ,
items : pressCarouselItems ( ) ,
} ,
pressCarouselMobile : {
id : 'carouselMobile' ,
items : pressCarouselItems ( ) ,
} ,
sponsors ,
navbar : {
isFrontPage : true ,
} ,
showToc : false ,
assetUrls ,
openGraph : {
title : 'Joplin website' ,
description : 'Joplin, the open source note-taking application' ,
url : 'https://joplinapp.org' ,
} ,
} ) ;
2021-07-10 12:16:13 +02:00
2023-04-23 23:33:15 +02:00
// =============================================================
// PLANS PAGE
// =============================================================
2021-07-10 12:16:13 +02:00
2022-11-28 18:16:32 +02:00
const planPageFaqMd = await readFile ( ` ${ readmeDir } /faq_joplin_cloud.md ` , 'utf8' ) ;
const planPageFaqHtml = getMarkdownIt ( ) . render ( planPageFaqMd , { } ) ;
2021-07-10 12:16:13 +02:00
2022-11-28 18:16:32 +02:00
const planPageParams : PlanPageParams = {
2023-04-23 23:33:15 +02:00
. . . defaultTemplateParams ( assetUrls , locale ) ,
2022-11-28 18:16:32 +02:00
partials : translatePartials ( partials , localeName , locale . htmlTranslations ) ,
templateHtml : applyTranslations ( plansTemplateHtml , localeName , locale . htmlTranslations ) ,
plans : getPlans ( stripeConfig ) ,
faqHtml : planPageFaqHtml ,
featureListHtml : getMarkdownIt ( ) . render ( createFeatureTableMd ( ) , { } ) ,
stripeConfig ,
} ;
2021-07-10 12:16:13 +02:00
2022-11-28 18:16:32 +02:00
const planPageContentHtml = renderMustache ( '' , planPageParams ) ;
const templateParams = {
2023-04-23 23:33:15 +02:00
. . . defaultTemplateParams ( assetUrls , locale ) ,
2022-11-28 18:16:32 +02:00
pageName : 'plans' ,
partials ,
showToc : false ,
showImproveThisDoc : false ,
contentHtml : planPageContentHtml ,
title : 'Joplin Cloud Plans' ,
} ;
templateParams . templateHtml = updatePageLanguage ( templateParams . templateHtml , locale . lang ) ;
renderPageToHtml ( '' , ` ${ docDir } ${ pathPrefix } /plans/index.html ` , templateParams ) ;
2023-07-05 16:18:29 +02:00
// =============================================================
// BRAND GUIDELINES PAGE
// =============================================================
{
const brandAssetUrls : AssetUrls = {
css : {
. . . assetUrls . css ,
brand : ` ${ cssBaseUrl } /brand.css?h= ${ await md5File ( ` ${ cssBasePath } /brand.css ` ) } ` ,
} ,
js : {
. . . assetUrls . js ,
} ,
} ;
const brandPageParams : TemplateParams = {
. . . defaultTemplateParams ( brandAssetUrls , locale ) ,
partials : translatePartials ( partials , localeName , locale . htmlTranslations ) ,
templateHtml : applyTranslations ( brandTemplateHtml , localeName , locale . htmlTranslations ) ,
} ;
const brandPageContentHtml = renderMustache ( '' , brandPageParams ) ;
const templateParams = {
. . . defaultTemplateParams ( brandAssetUrls , locale ) ,
pageName : 'plans' ,
partials ,
showToc : false ,
showImproveThisDoc : false ,
contentHtml : brandPageContentHtml ,
title : 'Joplin Brand Guidelines' ,
} ;
templateParams . templateHtml = updatePageLanguage ( templateParams . templateHtml , locale . lang ) ;
renderPageToHtml ( '' , ` ${ docDir } ${ pathPrefix } /brand/index.html ` , templateParams ) ;
}
2022-11-28 18:16:32 +02:00
}
setLocale ( 'en_GB' ) ;
2021-07-10 12:16:13 +02:00
2023-10-30 13:32:14 +02:00
// ==========================================================================
// All other pages are generated dynamically from the Markdown files under
// /readme
//
// 2023-10-23: This was used to build the Help pages from the Markdown
// files, however this is now done using Docusaurus. A few files still need
// to be at the root however, and so we keep that process here for now. Any
// file that need to be processed should go in the `filesToProcess` array.
// Eventually all that should probably be moved to Docusaurus or to some
// static pages.
// ==========================================================================
const filesToProcess = [
'download.md' ,
'privacy.md' ,
'donate.md' ,
'connection_check.md' ,
] ;
2021-07-10 12:16:13 +02:00
2023-04-23 23:33:15 +02:00
interface SourceInfo {
title : string ;
donateLinksMd : string ;
showToc : boolean ;
openGraph : OpenGraphTags ;
sourceMarkdownName? : string ;
sourceMarkdownFile? : string ;
locale : Locale ;
}
const mdFiles : string [ ] = glob . sync ( ` ${ readmeDir } /**/*.md ` ) . map ( ( f : string ) = > f . substr ( rootDir . length + 1 ) ) ;
const sources : [ string , string , SourceInfo ] [ ] = [ ] ;
2021-07-10 12:16:13 +02:00
2023-04-23 23:33:15 +02:00
const makeTargetBasename = ( input : string , pathPrefix : string ) : string = > {
2021-12-17 19:37:01 +02:00
if ( isNewsFile ( input ) ) {
2021-12-21 20:53:36 +02:00
const filenameNoExt = basename ( input , '.md' ) ;
2022-02-24 21:35:28 +02:00
return ` news/ ${ filenameNoExt } /index.html ` ;
2021-12-17 19:37:01 +02:00
} else {
2023-10-30 13:32:14 +02:00
// Input is for example "readme/dev/spec/interop_with_frontmatter.md",
2021-12-21 20:53:36 +02:00
// and we need to convert it to
// "docs/spec/interop_with_frontmatter/index.html" and prefix it
// with the website repo full path.
2022-02-24 21:35:28 +02:00
let s = input ;
2022-02-09 17:24:08 +02:00
if ( s . endsWith ( 'index.md' ) ) {
s = s . replace ( /index\.md/ , 'index.html' ) ;
} else {
s = s . replace ( /\.md/ , '/index.html' ) ;
}
s = s . replace ( /readme\// , '' ) ;
2023-04-23 23:33:15 +02:00
if ( pathPrefix ) s = ` ${ pathPrefix } / ${ s } ` ;
2022-02-09 17:24:08 +02:00
return s ;
2021-12-17 19:37:01 +02:00
}
} ;
2023-04-23 23:33:15 +02:00
const makeTargetFilePath = ( input : string , pathPrefix : string ) : string = > {
return ` ${ docDir } / ${ makeTargetBasename ( input , pathPrefix ) } ` ;
2022-02-24 21:35:28 +02:00
} ;
2023-04-23 23:33:15 +02:00
const makeTargetUrl = ( input : string , pathPrefix : string ) = > {
return ` https://joplinapp.org/ ${ makeTargetBasename ( input , pathPrefix ) } ` ;
2022-02-24 21:35:28 +02:00
} ;
2021-12-17 19:37:01 +02:00
const newsFilePaths : string [ ] = [ ] ;
2021-07-10 12:16:13 +02:00
for ( const mdFile of mdFiles ) {
2023-10-30 13:32:14 +02:00
if ( ! filesToProcess . includes ( basename ( mdFile ) ) ) continue ;
2023-04-23 23:33:15 +02:00
if ( mdFile . startsWith ( 'readme/_i18n' ) ) continue ;
for ( const [ localeName , locale ] of Object . entries ( supportedLocales ) ) {
const title = await readmeFileTitle ( ` ${ rootDir } / ${ mdFile } ` ) ;
const targetFilePath = makeTargetFilePath ( mdFile , locale . pathPrefix ) ;
const openGraph = await extractOpenGraphTags ( mdFile , makeTargetUrl ( mdFile , locale . pathPrefix ) ) ;
const isNews = isNewsFile ( mdFile ) ;
2023-05-08 13:59:27 +02:00
if ( isNews && localeName === 'en_GB' ) newsFilePaths . push ( mdFile ) ;
2023-04-23 23:33:15 +02:00
let sourceFile = mdFile ;
if ( localeName !== 'en_GB' ) {
let temp = mdFile . replace ( /readme\// , '' ) ;
temp = ` readme/_i18n/ ${ localeName } / ${ temp } ` ;
if ( await pathExists ( temp ) ) sourceFile = temp ;
}
sources . push ( [ sourceFile , targetFilePath , {
title : title ,
donateLinksMd : mdFile === 'readme/donate.md' ? '' : donateLinksMd ,
showToc : mdFile !== 'readme/download.md' && ! isNews ,
openGraph ,
locale ,
} ] ) ;
}
2021-07-10 12:16:13 +02:00
}
for ( const source of sources ) {
source [ 2 ] . sourceMarkdownFile = source [ 0 ] ;
source [ 2 ] . sourceMarkdownName = path . basename ( source [ 0 ] , path . extname ( source [ 0 ] ) ) ;
2021-12-18 17:31:08 +02:00
const sourceFilePath = ` ${ rootDir } / ${ source [ 0 ] } ` ;
2021-12-19 09:53:19 +02:00
const targetFilePath = source [ 1 ] ;
2021-12-18 17:45:59 +02:00
const isNews = isNewsFile ( sourceFilePath ) ;
2021-12-18 17:31:08 +02:00
2021-12-19 09:53:19 +02:00
renderFileToHtml ( sourceFilePath , targetFilePath , {
2021-07-10 12:16:13 +02:00
. . . source [ 2 ] ,
templateHtml : mainTemplateHtml ,
2021-12-18 17:45:59 +02:00
pageName : isNews ? 'news-item' : '' ,
showImproveThisDoc : ! isNews ,
2022-03-03 16:06:37 +02:00
isNews ,
2021-07-10 12:16:13 +02:00
partials ,
2021-10-25 17:49:21 +02:00
assetUrls ,
2021-07-10 12:16:13 +02:00
} ) ;
}
2021-12-17 19:37:01 +02:00
2023-10-30 13:32:14 +02:00
// newsFilePaths.sort((a, b) => {
// return a.toLowerCase() > b.toLowerCase() ? -1 : +1;
// });
// await makeNewsFrontPage(newsFilePaths, `${docDir}/news/index.html`, {
// ...defaultTemplateParams(assetUrls, null),
// title: 'What\'s new',
// pageName: 'news',
// partials,
// showToc: false,
// showImproveThisDoc: false,
// donateLinksMd,
// openGraph: {
// title: 'Joplin - what\'s new',
// description: 'News about the Joplin open source application',
// url: 'https://joplinapp.org/news/',
// },
// });
2022-11-22 20:16:57 +02:00
2022-11-28 18:16:32 +02:00
// setLocale('zh_CN');
// const translations = parseTranslations(await parsePoFile(`${websiteAssetDir}/locales/zh_CN.po`));
// await processTranslations(`${docDir}/index.html`, `${docDir}/cn/index.html`, 'zh-cn', translations);
// await processTranslations(`${docDir}/plans/index.html`, `${docDir}/cn/plans/index.html`, 'zh-cn', translations);
// setLocale('en_GB');
2021-07-10 12:16:13 +02:00
}
main ( ) . catch ( ( error ) = > {
console . error ( error ) ;
2021-12-17 16:08:52 +02:00
process . exit ( 1 ) ;
2021-07-10 12:16:13 +02:00
} ) ;