33const fs = require ( 'fs' )
44const path = require ( 'path' )
55const walk = require ( 'walk-sync' )
6+ const languages = require ( '../../lib/languages' )
7+ const frontmatter = require ( '../../lib/read-frontmatter' )
8+ const addRedirectToFrontmatter = require ( '../../lib/redirects/add-redirect-to-frontmatter' )
69
710const relativeRefRegex = / \/ [ a - z A - Z 0 - 9 - ] + / g
811const linkString = / { % [ ^ } ] * ?l i n k .* ? \/ ( .* ?) ? % } / m
912const linksArray = new RegExp ( linkString . source , 'gm' )
1013
11- const fullDirectoryPath = path . join ( process . cwd ( ) , '/content' )
12- const files = walk ( fullDirectoryPath , {
14+ const walkOpts = {
1315 includeBasePath : true ,
1416 directories : false
15- } )
17+ }
18+
19+ // We only want category TOC files, not product TOCs.
20+ const categoryFileRegex = / c o n t e n t \/ [ ^ / ] + ?\/ [ ^ / ] + ?\/ i n d e x .m d /
21+
22+ const fullDirectoryPaths = Object . values ( languages ) . map ( langObj => path . join ( process . cwd ( ) , langObj . dir , 'content' ) )
23+ const categoryIndexFiles = fullDirectoryPaths . map ( fullDirectoryPath => walk ( fullDirectoryPath , walkOpts ) ) . flat ( )
24+ . filter ( file => categoryFileRegex . test ( file ) )
25+
26+ // const categoryIndexFiles = [ path.join(process.cwd(), 'content/desktop/installing-and-configuring-github-desktop/index.md') ]
1627
17- files . forEach ( file => {
18- if ( path . basename ( file ) !== 'index.md' ) return
28+ categoryIndexFiles . forEach ( categoryIndexFile => {
29+ let categoryIndexContent = fs . readFileSync ( categoryIndexFile , 'utf8' )
1930
20- let fileContent = fs . readFileSync ( file , 'utf-8' )
2131 // find array of TOC link strings
22- const rawItems = fileContent . match ( linksArray )
32+ const rawItems = categoryIndexContent . match ( linksArray )
2333 if ( ! rawItems || ! rawItems [ 0 ] . includes ( 'topic_link_in_list' ) ) return
2434
2535 const pageToc = { }
@@ -37,24 +47,53 @@ files.forEach(file => {
3747 pageToc [ currentTopic ] = tmpArray
3848 }
3949 } )
50+
4051 for ( const topic in pageToc ) {
41- const oldTopicDirectory = path . dirname ( file )
52+ const oldTopicDirectory = path . dirname ( categoryIndexFile )
4253 const newTopicDirectory = path . join ( oldTopicDirectory , topic )
43- const topicFile = path . join ( oldTopicDirectory , `${ topic } .md` )
54+ const oldTopicFile = path . join ( oldTopicDirectory , `${ topic } .md` )
55+
56+ // Some translated category TOCs may be outdated and contain incorrect links
57+ if ( ! fs . existsSync ( oldTopicFile ) ) continue
4458
4559 if ( ! fs . existsSync ( newTopicDirectory ) ) fs . mkdirSync ( newTopicDirectory )
4660
47- let topicContent = fs . readFileSync ( topicFile , 'utf-8' )
48- topicContent = topicContent . replace ( 'mapTopic: true\n' , '' )
61+ const { data, content } = frontmatter ( fs . readFileSync ( oldTopicFile , 'utf8' ) )
62+ delete data . mapTopic
63+
64+ let topicContent = content
4965
5066 const articles = pageToc [ topic ]
5167
5268 articles . forEach ( article => {
53- fs . renameSync ( ` ${ oldTopicDirectory } / ${ article } .md` , ` ${ newTopicDirectory } / ${ article } .md` )
69+ // Update the new map topic index file content
5470 topicContent = topicContent + `{% link_with_intro /${ article } %}\n`
55- fileContent = fileContent . replace ( `/{% link_in_list /${ article } ` , `/{% link_in_list /${ newTopicDirectory } /${ article } ` )
71+
72+ // Update the category index file content
73+ categoryIndexContent = categoryIndexContent . replace ( `{% link_in_list /${ article } ` , `{% link_in_list /${ topic } /${ article } ` )
74+
75+ // Early return if the article doesn't exist (some translated category TOCs may be outdated and contain incorrect links)
76+ if ( ! fs . existsSync ( `${ oldTopicDirectory } /${ article } .md` ) ) return
77+
78+ // Move the file under the new map topic directory
79+ const newArticlePath = `${ newTopicDirectory } /${ article } .md`
80+ fs . renameSync ( `${ oldTopicDirectory } /${ article } .md` , newArticlePath )
81+
82+ // Read the article file so we can add a redirect from its old path
83+ const articleContents = frontmatter ( fs . readFileSync ( newArticlePath , 'utf8' ) )
84+ addRedirectToFrontmatter ( articleContents . data . redirect_from , `${ oldTopicDirectory } /${ article } ` )
85+
86+ // Write the article with updated frontmatter
87+ fs . writeFileSync ( newArticlePath , frontmatter . stringify ( articleContents . content . trim ( ) , articleContents . data , { lineWidth : 10000 } ) )
5688 } )
57- fs . writeFileSync ( `${ newTopicDirectory } /index.md` , topicContent )
58- fs . unlinkSync ( topicFile )
89+
90+ // Write the map topic index file
91+ fs . writeFileSync ( `${ newTopicDirectory } /index.md` , frontmatter . stringify ( topicContent . trim ( ) , data , { lineWidth : 10000 } ) )
92+
93+ // Write the category index file
94+ fs . writeFileSync ( categoryIndexFile , categoryIndexContent )
95+
96+ // Delete the old map topic
97+ fs . unlinkSync ( oldTopicFile )
5998 }
6099} )
0 commit comments