Skip to content

Commit 2ac95cf

Browse files
committed
first commit
0 parents  commit 2ac95cf

12 files changed

+4351
-0
lines changed

.babelrc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"presets": [ "es2015", "stage-0", "react" ],
3+
plugins: [ "transform-decorators-legacy" ]
4+
}

.gitignore

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# osx noise
2+
.DS_Store
3+
profile
4+
5+
# xcode noise
6+
build/*
7+
*.mode1
8+
*.mode1v3
9+
*.mode2v3
10+
*.perspective
11+
*.perspectivev3
12+
*.pbxuser
13+
*.xcworkspace
14+
xcuserdata
15+
16+
# svn & cvs
17+
.svn
18+
CVS
19+
node_modules
20+
lib

README.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
markdown-in-js
2+
---
3+
4+
zero-overhead markdown in your react components
5+
6+
```jsx
7+
const App = () => markdown`
8+
## This is some content.
9+
10+
${ <span> interpolate more <Content/> </span> }
11+
12+
you can <i>inline *html*</i>
13+
<div style=${{fontWeight: 'bold'}} className=${'some more styles'} onClick=${handler}>
14+
interpolate attributes as expected
15+
</div>
16+
`
17+
18+
- gets compiled to react elements via a babel plugin
19+
- preserves interpolations
20+
- built with [commonmark](https://github.com/jgm/commonmark.js)
21+
22+
usage
23+
---
24+
add `'markdown-in-js/babel'` to the `plugins` field of your babel config
25+
26+
27+
todo
28+
---
29+
- optionally no-wrap paragraphs
30+
- custom components for markdown primitives
31+
- `@markdown <custom>` pragma
32+
- tests!

examples/index.html

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<title></title>
5+
</head>
6+
<body>
7+
<div id="app"></div>
8+
<script src="bundle.js"></script>
9+
</body>
10+
</html>

examples/index.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import React from 'react'
2+
import { render } from 'react-dom'
3+
4+
import markdown from '../src' // so the linter won't complain
5+
6+
const App = () => <div>hello world</div>
7+
8+
render(<App/>, window.app)
9+
10+
// let x = md `here`
11+
12+
let x = markdown`
13+
${<M.a/>}
14+
15+
This is some text <span style=${{ fontWeight: 'bold' }}> we _here_ </span>
16+
17+
This is more text. And some more. And more.
18+
19+
${'I interpolated some text here'}
20+
21+
and <span style=${{ fontWeight: 'bold' }} className=${'someclasssomething else'}>
22+
this is some inline _italicized_ *bold* html
23+
and this bit is _${'interpolated'}_
24+
</span>
25+
26+
and <p> what about _this_ </p>
27+
28+
This is an H1
29+
=============
30+
31+
This is an H2
32+
-------------
33+
34+
# This is an H1
35+
36+
## This is an H2
37+
38+
###### This is an H6
39+
`

examples/webpack.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
let webpack = require('webpack')
2+
let path = require('path')
3+
module.exports = {
4+
devtool: 'source-map',
5+
entry: './examples/index.js',
6+
output: {
7+
path: path.resolve('./examples'),
8+
filename: 'bundle.js'
9+
},
10+
module: {
11+
rules: [ {
12+
test: /\.js$/,
13+
exclude: /node_modules/,
14+
loader: 'babel-loader',
15+
query: {
16+
plugins: [ path.join(__dirname, '../lib') ]
17+
}
18+
}, {
19+
test: /\.json$/,
20+
loader: 'json-loader'
21+
} ]
22+
},
23+
plugins: [
24+
new webpack.DefinePlugin({
25+
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development')
26+
})
27+
],
28+
devServer: {
29+
contentBase: 'examples/',
30+
historyApiFallback: true,
31+
compress: true,
32+
inline: true
33+
}
34+
}

package.json

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
{
2+
"name": "markdown-in-js",
3+
"version": "1.0.0",
4+
"description": "markdown in js ",
5+
"main": "lib/index.js",
6+
"author": "Sunil Pai <[email protected]>",
7+
"license": "MIT",
8+
"files": [ "lib" ],
9+
"prepublish": "npm run build",
10+
"scripts": {
11+
"start": "webpack-dev-server --config examples/webpack.js",
12+
"build": "babel src -d lib"
13+
},
14+
"dependencies": {
15+
"commonmark": "^0.27.0"
16+
},
17+
"devDependencies": {
18+
"babel-cli": "^6.18.0",
19+
"babel-core": "^6.18.2",
20+
"babel-eslint": "^7.1.1",
21+
"babel-loader": "^6.2.8",
22+
"babel-plugin-istanbul": "^3.0.0",
23+
"babel-plugin-transform-decorators-legacy": "^1.3.4",
24+
"babel-polyfill": "^6.16.0",
25+
"babel-preset-es2015": "^6.18.0",
26+
"babel-preset-react": "^6.16.0",
27+
"babel-preset-stage-0": "^6.16.0",
28+
"babylon": "^6.14.1",
29+
"eslint": "^3.10.2",
30+
"eslint-config-rackt": "^1.1.1",
31+
"eslint-plugin-react": "^6.7.1",
32+
"json-loader": "^0.5.4",
33+
"react": "^15.4.0",
34+
"react-dom": "^15.4.0",
35+
"webpack": "2.1.0-beta.27",
36+
"webpack-dev-server": "2.1.0-beta.11"
37+
},
38+
"eslintConfig": {
39+
"extends": [
40+
"rackt"
41+
],
42+
"plugins": [
43+
"react"
44+
],
45+
"rules": {
46+
"react/jsx-uses-vars": "error",
47+
"react/jsx-uses-react": "error",
48+
"jsx-quotes": 0
49+
}
50+
}
51+
}

src/babel.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import * as babylon from 'babylon'
2+
3+
import commonmark from 'commonmark'
4+
import JSXRenderer from './jsx'
5+
let reader = new commonmark.Parser()
6+
let writer = new JSXRenderer()
7+
8+
module.exports = {
9+
visitor: {
10+
TaggedTemplateExpression(path) {
11+
12+
let code = path.hub.file.code
13+
if(path.node.tag.name === 'markdown') {
14+
let stubs = path.node.quasi.expressions.map(x => code.substring(x.start, x.end))
15+
let stubCtx = stubs.reduce((o, stub, i) => (o['spur-' + i] = stub, o), {})
16+
let ctr = 0
17+
let strs = path.node.quasi.quasis.map(x => x.value.cooked)
18+
let src = strs.reduce((arr, str, i) => {
19+
arr.push(str)
20+
if(i !== stubs.length) {
21+
arr.push('spur-'+ctr++)
22+
}
23+
return arr
24+
}, []).join('')
25+
let parsed = reader.parse(src)
26+
let intermediateSrc = writer.render(parsed)
27+
// replace with stubs
28+
let regex = /spur\-[0-9]+/gm
29+
let newSrc = intermediateSrc.replace(regex, x => `{${stubCtx[x]}}`)
30+
let transformed = babylon.parse(`<div className='_markdown_'>${newSrc}</div>`, { plugins: [
31+
'jsx', 'flow', 'doExpressions', 'objectRestSpread', 'decorators', 'classProperties',
32+
'exportExtensions', 'asyncGenerators', 'functionBind', 'functionSent', 'dynamicImport' ]
33+
})
34+
path.replaceWith(transformed.program.body[0])
35+
}
36+
}
37+
}
38+
}
39+

src/index.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
module.exports = () => {
2+
throw new Error('you forgot to add \'markdown-in-js/babel\' to your babel plugins')
3+
}
4+
5+
// text
6+
// softbreak
7+
// linebreak
8+
// link
9+
// image
10+
// emph
11+
// strong
12+
// paragraph
13+
// heading
14+
// code
15+
// code_block
16+
// thematic_break
17+
// block_quote
18+
// list
19+
// item
20+
// html_inline
21+
// html_block
22+
// custom_inline
23+
// custom_block
24+

0 commit comments

Comments
 (0)