From d42ecb943f485b0e6368419f018ba71ebf8480f6 Mon Sep 17 00:00:00 2001 From: Endilie Yacop Sucipto Date: Sat, 21 Jul 2018 20:54:45 +0700 Subject: [PATCH] Don't replace static assets linking in fenced code blocks (#864) * Don't replace any relative links to static assets in a fenced code block * revert unintended docs change * improve regex * remove test file :sob * stronger regex test for replace assets * super simplify solution --- lib/server/__tests__/__fixtures__/doc1.md | 17 +++- lib/server/__tests__/__fixtures__/doc2.md | 13 +++- .../__tests__/__snapshots__/docs.test.js.snap | 78 ++++++++++++++++++- lib/server/__tests__/docs.test.js | 30 ++++++- lib/server/docs.js | 21 +++-- 5 files changed, 148 insertions(+), 11 deletions(-) diff --git a/lib/server/__tests__/__fixtures__/doc1.md b/lib/server/__tests__/__fixtures__/doc1.md index 3320c42f0e..544689cab7 100644 --- a/lib/server/__tests__/__fixtures__/doc1.md +++ b/lib/server/__tests__/__fixtures__/doc1.md @@ -3,4 +3,19 @@ id: doc1 title: Document 1 --- -Docusaurus is the best :) \ No newline at end of file +Docusaurus is the best :) + +![image1](assets/image1.png) + +```js +console.log("Docusaurus"); +``` + +![image2](assets/image2.jpg) +![image3](assets/image3.gif) + +Don't replace the one below +```md + +![image4](assets/image4.bmp) +``` \ No newline at end of file diff --git a/lib/server/__tests__/__fixtures__/doc2.md b/lib/server/__tests__/__fixtures__/doc2.md index 7224307a93..8219f75085 100644 --- a/lib/server/__tests__/__fixtures__/doc2.md +++ b/lib/server/__tests__/__fixtures__/doc2.md @@ -15,4 +15,15 @@ title: Document 2 ## Repeating Docs - [doc1](doc1.md) -- [doc2](./doc2.md) \ No newline at end of file +- [doc2](./doc2.md) + +## Do not replace this +```md +![image1](assets/image1.png) +``` + +```js +const doc1 = foo(); +console.log("[image2](assets/image2.jpg)"); +const testStr = `![image3](assets/image3.gif)`; +``` \ No newline at end of file diff --git a/lib/server/__tests__/__snapshots__/docs.test.js.snap b/lib/server/__tests__/__snapshots__/docs.test.js.snap index c7c9123421..50cf8f40c9 100644 --- a/lib/server/__tests__/__snapshots__/docs.test.js.snap +++ b/lib/server/__tests__/__snapshots__/docs.test.js.snap @@ -2,7 +2,22 @@ exports[`mdToHtmlify transform nothing 1`] = ` " -Docusaurus is the best :)" +Docusaurus is the best :) + +![image1](assets/image1.png) + +\`\`\`js +console.log(\\"Docusaurus\\"); +\`\`\` + +![image2](assets/image2.jpg) +![image3](assets/image3.gif) + +Don't replace the one below +\`\`\`md + +![image4](assets/image4.bmp) +\`\`\`" `; exports[`mdToHtmlify transform to correct link 1`] = ` @@ -19,5 +34,64 @@ exports[`mdToHtmlify transform to correct link 1`] = ` ## Repeating Docs - [doc1](/docs/en/next/doc1) -- [doc2](/docs/en/next/doc2)" +- [doc2](/docs/en/next/doc2) + +## Do not replace this +\`\`\`md +![image1](assets/image1.png) +\`\`\` + +\`\`\`js +const doc1 = foo(); +console.log(\\"[image2](assets/image2.jpg)\\"); +const testStr = \`![image3](assets/image3.gif)\`; +\`\`\`" +`; + +exports[`replaceAssetsLink does not transform document without valid assets link 1`] = ` +" +### Existing Docs + +- [doc1](doc1.md) +- [doc2](./doc2.md) + +### Non-existing Docs + +- [hahaha](hahaha.md) + +## Repeating Docs + +- [doc1](doc1.md) +- [doc2](./doc2.md) + +## Do not replace this +\`\`\`md +![image1](assets/image1.png) +\`\`\` + +\`\`\`js +const doc1 = foo(); +console.log(\\"[image2](assets/image2.jpg)\\"); +const testStr = \`![image3](assets/image3.gif)\`; +\`\`\`" +`; + +exports[`replaceAssetsLink transform document with valid assets link 1`] = ` +" +Docusaurus is the best :) + +![image1](/docs/assets/image1.png) + +\`\`\`js +console.log(\\"Docusaurus\\"); +\`\`\` + +![image2](/docs/assets/image2.jpg) +![image3](/docs/assets/image3.gif) + +Don't replace the one below +\`\`\`md + +![image4](assets/image4.bmp) +\`\`\`" `; diff --git a/lib/server/__tests__/docs.test.js b/lib/server/__tests__/docs.test.js index eb3cbee9c5..19ec0e7c1a 100644 --- a/lib/server/__tests__/docs.test.js +++ b/lib/server/__tests__/docs.test.js @@ -49,9 +49,10 @@ const doc2 = fs.readFileSync( 'utf8' ); +const rawContent1 = metadataUtils.extractMetadata(doc1).rawContent; +const rawContent2 = metadataUtils.extractMetadata(doc2).rawContent; + describe('mdToHtmlify', () => { - const rawContent1 = metadataUtils.extractMetadata(doc1).rawContent; - const rawContent2 = metadataUtils.extractMetadata(doc2).rawContent; const mdToHtml = metadataUtils.mdToHtml(Metadata, '/'); test('transform nothing', () => { @@ -129,6 +130,31 @@ describe('getFile', () => { }); }); +describe('replaceAssetsLink', () => { + test('transform document with valid assets link', () => { + const content1 = docs.replaceAssetsLink(rawContent1); + expect(content1).toMatchSnapshot(); + expect(content1).toContain('![image1](/docs/assets/image1.png)'); + expect(content1).toContain('![image2](/docs/assets/image2.jpg)'); + expect(content1).toContain('![image3](/docs/assets/image3.gif)'); + expect(content1).toContain('![image4](assets/image4.bmp)'); + expect(content1).not.toContain('![image1](assets/image1.png)'); + expect(content1).not.toContain('![image2](assets/image2.jpg)'); + expect(content1).not.toContain('![image3](assets/image3.gif)'); + expect(content1).not.toContain('![image4](/docs/assets/image4.bmp)'); + expect(content1).not.toEqual(rawContent1); + }); + + test('does not transform document without valid assets link', () => { + const content2 = docs.replaceAssetsLink(rawContent2); + expect(content2).toMatchSnapshot(); + expect(content2).not.toContain('![image1](/docs/assets/image1.png)'); + expect(content2).not.toContain('![image2](/docs/assets/image2.jpg)'); + expect(content2).not.toContain('![image3](/docs/assets/image3.gif)'); + expect(content2).toEqual(rawContent2); + }); +}); + afterAll(() => { process.chdir(originalCwd); }); diff --git a/lib/server/docs.js b/lib/server/docs.js index 896d3e1ec9..2ab0bae25a 100644 --- a/lib/server/docs.js +++ b/lib/server/docs.js @@ -69,6 +69,19 @@ function mdToHtmlify(oldContent, mdToHtml, metadata) { return content; } +function replaceAssetsLink(oldContent) { + let fencedBlock = false; + const lines = oldContent.split('\n').map(line => { + if (line.trim().startsWith('```')) { + fencedBlock = !fencedBlock; + } + return fencedBlock + ? line + : line.replace(/\]\(assets\//g, `](${siteConfig.baseUrl}docs/assets/`); + }); + return lines.join('\n'); +} + function getComponent(rawContent, mdToHtml, metadata) { // generate table of contents let content = insertTOC(rawContent); @@ -76,11 +89,8 @@ function getComponent(rawContent, mdToHtml, metadata) { // replace any links to markdown files to their website html links content = mdToHtmlify(content, mdToHtml, metadata); - // replace any relative links to static assets to absolute links - content = content.replace( - /\]\(assets\//g, - `](${siteConfig.baseUrl}docs/assets/` - ); + // replace any relative links to static assets (not in fenced code blocks) to absolute links + content = replaceAssetsLink(content); const DocsLayout = require('../core/DocsLayout.js'); return ( @@ -97,4 +107,5 @@ module.exports = { getComponent, getFile, mdToHtmlify, + replaceAssetsLink, };