This repository has been archived by the owner on Feb 10, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 12
/
CodeFromRemote.js
100 lines (85 loc) · 2.04 KB
/
CodeFromRemote.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import React, { useEffect, useState } from 'react'
import fetch from 'node-fetch'
import CodeBlock from '@theme/CodeBlock'
import styles from './CodeFromRemote.module.css'
const detectLanguage = (src) => {
const ext = src.split('.').pop()
switch (ext) {
case 'jsx':
return 'jsx'
case 'tsx':
return 'tsx'
case 'ts':
return 'typescript'
case 'go':
return 'go'
case 'yaml':
case 'yml':
return 'yaml'
case 'js':
return 'javascript'
case 'html':
return 'html'
case 'pug':
return 'pug'
default:
return ext
}
}
const findPath = (src) => {
const matches =
src.match(
new RegExp('https://github.com/[^/]+/[^/]+/blob/[^/]+/(.+)', 'i')
) || []
if (matches.length >= 2) {
return matches[1]
}
return src
}
const findLine = (needle, haystack) => {
if (!needle) {
return 0
}
const index = haystack.findIndex((s) => s.indexOf(needle) > -1)
if (index === -1) {
return 0
}
return index
}
const transform =
({ startAt, endAt }) =>
(content) => {
let lines = content.split('\n')
const startIndex = findLine(startAt, lines)
if (startIndex > 0) {
lines = ['// ...', ...lines.slice(startIndex, -1)]
}
const endIndex = findLine(endAt, lines)
if (endIndex > 0) {
lines = [...lines.slice(0, endIndex + 1), '// ...']
}
return lines.join('\n')
}
const CodeFromRemote = (props) => {
const { src, title } = props
const [content, setContent] = useState('')
useEffect(() => {
fetch(
src
.replace('github.com', 'raw.githubusercontent.com')
.replace('/blob/', '/')
)
.then((body) => body.text())
.then(transform(props))
.then(setContent)
.catch(console.error)
}, [])
const lang = `language-${detectLanguage(src)}`
const metaString = `title="${title || findPath(src)}"`
return (
<div className={styles.container}>
<CodeBlock metastring={metaString} className={lang} children={content} />
</div>
)
}
export default CodeFromRemote