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 /
1621
17- files . forEach ( file => {
18- if ( path . basename ( file ) !== 'index.md' ) return
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+ categoryIndexFiles . forEach ( categoryIndexFile => {
27+ let categoryIndexContent = fs . readFileSync ( categoryIndexFile , 'utf8' )
1928
20- let fileContent = fs . readFileSync ( file , 'utf-8' )
2129 // find array of TOC link strings
22- const rawItems = fileContent . match ( linksArray )
30+ const rawItems = categoryIndexContent . match ( linksArray )
2331 if ( ! rawItems || ! rawItems [ 0 ] . includes ( 'topic_link_in_list' ) ) return
2432
2533 const pageToc = { }
@@ -37,24 +45,53 @@ files.forEach(file => {
3745 pageToc [ currentTopic ] = tmpArray
3846 }
3947 } )
48+
4049 for ( const topic in pageToc ) {
41- const oldTopicDirectory = path . dirname ( file )
50+ const oldTopicDirectory = path . dirname ( categoryIndexFile )
4251 const newTopicDirectory = path . join ( oldTopicDirectory , topic )
43- const topicFile = path . join ( oldTopicDirectory , `${ topic } .md` )
52+ const oldTopicFile = path . join ( oldTopicDirectory , `${ topic } .md` )
53+
54+ // Some translated category TOCs may be outdated and contain incorrect links
55+ if ( ! fs . existsSync ( oldTopicFile ) ) continue
4456
4557 if ( ! fs . existsSync ( newTopicDirectory ) ) fs . mkdirSync ( newTopicDirectory )
4658
47- let topicContent = fs . readFileSync ( topicFile , 'utf-8' )
48- topicContent = topicContent . replace ( 'mapTopic: true\n' , '' )
59+ const { data, content } = frontmatter ( fs . readFileSync ( oldTopicFile , 'utf8' ) )
60+ delete data . mapTopic
61+
62+ let topicContent = content
4963
5064 const articles = pageToc [ topic ]
5165
5266 articles . forEach ( article => {
53- fs . renameSync ( ` ${ oldTopicDirectory } / ${ article } .md` , ` ${ newTopicDirectory } / ${ article } .md` )
67+ // Update the new map topic index file content
5468 topicContent = topicContent + `{% link_with_intro /${ article } %}\n`
55- fileContent = fileContent . replace ( `/{% link_in_list /${ article } ` , `/{% link_in_list /${ newTopicDirectory } /${ article } ` )
69+
70+ // Update the category index file content
71+ categoryIndexContent = categoryIndexContent . replace ( `{% link_in_list /${ article } ` , `{% link_in_list /${ topic } /${ article } ` )
72+
73+ // Early return if the article doesn't exist (some translated category TOCs may be outdated and contain incorrect links)
74+ if ( ! fs . existsSync ( `${ oldTopicDirectory } /${ article } .md` ) ) return
75+
76+ // Move the file under the new map topic directory
77+ const newArticlePath = `${ newTopicDirectory } /${ article } .md`
78+ fs . renameSync ( `${ oldTopicDirectory } /${ article } .md` , newArticlePath )
79+
80+ // Read the article file so we can add a redirect from its old path
81+ const articleContents = frontmatter ( fs . readFileSync ( newArticlePath , 'utf8' ) )
82+ addRedirectToFrontmatter ( articleContents . data . redirect_from , `${ oldTopicDirectory } /${ article } ` )
83+
84+ // Write the article with updated frontmatter
85+ fs . writeFileSync ( newArticlePath , frontmatter . stringify ( articleContents . content . trim ( ) , articleContents . data , { lineWidth : 10000 } ) )
5686 } )
57- fs . writeFileSync ( `${ newTopicDirectory } /index.md` , topicContent )
58- fs . unlinkSync ( topicFile )
87+
88+ // Write the map topic index file
89+ fs . writeFileSync ( `${ newTopicDirectory } /index.md` , frontmatter . stringify ( topicContent . trim ( ) , data , { lineWidth : 10000 } ) )
90+
91+ // Write the category index file
92+ fs . writeFileSync ( categoryIndexFile , categoryIndexContent )
93+
94+ // Delete the old map topic
95+ fs . unlinkSync ( oldTopicFile )
5996 }
6097} )
0 commit comments