Skip to content

Commit 2afa4a8

Browse files
committed
Add local build of remark-ts-tools with improved caching
1 parent 31f0896 commit 2afa4a8

File tree

11 files changed

+1628
-1
lines changed

11 files changed

+1628
-1
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ dist*/
77
lib
88
es
99

10-
.yalc
10+
#.yalc
1111
yalc.lock
1212
yalc.sig
1313

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2020 Lenz Weber
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.
Lines changed: 298 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,298 @@
1+
# remark-typescript-tools
2+
3+
## What is it?
4+
5+
`remark-typescript-tools` contains two remark plugins to use TypeScript code with remark, to generate better documentation.
6+
7+
Currently it is aimed at docusaurus, but already pretty configurable. And it's open source, pull requests for more configuration options are always welcome ;)
8+
9+
### transpileCodeblocks
10+
11+
The `transpileCodeblocks` plugin will transpile all your `ts`-typed codeblocks to JavaScript and displays them side-by-side in tabs.
12+
13+
So
14+
15+
````md
16+
```ts
17+
import { createAction, createReducer } from '@reduxjs/toolkit';
18+
19+
const increment = createAction<number>('counter/increment');
20+
const decrement = createAction<number>('counter/decrement');
21+
22+
const counterReducer = createReducer(0, (builder) => {
23+
builder.addCase(increment, (state, action) => state + action.payload);
24+
builder.addCase(decrement, (state, action) => state - action.payload);
25+
});
26+
```
27+
````
28+
29+
will be rendered to this:
30+
31+
![an animations of tabs switching from TypeScript to JavaScript and back](./assets/tabs.gif)
32+
33+
It will _validate the TypeScript on compilation_, so your docs will be guaranteed to actually be runnable.
34+
It can even work _against your library source code_, which means that any PR that requires an update to your documentation will already get noticed in CI.
35+
36+
![an image of a compilation error](./assets/compileError.png)
37+
38+
Also, your examples can contain virtual files, importing from each other and you can even hide some of these virtual files, if they are not relevant for the example, but necessary for you to have valid code.
39+
40+
````md
41+
```ts
42+
// file: reducers.ts noEmit
43+
import { Reducer } from '@reduxjs/toolkit';
44+
declare const rootReducer: Reducer<{}>;
45+
export default rootReducer;
46+
47+
// file: store.ts
48+
import { configureStore } from '@reduxjs/toolkit';
49+
50+
import rootReducer from './reducers';
51+
52+
const store = configureStore({ reducer: rootReducer });
53+
```
54+
````
55+
56+
### linkDocblocks
57+
58+
This plugin allows you to link to sections of your source code's Docblocks, making sure that your documentation is up-to-date with your code.
59+
60+
So assuming this source code:
61+
62+
````ts
63+
/**
64+
* Interface Test!
65+
* @remarks
66+
* Some more infos.
67+
*/
68+
export interface Test {
69+
/**
70+
* This is a function
71+
* @remarks
72+
* And it is nested!
73+
* @overloadSummary
74+
* Also, this is a special overload
75+
* @overloadRemarks
76+
* With some more description
77+
* @param foo - some info about the first parameter
78+
* @example
79+
```ts
80+
console.log("test")
81+
```
82+
*/
83+
nestedFunction(foo: string): void;
84+
/**
85+
* This is a function
86+
* @remarks
87+
* And it is nested!
88+
* @overloadSummary
89+
* Also, this is a special overload that takes a second parameter
90+
* @overloadRemarks
91+
* With some more extra description
92+
* @param foo - some info about the first parameter
93+
* @param bar - and some info about the second parameter
94+
* @example
95+
```ts
96+
console.log("test")
97+
```
98+
*/
99+
nestedFunction(foo: string, bar: number): void;
100+
}
101+
````
102+
103+
the markdown code
104+
105+
```md
106+
# Infos about Test
107+
108+
[summary](docblock://test/linkDocblocks.test.ts?token=Test)
109+
110+
## Some more remarks
111+
112+
[remarks](docblock://test/linkDocblocks.test.ts?token=Test)
113+
```
114+
115+
would result in
116+
117+
```md
118+
# Infos about Test
119+
120+
Interface Test!
121+
122+
## Some more remarks
123+
124+
Some more infos.
125+
```
126+
127+
And you can also link to nested identifiers or function overloads:
128+
129+
```md
130+
# Infos about Test.nestedFunction
131+
132+
[summary,remarks](docblock://test/linkDocblocks.test.ts?token=Test.nestedFunction)
133+
134+
# Overload 0
135+
136+
[overloadSummary,params,overloadRemarks,examples](docblock://test/linkDocblocks.test.ts?token=Test.nestedFunction&overload=0)
137+
138+
# Overload 1
139+
140+
[overloadSummary,params,overloadRemarks,examples](docblock://test/linkDocblocks.test.ts?token=Test.nestedFunction&overload=1)
141+
```
142+
143+
will result in
144+
145+
```md
146+
# Infos about Test.nestedFunction
147+
148+
This is a function
149+
150+
And it is nested!
151+
152+
# Overload 0
153+
154+
Also, this is a special overload
155+
156+
#### Parameters:
157+
158+
- **foo** some info about the first parameter
159+
160+
With some more description
161+
162+
\`\`\`ts
163+
console.log(\\"test\\")
164+
165+
\`\`\`
166+
167+
# Overload 1
168+
169+
Also, this is a special overload that takes a second parameter
170+
171+
#### Parameters:
172+
173+
- **foo** some info about the first parameter
174+
- **bar** and some info about the second parameter
175+
176+
With some more extra description
177+
178+
\`\`\`ts
179+
console.log(\\"test\\")
180+
181+
\`\`\`
182+
```
183+
184+
Of course, you can combine this with `transpileCodeblocks`, so your examples from your comments from your source code will be actually type-checked against your source code!
185+
186+
## Usage with Docusaurus:
187+
188+
We are using the plugins like this over in `reduxjs/toolkit`:
189+
190+
```js
191+
// site configuration options.
192+
const { resolve } = require('path');
193+
const {
194+
linkDocblocks,
195+
transpileCodeblocks,
196+
} = require('remark-typescript-tools');
197+
198+
module.exports = {
199+
presets: [
200+
[
201+
'@docusaurus/preset-classic',
202+
{
203+
docs: {
204+
remarkPlugins: [
205+
[
206+
linkDocblocks,
207+
{
208+
extractorSettings: {
209+
tsconfig: resolve(__dirname, '../docs/tsconfig.json'),
210+
basedir: resolve(__dirname, '../src'),
211+
rootFiles: ['index.ts'],
212+
},
213+
},
214+
],
215+
[
216+
transpileCodeblocks,
217+
{
218+
compilerSettings: {
219+
tsconfig: resolve(__dirname, '../docs/tsconfig.json'),
220+
externalResolutions: {
221+
'@reduxjs/toolkit': {
222+
resolvedPath: resolve(__dirname, '../src'),
223+
packageId: {
224+
name: '@reduxjs/toolkit',
225+
subModuleName: 'index.ts',
226+
version: '1.0',
227+
},
228+
},
229+
},
230+
},
231+
},
232+
],
233+
],
234+
},
235+
},
236+
],
237+
],
238+
};
239+
```
240+
241+
In addition to that, `transpileCodeblocks` takes these options:
242+
243+
```ts
244+
import type { Node } from 'unist';
245+
import type { VFile } from 'vfile';
246+
247+
export interface TranspileCodeblocksSettings {
248+
compilerSettings: CompilerSettings;
249+
postProcessTranspiledJs?: PostProcessor;
250+
postProcessTs?: PostProcessor;
251+
assembleReplacementNodes?: (
252+
node: CodeNode,
253+
file: VFile,
254+
virtualFolder: string,
255+
virtualFiles: Record<string, VirtualFile>,
256+
transpilationResult: Record<string, TranspiledFile>,
257+
postProcessTs: PostProcessor,
258+
postProcessTranspiledJs: PostProcessor
259+
) => Node[];
260+
}
261+
262+
interface CompilerSettings {
263+
tsconfig: string;
264+
externalResolutions: Record<string, ExternalResolution>;
265+
/**
266+
* Allows transforming the virtual filepath for codeblocks.
267+
* This allows the files to resolve node modules from a different location
268+
* to their own directory.
269+
*/
270+
transformVirtualFilepath?: (filepath: string) => string;
271+
}
272+
273+
interface CodeNode extends Node {
274+
lang: string;
275+
meta: string;
276+
value: string;
277+
indent: number[];
278+
}
279+
280+
export interface VirtualFile {
281+
code: string;
282+
skip?: boolean;
283+
}
284+
285+
export type VirtualFiles = Record<string, VirtualFile>;
286+
287+
type PostProcessor = (
288+
files: VirtualFiles,
289+
parentFile?: string,
290+
defaultProcessor?: PostProcessor
291+
) => VirtualFiles;
292+
293+
export interface TranspiledFile extends VirtualFile {
294+
diagnostics: Array<Diagnostic>;
295+
}
296+
297+
export type TranspiledFiles = Record<string, TranspiledFile>;
298+
```

0 commit comments

Comments
 (0)