Skip to content

Commit

Permalink
feat: resolve markdown images (#851)
Browse files Browse the repository at this point in the history
Markdown images are converted to MDX and require statements. This way
referencing local images using markdown syntax is now supported.
  • Loading branch information
remcohaszing authored and pedronauck committed May 8, 2019
1 parent 6d97e1a commit 1c8963f
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 0 deletions.
2 changes: 2 additions & 0 deletions core/remark-docz/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
"test": "jest"
},
"dependencies": {
"@babel/generator": "^7.4.0",
"@babel/types": "^7.4.0",
"unist-util-remove": "^1.0.1",
"unist-util-visit": "^1.4.0"
},
Expand Down
41 changes: 41 additions & 0 deletions core/remark-docz/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
import * as url from 'url'

import generate from '@babel/generator'
import t from '@babel/types'
import visit from 'unist-util-visit'
import remove from 'unist-util-remove'

Expand Down Expand Up @@ -65,8 +69,45 @@ const mergeNodeWithoutCloseTag = (tree: any, node: any, idx: any) => {
}
}

const createImgSrc = (src: string) => {
const parsed = url.parse(src)

if (parsed.protocol) {
return t.stringLiteral(src)
}

let { pathname } = parsed as { pathname: string }
if (!/^\.[./]+/.test(pathname)) {
pathname = `./${pathname}`
}
return t.jsxExpressionContainer(
t.callExpression(t.identifier('require'), [t.stringLiteral(pathname)])
)
}

const imageToJsx = (node: any): string =>
generate(
t.jsxOpeningElement(
t.jsxIdentifier('img'),
[
t.jsxAttribute(t.jsxIdentifier('alt'), t.stringLiteral(node.alt)),
t.jsxAttribute(t.jsxIdentifier('src'), createImgSrc(node.url)),
],
true
)
).code

// turns `html` nodes into `jsx` nodes
export default () => (tree: any) => {
visit(
tree,
'image',
(node: any, idx: any): void => {
// check if a node has just open tag
node.type = 'jsx'
node.value = imageToJsx(node)
}
)
visit(
tree,
'jsx',
Expand Down
3 changes: 3 additions & 0 deletions examples/images/doczrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default {
menu: ['Getting Started', 'Components'],
}
19 changes: 19 additions & 0 deletions examples/images/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"name": "docz-example-images",
"version": "1.0.4",
"license": "MIT",
"scripts": {
"dev": "docz dev",
"build": "docz build"
},
"dependencies": {
"prop-types": "^15.7.2",
"react": "^16.8.6",
"react-dom": "^16.8.6",
"styled-components": "^4.2.0"
},
"devDependencies": {
"docz": "^1.0.4",
"docz-theme-default": "^1.0.4"
}
}
20 changes: 20 additions & 0 deletions examples/images/src/index.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
name: Getting Started
route: /
---

# Tux

Tux is a penguin character and the official brand character of the Linux kernel.[1] Originally created as an entry to a Linux logo competition, Tux is the most commonly used icon for Linux, although different Linux distributions depict Tux in various styles. The character is used in many other Linux programs and as a general symbol of Linux.

An image of Tux can be resolved directly in markdown

![Tux](tux.png)

It can also be resolved using explicit relative paths

![Tux](./tux.png)

Images may also link to external URLs. For example, the following image is downloaded from Wikipedia

![Tux original](https://upload.wikimedia.org/wikipedia/commons/a/af/Tux.png)
Binary file added examples/images/src/tux.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 1c8963f

Please sign in to comment.