Skip to content

Commit d96aa47

Browse files
dignifiedquiretmcw
authored andcommitted
feat(config): add file property for notes (#614)
* feat(config): add file property for notes Fixes #609 * feat(config): resolve files against the config file location
1 parent 43e01ce commit d96aa47

File tree

7 files changed

+172
-6
lines changed

7 files changed

+172
-6
lines changed

docs/CONFIG.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,24 @@ This puts the top level API documentation for the `Map`, `LngLat`, and `LngLatBo
2727
items in the given order, and inserts a narrative item titled `Geography`
2828
after the section on maps. The `description` property of that narrative item
2929
is interpreted as Markdown.
30+
If you would like reuse your existing markdown files or just keep the content separate from the configuration you can use the `file` property. It is a filename it will be resolved against the directory that the `documentation.yml` file resides in.
31+
32+
So with a `documentation.yml` file like this
33+
34+
```yml
35+
toc:
36+
- Map
37+
- name: Geography
38+
file: geo.md
39+
- LngLat
40+
- LngLatBounds
41+
```
42+
43+
and a file `geo.md`
44+
45+
```markdown
46+
These are Mapbox GL JS's ways of representing locations
47+
and areas on the sphere.
48+
```
49+
50+
it would produce the same output as the previous example.

lib/load_config.js

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,41 @@ var yaml = require('js-yaml'),
1616
*/
1717
function loadConfig(filePath) {
1818
var ext = path.extname(filePath);
19-
var rawFile = fs.readFileSync(
20-
path.resolve(process.cwd(), filePath), 'utf8'
21-
);
19+
var absFilePath = path.resolve(process.cwd(), filePath);
20+
var rawFile = fs.readFileSync(absFilePath, 'utf8');
2221

2322
try {
2423
if (ext === '.json') {
25-
return JSON.parse(stripComments(rawFile));
24+
return processToc(JSON.parse(stripComments(rawFile)));
2625
}
2726

28-
return yaml.safeLoad(rawFile);
27+
return processToc(yaml.safeLoad(rawFile));
2928
} catch (e) {
3029
e.message = 'Cannot read config file: ' +
3130
filePath +
3231
'\nError: ' +
3332
e.message;
3433
throw e;
3534
}
35+
36+
function processToc(config) {
37+
if (!config || !config.toc) {
38+
return config;
39+
}
40+
41+
config.toc = config.toc.map(function (entry) {
42+
if (entry && entry.file) {
43+
entry.file = path.join(
44+
path.dirname(absFilePath),
45+
entry.file
46+
);
47+
}
48+
49+
return entry;
50+
});
51+
52+
return config;
53+
}
3654
}
3755

3856
module.exports = loadConfig;

lib/sort.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
var parseMarkdown = require('./parse_markdown');
44
var chalk = require('chalk');
5+
var path = require('path');
6+
var fs = require('fs');
57

68
/**
79
* Sort two documentation objects, given an optional order object. Returns
@@ -36,6 +38,19 @@ module.exports = function sortDocs(comments, options) {
3638
var fixed = options.toc.filter(function (val) {
3739
return typeof val === 'object' && val.name;
3840
}).map(function (val) {
41+
if (typeof val.file === 'string') {
42+
var filename = val.file;
43+
if (!path.isAbsolute(val.file)) {
44+
filename = path.join(process.cwd(), val.file);
45+
}
46+
47+
try {
48+
val.description = fs.readFileSync(filename).toString();
49+
delete val.file;
50+
} catch (err) {
51+
process.stderr.write(chalk.red('Failed to read file ' + filename));
52+
}
53+
}
3954
if (typeof val.description === 'string') {
4055
val.description = parseMarkdown(val.description);
4156
}

test/config_fixture/config_file.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
toc:
2+
- name: snowflake
3+
file: ../fixture/snowflake.md

test/fixture/snowflake.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# The Snowflake

test/lib/load_config.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,12 @@ test('loadConfig', function (t) {
2828
t.deepEqual(loadConfig(path.join(__dirname, '../config_fixture/config_links.yml')),
2929
{ foo: 'hello [link](https://github.com/my/link) world' }, 'config with markdown link');
3030

31+
t.deepEqual(loadConfig(path.join(__dirname, '../config_fixture/config_file.yml')),{
32+
toc: [{
33+
name: 'snowflake',
34+
file: path.join(__dirname, '../fixture/snowflake.md')
35+
}]
36+
}, 'config with file reference');
37+
3138
t.end();
3239
});

test/lib/sort.js

Lines changed: 102 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
'use strict';
22

33
var test = require('tap').test,
4-
sort = require('../../lib/sort');
4+
sort = require('../../lib/sort'),
5+
path = require('path');
56

67
test('sort stream alphanumeric', function (t) {
78
var apples = { context: { sortKey: 'a' }, name: 'apples' };
@@ -177,3 +178,103 @@ test('sort an already-sorted stream containing a section/description', function
177178
t.deepEqual(sortTwice, [carrot, sectionMarkdown, bananas, apples]);
178179
t.end();
179180
});
181+
182+
test('sort toc with files', function (t) {
183+
var apples = { context: { sortKey: 'a' }, name: 'apples' };
184+
var carrot = { context: { sortKey: 'b' }, name: 'carrot' };
185+
var bananas = { context: { sortKey: 'c' }, name: 'bananas' };
186+
187+
var snowflake = {
188+
name: 'snowflake',
189+
file: 'test/fixture/snowflake.md'
190+
};
191+
192+
var processedSnowflake = {
193+
name: 'snowflake',
194+
kind: 'note',
195+
description: {
196+
children: [{
197+
children: [{
198+
position: {
199+
end: {column: 16, line: 1, offset: 15},
200+
indent: [],
201+
start: {column: 3, line: 1, offset: 2}
202+
},
203+
type: 'text',
204+
value: 'The Snowflake'
205+
}],
206+
depth: 1,
207+
position: {
208+
end: {column: 16, line: 1, offset: 15},
209+
indent: [],
210+
start: {column: 1, line: 1, offset: 0}
211+
},
212+
type: 'heading'
213+
}],
214+
position: {
215+
end: {column: 1, line: 2, offset: 16},
216+
start: {column: 1, line: 1, offset: 0}
217+
},
218+
type: 'root'
219+
}
220+
};
221+
t.deepEqual(sort([
222+
apples, carrot, bananas
223+
], {
224+
toc: [snowflake]
225+
}), [
226+
processedSnowflake, apples, carrot, bananas
227+
], 'with configuration');
228+
229+
t.end();
230+
});
231+
232+
test('sort toc with files absolute path', function (t) {
233+
var apples = { context: { sortKey: 'a' }, name: 'apples' };
234+
var carrot = { context: { sortKey: 'b' }, name: 'carrot' };
235+
var bananas = { context: { sortKey: 'c' }, name: 'bananas' };
236+
237+
var snowflake = {
238+
name: 'snowflake',
239+
file: path.join(__dirname, '../fixture/snowflake.md')
240+
};
241+
242+
var processedSnowflake = {
243+
name: 'snowflake',
244+
kind: 'note',
245+
description: {
246+
children: [{
247+
children: [{
248+
position: {
249+
end: {column: 16, line: 1, offset: 15},
250+
indent: [],
251+
start: {column: 3, line: 1, offset: 2}
252+
},
253+
type: 'text',
254+
value: 'The Snowflake'
255+
}],
256+
depth: 1,
257+
position: {
258+
end: {column: 16, line: 1, offset: 15},
259+
indent: [],
260+
start: {column: 1, line: 1, offset: 0}
261+
},
262+
type: 'heading'
263+
}],
264+
position: {
265+
end: {column: 1, line: 2, offset: 16},
266+
start: {column: 1, line: 1, offset: 0}
267+
},
268+
type: 'root'
269+
}
270+
};
271+
t.deepEqual(sort([
272+
apples, carrot, bananas
273+
], {
274+
toc: [snowflake]
275+
}), [
276+
processedSnowflake, apples, carrot, bananas
277+
], 'with configuration');
278+
279+
t.end();
280+
});

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy