import File from './utils/file' ; import Log from './utils/log' ; import Filter from './utils/filter' ; import { Stats } from 'fs' ; import { appendHighlight , appendHighlightStyle } from './utils/highlight' ; const __app = Filter . path ( `${ __dirname }/../../templates/app` ) ; const __target = Filter . path ( `${ __dirname }/../../templates/target` ) ; const __temp = Filter . path ( `${ __dirname }/../../templates/temp` ) ; const USER_PATH = process . cwd ( ) ; const parseSuffix = ( filePath ) : [ string , string , string , string , number ] => { const suffix = filePath . split ( '/' ) . reverse ( ) [ 0 ] ; const includeNumberPrefix = /^\d+_/ . test ( suffix ) && ! Number . isNaN ( + suffix . split ( '_' ) [ 0 ] ) ; const weight = includeNumberPrefix ? + suffix . split ( '_' ) [ 0 ] : 100 ; const fileName = includeNumberPrefix ? suffix . replace ( /^\d+_/ , '' ) : suffix ; const path = filePath . replace ( suffix , '' ) ; const showPath = path . replace ( /\d+_/g , '' ) ; return [ path , showPath , suffix , fileName , weight ] ; } ; const generateCatalog = ( filePath , config , children = [ ] ) => { const [ path , showPath , suffix , fileName , weight ] = parseSuffix ( filePath ) ; return { path , showPath , native : suffix , name : config . alias [ fileName ] ? config . alias [ fileName ] : fileName , children , weight , } ; } ; const isMarkFileOrDirectory = ( name ) : boolean => name . endsWith ( '.md' ) || ! name . includes ( '.' ) ; const deepEachSource = async ( path , config ) : Promise < Catalog [ ] > => { const files = await File . readdir ( `${ USER_PATH }/${ path }` ) ; const catalogs = [ ] ; for ( const name of files ) { if ( ! isMarkFileOrDirectory ( name ) ) continue ; if ( name === 'assets' ) continue ; const nextPath = `${ path }/${ name }` ; const stat = await File . stat ( nextPath ) ; if ( stat . isFile ( ) ) { catalogs . push ( generateCatalog ( nextPath , config ) ) ; continue ; } if ( stat . isDirectory ( ) ) { catalogs . push ( generateCatalog ( nextPath , config , await deepEachSource ( nextPath , config ) ) ) ; } } return catalogs . sort ( ( pre , next ) => pre . weight - next . weight ) ; } ; export const compileCatalog = async ( config ) => { Log . time . start ( 'generate catalog' ) ; const catalogs = await deepEachSource ( config . __user_source_path , config ) ; Log . time . over ( ) ; return catalogs ; } ; const makeTargetPath = ( path , sourcePath ) : string => { const sourceFullPath = path . split ( sourcePath ) . reverse ( ) [ 0 ] ; return `${ __temp }/static/${ sourceFullPath }` ; } ; const createHtml = async ( source , target ) : Promise < void > => { const content = await File . readFile ( source , 'utf-8' ) ; target = target . replace ( '.md' , '.html' ) ; await File . writeFile ( target , await File . marked ( content ) , 'utf-8' ) ; } ; const generatePages = async ( catalogs , sourcePath ) : Promise < void > => { for ( const unit of catalogs ) { const p = makeTargetPath ( unit . showPath + unit . name , sourcePath ) ; if ( unit . children && unit . children . length > 0 ) { await File . spawnSync ( 'mkdir' , [ p ] ) ; await generatePages ( unit . children , sourcePath ) ; continue ; } await createHtml ( unit . path + unit . native , p ) ; } } ; export const compileMarkdown = async ( catalogs , sourcePath ) => { Log . time . start ( 'compile to html' ) ; await File . exists ( __temp ) && await File . exec ( `rm -rf ${ __temp }` ) ; await File . mkdir ( __temp ) ; await File . mkdir ( `${ __temp }/static` ) ; await generatePages ( catalogs , sourcePath ) ; Log . time . over ( ) ; } ; export const copyTheme = async ( config ) : Promise < void > => { const theme = config . theme || 'default' ; const p = `${ __dirname }/../../node_modules/simpler-paper-themes/dist/${ theme }.css` ; const themeStr = await File . readFile ( p , 'utf-8' ) ; await File . writeFile ( `${ __temp }/index.css` , themeStr ) ; } ; export const copyAssets = async ( config ) : Promise < void > => { const p = `${ config . __user_source_path }/assets` ; if ( ! ( await File . exists ( p ) ) ) return ; await File . exec ( `cp -r ${ p } ${ __temp }` ) ; } ; export const copyInlineHtml = async ( config , catalogs ) : Promise < void > => { const index = await File . readFile ( `${ __app }/index.html` , 'utf-8' ) ; const indexs = index . split ( '</body>' ) ; let scripts = `
    <script>window.__config=${ JSON . stringify ( config ) };window.__catalogs=${ JSON . stringify ( catalogs ) }</script>
    <script src="./index.js"></script>` ; const foot = `</body>${ indexs . pop ( ) }` ; await File . exec ( `cp ${ __dirname }/../index.js ${ __target }/index.js` ) ; scripts = await appendHighlight ( config . __user_source_path , scripts ) ; let inlineHtml = indexs . reduce ( ( pre , next ) => pre + next , '' ) + scripts + foot ; inlineHtml = inlineHtml . replace ( '__TITLE__' , config . title ) ; inlineHtml = appendHighlightStyle ( inlineHtml ) ; inlineHtml = inlineHtml . replace ( /\n/g , '' ) . replace ( />\s+</g , '><' ) ; await File . writeFile ( `${ __target }/index.html` , inlineHtml , 'utf-8' ) ; } ;