Skip to content

Commit 70ebb3b

Browse files
committed
[orga-build] handle image and relative link properly
1 parent d2ae4c0 commit 70ebb3b

File tree

9 files changed

+124
-47
lines changed

9 files changed

+124
-47
lines changed

.changeset/public-stars-search.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'orga-build': patch
3+
---
4+
5+
handle image and relative links

docs/guides/next.org

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#+type: document
44
#+position: 4
55

6-
Use the next plugin for orga.
6+
Use the next plugin for orga. Or better, use [[file:orga-build.org][orga-build]] instead.
77

88
* Installation
99

docs/guides/webpack.org

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#+position: 3
55

66
=@orgajs/loader= is a webpack loader taht can be used natrually with webpack setup.
7+
For hassle free experience, use [[file:orga-build.org][orga-build]].
78

89
* Installation
910

packages/orga-build/lib/build.js

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
import path from 'node:path'
22
import { createRequire } from 'node:module'
33
import { build as viteBuild } from 'vite'
4-
import orga from '@orgajs/rollup'
4+
import { setupOrga } from './orga.js'
55
import react from '@vitejs/plugin-react'
66
import { fileURLToPath, pathToFileURL } from 'node:url'
77
import { copy, emptyDir, ensureDir } from './fs.js'
88
import { pluginFactory } from './vite.js'
99
import fs from 'fs/promises'
1010
import assert from 'node:assert'
11-
import { rehypeWrap } from './plugins.js'
1211

1312
const require = createRequire(import.meta.url)
1413

@@ -33,9 +32,7 @@ export async function build({
3332
const clientOutDir = path.join(outDir, '.client')
3433

3534
const plugins = [
36-
orga({
37-
rehypePlugins: [[rehypeWrap, { className: containerClass }]]
38-
}),
35+
setupOrga({ containerClass }),
3936
react(),
4037
pluginFactory({ dir: root }),
4138
...vitePlugins

packages/orga-build/lib/orga.js

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/**
2+
* @import {Root as HastTree} from 'hast'
3+
*/
4+
import _orga from '@orgajs/rollup'
5+
import { visitParents } from 'unist-util-visit-parents'
6+
7+
/**
8+
* @param {Object} options
9+
* @param {string|string[]} options.containerClass - CSS class name(s) to wrap the rendered content
10+
*/
11+
export function setupOrga({ containerClass }) {
12+
return _orga({
13+
rehypePlugins: [[rehypeWrap, { className: containerClass }], image],
14+
reorgRehypeOptions: {
15+
linkHref: (link) => {
16+
console.log({ link })
17+
if (link.path.protocol === 'file') {
18+
return link.path.value.replace(/\.org$/, '')
19+
}
20+
return link.path.value
21+
}
22+
}
23+
})
24+
}
25+
26+
// --- plugins ---
27+
28+
/**
29+
* @param {Object} options
30+
* @param {string[]} options.className
31+
*/
32+
function rehypeWrap({ className = [] }) {
33+
/**
34+
* Transform.
35+
*
36+
* @param {HastTree} tree
37+
* Tree.
38+
* @returns {HastTree}
39+
* Nothing.
40+
*/
41+
return (tree) => {
42+
return {
43+
...tree,
44+
children: [
45+
{
46+
type: 'element',
47+
tagName: 'div',
48+
properties: {
49+
className
50+
},
51+
// @ts-ignore
52+
children: tree.children
53+
}
54+
]
55+
}
56+
}
57+
}
58+
59+
function image() {
60+
/**
61+
* @param {any} tree
62+
*/
63+
return function (tree) {
64+
/** @type {Record<string, string>} */
65+
const imports = {}
66+
visitParents(tree, { tagName: 'img' }, (node) => {
67+
node.type = 'jsx'
68+
const { src, target } = node.properties
69+
if (typeof src !== 'string') return
70+
if (src.startsWith('http')) {
71+
return
72+
}
73+
const name = (imports[src] ??= `asset_${genId()}`)
74+
node.value = `<img src={${name}} target='${target}'/>`
75+
})
76+
77+
for (const [src, name] of Object.entries(imports)) {
78+
tree.children.unshift({
79+
type: 'jsx',
80+
value: `import ${name} from '${src}'`,
81+
children: []
82+
})
83+
}
84+
}
85+
}
86+
87+
function genId(length = 8) {
88+
const array = new Uint8Array(length)
89+
crypto.getRandomValues(array)
90+
return Array.from(array, (byte) => (byte % 36).toString(36)).join('')
91+
}

packages/orga-build/lib/plugins.js

Lines changed: 0 additions & 34 deletions
This file was deleted.

packages/orga-build/lib/serve.js

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
import express from 'express'
22
import { createServer } from 'vite'
33
import fs from 'node:fs/promises'
4-
import orga from '@orgajs/rollup'
54
import react from '@vitejs/plugin-react'
65
import { pluginFactory } from './vite.js'
7-
import { rehypeWrap } from './plugins.js'
86
import { alias } from './build.js'
7+
import { setupOrga } from './orga.js'
98

109
/**
1110
* @param {import('./config.js').Config} config
@@ -15,9 +14,7 @@ export async function serve(config, port = 3000) {
1514
const app = express()
1615
const vite = await createServer({
1716
plugins: [
18-
orga({
19-
rehypePlugins: [[rehypeWrap, { className: config.containerClass }]]
20-
}),
17+
setupOrga({ containerClass: config.containerClass }),
2118
react(),
2219
pluginFactory({ dir: config.root }),
2320
...config.vitePlugins

packages/orga-build/package.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
"bin": {
77
"orga-build": "./cli.js"
88
},
9-
"scripts": {},
9+
"scripts": {
10+
"clean": "fd . -e d.ts -e d.ts.map -I -x rm {}"
11+
},
1012
"files": [
1113
"lib/",
1214
"cli.js",
@@ -48,6 +50,7 @@
4850
"@types/hast": "^3.0.4",
4951
"@types/node": "^22.13.1",
5052
"@types/react": "^19.0.8",
51-
"@types/react-dom": "^19.0.3"
53+
"@types/react-dom": "^19.0.3",
54+
"orga": "^4.5.1"
5255
}
5356
}

pnpm-lock.yaml

Lines changed: 17 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)