mirror of
https://github.com/GitbookIO/gitbook.git
synced 2026-09-16 07:35:16 +00:00
Compare commits
20 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2b81e94a5d | |||
| bc315a1dea | |||
| 7fc1e022ee | |||
| 78d947c5e8 | |||
| 9f9e1976e5 | |||
| ef84a34fcd | |||
| 5df4c358a4 | |||
| caa8c52222 | |||
| c3e243c775 | |||
| 4e3e3e515d | |||
| 2661a58776 | |||
| da2ee396cf | |||
| 2e66333aa6 | |||
| a2ad586a93 | |||
| 856b222a61 | |||
| fade3740c1 | |||
| 803d6218a7 | |||
| 7128db842a | |||
| 0342a11da0 | |||
| af80cbcd7c |
+1
-1
@@ -65,7 +65,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
||||
- Headings are no longer annotated with glossary terms
|
||||
- Themes are now published as a plugin, with ability to extend it from the book source
|
||||
- `links.sidebar` configuration is no longer supported, use summary sections instead
|
||||
- `pdf.headerTemplate` and `pdf.footerTemplate` have been replaced by a template in theme/book: `_layout/ebook/pdf_header.html` and `_layout/ebook/pdf_footer.html`
|
||||
- `pdf.headerTemplate` and `pdf.footerTemplate` have been replaced by a template in theme/book: `_layouts/ebook/pdf_header.html` and `_layouts/ebook/pdf_footer.html`
|
||||
- Markdown parser is now using CommonMark
|
||||
- Root folder for the book can be specified in the `"root"` property of the `book.json` file
|
||||
- Multi-lingual books share assets folder
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<img src="https://badge.fury.io/js/gitbook.svg" />
|
||||
<a href="https://travis-ci.org/GitbookIO/gitbook"><img src="https://travis-ci.org/GitbookIO/gitbook.png?branch=master" /></a>
|
||||
<a href="https://ci.appveyor.com/project/GitBook/gitbook"><img src="https://ci.appveyor.com/api/projects/status/63nlflxcwmb2pue6?svg=true" /></a>
|
||||
<a href="https://ci.appveyor.com/project/GitBook/gitbook"><img src="https://slack.gitbook.com/badge.svg" /></a>
|
||||
<a href="https://slack.gitbook.com"><img src="https://slack.gitbook.com/badge.svg" /></a>
|
||||
</p>
|
||||
|
||||
GitBook is a command line tool (and Node.js library) for building beautiful books using GitHub/Git and Markdown (or AsciiDoc). Here is an example: [ReduxJS documentation](http://redux.js.org/).
|
||||
|
||||
+1
-1
@@ -68,7 +68,7 @@ Parts are just groups of chapters and do not have dedicated pages, but according
|
||||
|
||||
#### Markdown syntax
|
||||
|
||||
Most of the files for GitBook use the Markdown syntax by default. GitBook infers your pages's structure from it. The syntax used is similar to the [GitHub Flavored Markdown syntax](https://guides.github.com/features/mastering-markdown/). One can also opt for the [AsciiDoc syntax](asciidoc.md).
|
||||
Most of the files for GitBook use the Markdown syntax by default. GitBook infers your pages's structure from it. The syntax used is similar to the [GitHub Flavored Markdown syntax](https://guides.github.com/features/mastering-markdown/). One can also opt for the [AsciiDoc syntax](syntax/asciidoc.md).
|
||||
|
||||
##### Example of a chapter file
|
||||
|
||||
|
||||
+12
-1
@@ -158,6 +158,17 @@ You can create fenced code blocks by placing triple backticks ` ``` ` before and
|
||||
}
|
||||
```
|
||||
|
||||
If your code contains templating syntax such as `{{ this }}` (see [templating](/docs/templating/variables.md)), you can disable templating with a `raw` block:
|
||||
|
||||
{% raw %}
|
||||
{% raw %}
|
||||
```html
|
||||
<span>{{ this will not be interpreted as templating }}</span>
|
||||
```
|
||||
{% endraw %}
|
||||
{% endraw %}
|
||||
|
||||
|
||||
##### Syntax highlighting
|
||||
|
||||
You can add an optional language identifier to enable syntax highlighting in your fenced code block.
|
||||
@@ -216,7 +227,7 @@ Asterisks
|
||||
|
||||
### Ignoring Markdown formatting
|
||||
|
||||
You can tell GitBook to ignore (or escape) Markdown formatting by using `\` before the Markdown character.
|
||||
You can tell GitBook to ignore (escape) Markdown formatting by using `\` before the Markdown character.
|
||||
|
||||
```
|
||||
Let's rename \*our-new-project\* to \*our-old-project\*.
|
||||
|
||||
@@ -96,3 +96,6 @@ Languages are defined by `{ id: 'en', title: 'English' }`.
|
||||
| Variable | Description |
|
||||
| -------- | ----------- |
|
||||
| `glossary.path` | Path to the Glossary in the book |
|
||||
|
||||
### Limitations
|
||||
Variables won't expand when used inside `SUMMARY.md`.
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
{
|
||||
"lerna": "2.0.0-beta.31",
|
||||
"version": "4.0.0-alpha.2"
|
||||
"version": "4.0.0-alpha.6"
|
||||
}
|
||||
|
||||
+3
-3
@@ -8,10 +8,10 @@
|
||||
"scripts": {
|
||||
"lint": "eslint .",
|
||||
"test": "lerna run --concurrency 1 test",
|
||||
"bootstrap": "npm run bump && lerna bootstrap",
|
||||
"bump": "./scripts/bump.js",
|
||||
"bootstrap": "lerna bootstrap",
|
||||
"clean": "lerna clean",
|
||||
"dist": "lerna run --concurrency 1 prepublish"
|
||||
"dist": "lerna run --concurrency 1 prepublish",
|
||||
"publish-version": "./scripts/publish.sh"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "gitbook-core",
|
||||
"version": "4.0.0-alpha.2",
|
||||
"version": "4.0.0-alpha.6",
|
||||
"description": "Core for GitBook plugins API",
|
||||
"main": "./lib/index.js",
|
||||
"dependencies": {
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
"description": "Button to copy code blocks",
|
||||
"main": "index.js",
|
||||
"browser": "./_assets/plugin.js",
|
||||
"version": "4.0.0-alpha.2",
|
||||
"version": "4.0.0-alpha.6",
|
||||
"dependencies": {
|
||||
"copy-to-clipboard": "^3.0.5",
|
||||
"gitbook-core": "^4.0.0-alpha.2"
|
||||
"gitbook-core": "^4.0.0-alpha.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"gitbook-plugin": "^4.0.0-alpha.2"
|
||||
"gitbook-plugin": "^4.0.0-alpha.6"
|
||||
},
|
||||
"engines": {
|
||||
"gitbook": ">=3.0.0"
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
"description": "Automatically add anchors to headings",
|
||||
"main": "index.js",
|
||||
"browser": "./_assets/plugin.js",
|
||||
"version": "4.0.0-alpha.2",
|
||||
"version": "4.0.0-alpha.6",
|
||||
"dependencies": {
|
||||
"classnames": "^2.2.5",
|
||||
"gitbook-core": "^4.0.0-alpha.2"
|
||||
"gitbook-core": "^4.0.0-alpha.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"gitbook-plugin": "^4.0.0-alpha.2"
|
||||
"gitbook-plugin": "^4.0.0-alpha.6"
|
||||
},
|
||||
"engines": {
|
||||
"gitbook": ">=3.0.0"
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
"description": "Syntax highlighter for Gitbook",
|
||||
"main": "index.js",
|
||||
"browser": "./_assets/plugin.js",
|
||||
"version": "4.0.0-alpha.2",
|
||||
"version": "4.0.0-alpha.6",
|
||||
"dependencies": {
|
||||
"gitbook-core": "^4.0.0-alpha.2",
|
||||
"gitbook-core": "^4.0.0-alpha.6",
|
||||
"highlight.js": "9.7.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"gitbook-plugin": "^4.0.0-alpha.2"
|
||||
"gitbook-plugin": "^4.0.0-alpha.6"
|
||||
},
|
||||
"engines": {
|
||||
"gitbook": ">=3.0.0"
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
"description": "Defines four types of styled hint blocks: info, danger, tip, working.",
|
||||
"main": "index.js",
|
||||
"browser": "./_assets/plugin.js",
|
||||
"version": "4.0.0-alpha.2",
|
||||
"version": "4.0.0-alpha.6",
|
||||
"dependencies": {
|
||||
"classnames": "^2.2.5",
|
||||
"gitbook-core": "^4.0.0-alpha.2"
|
||||
"gitbook-core": "^4.0.0-alpha.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"gitbook-plugin": "^4.0.0-alpha.2"
|
||||
"gitbook-plugin": "^4.0.0-alpha.6"
|
||||
},
|
||||
"engines": {
|
||||
"gitbook": ">=4.0.0"
|
||||
|
||||
@@ -3,15 +3,15 @@
|
||||
"description": "Live reloading for your gitbook",
|
||||
"main": "index.js",
|
||||
"browser": "./_assets/plugin.js",
|
||||
"version": "4.0.0-alpha.2",
|
||||
"version": "4.0.0-alpha.6",
|
||||
"engines": {
|
||||
"gitbook": "*"
|
||||
},
|
||||
"dependencies": {
|
||||
"gitbook-core": "^4.0.0-alpha.2"
|
||||
"gitbook-core": "^4.0.0-alpha.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"gitbook-plugin": "^4.0.0-alpha.2"
|
||||
"gitbook-plugin": "^4.0.0-alpha.6"
|
||||
},
|
||||
"scripts": {
|
||||
"build-js": "gitbook-plugin build ./src/index.js ./_assets/plugin.js",
|
||||
|
||||
@@ -3,14 +3,14 @@
|
||||
"description": "Static and local index for search in GitBook",
|
||||
"main": "index.js",
|
||||
"browser": "./_assets/theme.js",
|
||||
"version": "4.0.0-alpha.2",
|
||||
"version": "4.0.0-alpha.6",
|
||||
"dependencies": {
|
||||
"gitbook-core": "^4.0.0-alpha.2",
|
||||
"gitbook-core": "^4.0.0-alpha.6",
|
||||
"html-entities": "1.2.0",
|
||||
"lunr": "0.5.12"
|
||||
},
|
||||
"devDependencies": {
|
||||
"gitbook-plugin": "^4.0.0-alpha.2"
|
||||
"gitbook-plugin": "^4.0.0-alpha.6"
|
||||
},
|
||||
"engines": {
|
||||
"gitbook": ">=3.0.0"
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
"description": "Search integration in GitBook",
|
||||
"main": "index.js",
|
||||
"browser": "./_assets/theme.js",
|
||||
"version": "4.0.0-alpha.2",
|
||||
"version": "4.0.0-alpha.6",
|
||||
"dependencies": {
|
||||
"gitbook-core": "^4.0.0-alpha.2",
|
||||
"gitbook-core": "^4.0.0-alpha.6",
|
||||
"react": "^15.4.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"gitbook-plugin": "^4.0.0-alpha.2",
|
||||
"gitbook-plugin": "^4.0.0-alpha.6",
|
||||
"react-highlighter": "^0.3.3"
|
||||
},
|
||||
"engines": {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"description": "Sharing buttons in the toolbar",
|
||||
"main": "index.js",
|
||||
"browser": "./_assets/plugin.js",
|
||||
"version": "4.0.0-alpha.2",
|
||||
"version": "4.0.0-alpha.6",
|
||||
"gitbook": {
|
||||
"properties": {
|
||||
"facebook": {
|
||||
@@ -53,10 +53,10 @@
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"gitbook-core": "^4.0.0-alpha.2"
|
||||
"gitbook-core": "^4.0.0-alpha.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"gitbook-plugin": "^4.0.0-alpha.2"
|
||||
"gitbook-plugin": "^4.0.0-alpha.6"
|
||||
},
|
||||
"engines": {
|
||||
"gitbook": ">=3.0.0"
|
||||
|
||||
@@ -3,19 +3,19 @@
|
||||
"description": "Default theme for GitBook",
|
||||
"main": "./index.js",
|
||||
"browser": "./_assets/theme.js",
|
||||
"version": "4.0.0-alpha.2",
|
||||
"version": "4.0.0-alpha.6",
|
||||
"engines": {
|
||||
"gitbook": ">=3.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"debounce": "^1.0.0",
|
||||
"gitbook-core": "^4.0.0-alpha.2"
|
||||
"gitbook-core": "^4.0.0-alpha.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"classnames": "^2.2.5",
|
||||
"font-awesome": "^4.6.3",
|
||||
"gitbook-markdown-css": "^1.0.1",
|
||||
"gitbook-plugin": "^4.0.0-alpha.2",
|
||||
"gitbook-plugin": "^4.0.0-alpha.6",
|
||||
"less": "^2.7.1",
|
||||
"less-plugin-clean-css": "^1.5.1",
|
||||
"preboot": "git+https://github.com/mdo/preboot.git#4aab4edd85f076d50609cbe28e4fe66cc0771701"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "gitbook-plugin",
|
||||
"version": "4.0.0-alpha.2",
|
||||
"version": "4.0.0-alpha.6",
|
||||
"description": "CLI for compiling and testing plugins",
|
||||
"main": "./lib/index.js",
|
||||
"dependencies": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "gitbook",
|
||||
"version": "4.0.0-alpha.2",
|
||||
"version": "4.0.0-alpha.6",
|
||||
"homepage": "https://www.gitbook.com",
|
||||
"description": "Library and cmd utility to generate GitBooks",
|
||||
"main": "lib/index.js",
|
||||
@@ -22,16 +22,16 @@
|
||||
"extend": "^3.0.0",
|
||||
"fresh-require": "1.0.3",
|
||||
"front-matter": "^2.1.0",
|
||||
"gitbook-core": "^4.0.0-alpha.2",
|
||||
"gitbook-plugin-copy-code": "^4.0.0-alpha.2",
|
||||
"gitbook-plugin-headings": "^4.0.0-alpha.2",
|
||||
"gitbook-plugin-highlight": "^4.0.0-alpha.2",
|
||||
"gitbook-plugin-hints": "^4.0.0-alpha.2",
|
||||
"gitbook-plugin-livereload": "^4.0.0-alpha.2",
|
||||
"gitbook-plugin-lunr": "^4.0.0-alpha.2",
|
||||
"gitbook-plugin-search": "^4.0.0-alpha.2",
|
||||
"gitbook-plugin-sharing": "^4.0.0-alpha.2",
|
||||
"gitbook-plugin-theme-default": "^4.0.0-alpha.2",
|
||||
"gitbook-core": "^4.0.0-alpha.6",
|
||||
"gitbook-plugin-copy-code": "^4.0.0-alpha.6",
|
||||
"gitbook-plugin-headings": "^4.0.0-alpha.6",
|
||||
"gitbook-plugin-highlight": "^4.0.0-alpha.6",
|
||||
"gitbook-plugin-hints": "^4.0.0-alpha.6",
|
||||
"gitbook-plugin-livereload": "^4.0.0-alpha.6",
|
||||
"gitbook-plugin-lunr": "^4.0.0-alpha.6",
|
||||
"gitbook-plugin-search": "^4.0.0-alpha.6",
|
||||
"gitbook-plugin-sharing": "^4.0.0-alpha.6",
|
||||
"gitbook-plugin-theme-default": "^4.0.0-alpha.6",
|
||||
"github-slugid": "1.0.1",
|
||||
"graceful-fs": "4.1.4",
|
||||
"i18n-t": "1.0.1",
|
||||
@@ -43,7 +43,7 @@
|
||||
"json-schema-defaults": "0.1.1",
|
||||
"jsonschema": "1.1.0",
|
||||
"juice": "2.0.0",
|
||||
"markup-it": "3.3.0",
|
||||
"markup-it": "^3.4.0",
|
||||
"mkdirp": "0.5.1",
|
||||
"moment": "2.13.0",
|
||||
"npm": "3.10.9",
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
const Book = require('../book');
|
||||
const File = require('../file');
|
||||
const Readme = require('../readme');
|
||||
const Summary = require('../summary');
|
||||
const Glossary = require('../glossary');
|
||||
|
||||
function createMockBook(def) {
|
||||
return new Book({
|
||||
readme: new Readme({
|
||||
file: new File({ path: def.readme })
|
||||
}),
|
||||
|
||||
summary: new Summary({
|
||||
file: new File({ path: def.summary })
|
||||
}),
|
||||
|
||||
glossary: new Glossary({
|
||||
file: new File({ path: def.glossary })
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
describe('Book', () => {
|
||||
describe('getDefaultExt', () => {
|
||||
it('must infer from README', () => {
|
||||
const book = createMockBook({
|
||||
readme: 'README.adoc',
|
||||
summary: 'SUMMARY.md',
|
||||
glossary: 'GLOSSARY.md'
|
||||
});
|
||||
|
||||
expect(book.getDefaultExt()).toBe('.adoc');
|
||||
});
|
||||
|
||||
it('must infer from SUMMARY', () => {
|
||||
const book = createMockBook({
|
||||
readme: '',
|
||||
summary: 'SUMMARY.adoc',
|
||||
glossary: 'GLOSSARY.md'
|
||||
});
|
||||
|
||||
expect(book.getDefaultExt()).toBe('.adoc');
|
||||
});
|
||||
|
||||
it('must infer from GLOSSARY', () => {
|
||||
const book = createMockBook({
|
||||
readme: '',
|
||||
summary: '',
|
||||
glossary: 'GLOSSARY.adoc'
|
||||
});
|
||||
|
||||
expect(book.getDefaultExt()).toBe('.adoc');
|
||||
});
|
||||
|
||||
it('must default to .md', () => {
|
||||
const book = createMockBook({
|
||||
readme: '',
|
||||
summary: '',
|
||||
glossary: ''
|
||||
});
|
||||
|
||||
expect(book.getDefaultExt()).toBe('.md');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -259,7 +259,7 @@ class Book extends Record(DEFAULTS) {
|
||||
const exts = clues.map((clue) => {
|
||||
const file = clue.getFile();
|
||||
if (file.exists()) {
|
||||
return file.getParser().getExtensions().first();
|
||||
return file.getParser().FILE_EXTENSIONS[0];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -2,9 +2,7 @@ const { Record } = require('immutable');
|
||||
const File = require('./file');
|
||||
|
||||
const DEFAULTS = {
|
||||
file: new File(),
|
||||
title: String(),
|
||||
description: String()
|
||||
file: new File()
|
||||
};
|
||||
|
||||
class Readme extends Record(DEFAULTS) {
|
||||
@@ -12,14 +10,6 @@ class Readme extends Record(DEFAULTS) {
|
||||
return this.get('file');
|
||||
}
|
||||
|
||||
getTitle() {
|
||||
return this.get('title');
|
||||
}
|
||||
|
||||
getDescription() {
|
||||
return this.get('description');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set file linked to the readme.
|
||||
* @param {File} file
|
||||
@@ -32,7 +22,6 @@ class Readme extends Record(DEFAULTS) {
|
||||
/**
|
||||
* Create a new readme
|
||||
*
|
||||
* @param {File} file
|
||||
* @param {Object} def
|
||||
* @return {Readme}
|
||||
*/
|
||||
@@ -40,8 +29,7 @@ class Readme extends Record(DEFAULTS) {
|
||||
def = def || {};
|
||||
|
||||
return new Readme({
|
||||
title: def.title || '',
|
||||
description: def.description || ''
|
||||
file: def.file || ''
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
const Summary = require('../../../models/summary');
|
||||
|
||||
describe('editArticleTitle', () => {
|
||||
const editArticleTitle = require('../editArticleTitle');
|
||||
const summary = Summary.createFromParts([
|
||||
{
|
||||
articles: [
|
||||
{
|
||||
title: 'My First Article',
|
||||
path: 'README.md'
|
||||
},
|
||||
{
|
||||
title: 'My Second Article',
|
||||
path: 'article.md'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'Test'
|
||||
}
|
||||
]);
|
||||
|
||||
it('should correctly set title of first article', () => {
|
||||
const newSummary = editArticleTitle(summary, '1.1', 'Hello World');
|
||||
const article = newSummary.getByLevel('1.1');
|
||||
|
||||
expect(article.getTitle()).toBe('Hello World');
|
||||
});
|
||||
|
||||
it('should correctly set title of second article', () => {
|
||||
const newSummary = editArticleTitle(summary, '1.2', 'Hello World');
|
||||
const article = newSummary.getByLevel('1.2');
|
||||
|
||||
expect(article.getTitle()).toBe('Hello World');
|
||||
});
|
||||
});
|
||||
+9
-3
@@ -16,7 +16,7 @@ nodes:
|
||||
- kind: inline
|
||||
type: link
|
||||
data:
|
||||
href: hello.md
|
||||
href: ''
|
||||
nodes:
|
||||
- kind: text
|
||||
text: Hello
|
||||
@@ -26,5 +26,11 @@ nodes:
|
||||
- kind: block
|
||||
type: unstyled
|
||||
nodes:
|
||||
- kind: text
|
||||
text: World
|
||||
- kind: inline
|
||||
type: link
|
||||
data:
|
||||
href: ''
|
||||
nodes:
|
||||
- kind: text
|
||||
text: World
|
||||
|
||||
+14
-4
@@ -13,13 +13,23 @@ nodes:
|
||||
- kind: block
|
||||
type: unstyled
|
||||
nodes:
|
||||
- kind: text
|
||||
text: Hello
|
||||
- kind: inline
|
||||
type: link
|
||||
data:
|
||||
href: 'hello.md'
|
||||
nodes:
|
||||
- kind: text
|
||||
text: 'Hello'
|
||||
- kind: block
|
||||
type: list_item
|
||||
nodes:
|
||||
- kind: block
|
||||
type: unstyled
|
||||
nodes:
|
||||
- kind: text
|
||||
text: World
|
||||
- kind: inline
|
||||
type: link
|
||||
data:
|
||||
href: ''
|
||||
nodes:
|
||||
- kind: text
|
||||
text: 'World'
|
||||
@@ -20,8 +20,13 @@ nodes:
|
||||
- kind: block
|
||||
type: unstyled
|
||||
nodes:
|
||||
- kind: text
|
||||
text: '1.1'
|
||||
- kind: inline
|
||||
type: link
|
||||
data:
|
||||
href: ''
|
||||
nodes:
|
||||
- kind: text
|
||||
text: '1.1'
|
||||
- kind: block
|
||||
type: unordered_list
|
||||
nodes:
|
||||
@@ -31,24 +36,39 @@ nodes:
|
||||
- kind: block
|
||||
type: unstyled
|
||||
nodes:
|
||||
- kind: text
|
||||
text: '1.1.1'
|
||||
- kind: inline
|
||||
type: link
|
||||
data:
|
||||
href: ''
|
||||
nodes:
|
||||
- kind: text
|
||||
text: '1.1.1'
|
||||
- kind: block
|
||||
type: list_item
|
||||
nodes:
|
||||
- kind: block
|
||||
type: unstyled
|
||||
nodes:
|
||||
- kind: text
|
||||
text: '1.1.2'
|
||||
- kind: inline
|
||||
type: link
|
||||
data:
|
||||
href: ''
|
||||
nodes:
|
||||
- kind: text
|
||||
text: '1.1.2'
|
||||
- kind: block
|
||||
type: list_item
|
||||
nodes:
|
||||
- kind: block
|
||||
type: unstyled
|
||||
nodes:
|
||||
- kind: text
|
||||
text: '1.2'
|
||||
- kind: inline
|
||||
type: link
|
||||
data:
|
||||
href: ''
|
||||
nodes:
|
||||
- kind: text
|
||||
text: '1.2'
|
||||
- kind: block
|
||||
type: unordered_list
|
||||
nodes:
|
||||
@@ -58,16 +78,26 @@ nodes:
|
||||
- kind: block
|
||||
type: unstyled
|
||||
nodes:
|
||||
- kind: text
|
||||
text: '1.2.1'
|
||||
- kind: inline
|
||||
type: link
|
||||
data:
|
||||
href: ''
|
||||
nodes:
|
||||
- kind: text
|
||||
text: '1.2.1'
|
||||
- kind: block
|
||||
type: list_item
|
||||
nodes:
|
||||
- kind: block
|
||||
type: unstyled
|
||||
nodes:
|
||||
- kind: text
|
||||
text: '1.2.2'
|
||||
- kind: inline
|
||||
type: link
|
||||
data:
|
||||
href: ''
|
||||
nodes:
|
||||
- kind: text
|
||||
text: '1.2.2'
|
||||
|
||||
- kind: block
|
||||
type: header_two
|
||||
@@ -84,8 +114,13 @@ nodes:
|
||||
- kind: block
|
||||
type: unstyled
|
||||
nodes:
|
||||
- kind: text
|
||||
text: '2.1'
|
||||
- kind: inline
|
||||
type: link
|
||||
data:
|
||||
href: ''
|
||||
nodes:
|
||||
- kind: text
|
||||
text: '2.1'
|
||||
- kind: block
|
||||
type: unordered_list
|
||||
nodes:
|
||||
@@ -95,8 +130,13 @@ nodes:
|
||||
- kind: block
|
||||
type: unstyled
|
||||
nodes:
|
||||
- kind: text
|
||||
text: '2.1.1'
|
||||
- kind: inline
|
||||
type: link
|
||||
data:
|
||||
href: ''
|
||||
nodes:
|
||||
- kind: text
|
||||
text: '2.1.1'
|
||||
- kind: block
|
||||
type: unordered_list
|
||||
nodes:
|
||||
@@ -106,8 +146,13 @@ nodes:
|
||||
- kind: block
|
||||
type: unstyled
|
||||
nodes:
|
||||
- kind: text
|
||||
text: '2.1.1.1'
|
||||
- kind: inline
|
||||
type: link
|
||||
data:
|
||||
href: ''
|
||||
nodes:
|
||||
- kind: text
|
||||
text: '2.1.1.1'
|
||||
- kind: block
|
||||
type: unordered_list
|
||||
nodes:
|
||||
@@ -117,5 +162,10 @@ nodes:
|
||||
- kind: block
|
||||
type: unstyled
|
||||
nodes:
|
||||
- kind: text
|
||||
text: '2.1.1.1.1'
|
||||
- kind: inline
|
||||
type: link
|
||||
data:
|
||||
href: ''
|
||||
nodes:
|
||||
- kind: text
|
||||
text: '2.1.1.1.1'
|
||||
|
||||
@@ -13,13 +13,23 @@ nodes:
|
||||
- kind: block
|
||||
type: unstyled
|
||||
nodes:
|
||||
- kind: text
|
||||
text: ''
|
||||
- kind: inline
|
||||
type: link
|
||||
data:
|
||||
href: ''
|
||||
nodes:
|
||||
- kind: text
|
||||
text: ''
|
||||
- kind: block
|
||||
type: list_item
|
||||
nodes:
|
||||
- kind: block
|
||||
type: unstyled
|
||||
nodes:
|
||||
- kind: text
|
||||
text: ''
|
||||
- kind: inline
|
||||
type: link
|
||||
data:
|
||||
href: ''
|
||||
nodes:
|
||||
- kind: text
|
||||
text: ''
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
nodes:
|
||||
- kind: block
|
||||
type: header_one
|
||||
nodes:
|
||||
- kind: text
|
||||
text: Summary
|
||||
|
||||
- kind: block
|
||||
type: header_two
|
||||
nodes:
|
||||
- kind: text
|
||||
text: 'Part 1'
|
||||
- kind: block
|
||||
type: unordered_list
|
||||
nodes:
|
||||
- kind: block
|
||||
type: list_item
|
||||
nodes:
|
||||
- kind: block
|
||||
type: unstyled
|
||||
nodes:
|
||||
- kind: inline
|
||||
type: link
|
||||
data:
|
||||
href: ''
|
||||
nodes:
|
||||
- kind: text
|
||||
text: 'Article 1'
|
||||
|
||||
- kind: block
|
||||
type: header_two
|
||||
nodes:
|
||||
- kind: text
|
||||
text: 'Empty part 1'
|
||||
|
||||
- kind: block
|
||||
type: header_two
|
||||
nodes:
|
||||
- kind: text
|
||||
text: 'Empty part 2'
|
||||
|
||||
- kind: block
|
||||
type: header_two
|
||||
nodes:
|
||||
- kind: text
|
||||
text: 'Part 2'
|
||||
- kind: block
|
||||
type: unordered_list
|
||||
nodes:
|
||||
- kind: block
|
||||
type: list_item
|
||||
nodes:
|
||||
- kind: block
|
||||
type: unstyled
|
||||
nodes:
|
||||
- kind: inline
|
||||
type: link
|
||||
data:
|
||||
href: ''
|
||||
nodes:
|
||||
- kind: text
|
||||
text: 'Article 2'
|
||||
|
||||
- kind: block
|
||||
type: header_two
|
||||
nodes:
|
||||
- kind: text
|
||||
text: 'Empty part 3'
|
||||
@@ -13,8 +13,13 @@ nodes:
|
||||
- kind: block
|
||||
type: unstyled
|
||||
nodes:
|
||||
- kind: text
|
||||
text: Hello
|
||||
- kind: inline
|
||||
type: link
|
||||
data:
|
||||
href: ''
|
||||
nodes:
|
||||
- kind: text
|
||||
text: Hello
|
||||
|
||||
- kind: block
|
||||
type: header_two
|
||||
@@ -30,8 +35,13 @@ nodes:
|
||||
- kind: block
|
||||
type: unstyled
|
||||
nodes:
|
||||
- kind: text
|
||||
text: World
|
||||
- kind: inline
|
||||
type: link
|
||||
data:
|
||||
href: ''
|
||||
nodes:
|
||||
- kind: text
|
||||
text: World
|
||||
|
||||
- kind: block
|
||||
type: hr
|
||||
@@ -47,5 +57,10 @@ nodes:
|
||||
- kind: block
|
||||
type: unstyled
|
||||
nodes:
|
||||
- kind: text
|
||||
text: Yeah
|
||||
- kind: inline
|
||||
type: link
|
||||
data:
|
||||
href: ''
|
||||
nodes:
|
||||
- kind: text
|
||||
text: Yeah
|
||||
|
||||
@@ -21,7 +21,7 @@ function expectDocument(documentPath, parts) {
|
||||
|
||||
describe('summaryToDocument', () => {
|
||||
it('should convert unlinked articles', () => {
|
||||
expectDocument('ul.yaml', [
|
||||
expectDocument('article-no-link.yaml', [
|
||||
{
|
||||
title: '',
|
||||
articles: [
|
||||
@@ -39,7 +39,7 @@ describe('summaryToDocument', () => {
|
||||
});
|
||||
|
||||
it('should convert articles with links', () => {
|
||||
expectDocument('ul-with-link.yaml', [
|
||||
expectDocument('article-with-link.yaml', [
|
||||
{
|
||||
title: '',
|
||||
articles: [
|
||||
@@ -106,6 +106,39 @@ describe('summaryToDocument', () => {
|
||||
]);
|
||||
});
|
||||
|
||||
it('should convert empty parts', () => {
|
||||
expectDocument('empty-part.yaml', [
|
||||
{
|
||||
title: 'Part 1',
|
||||
articles: [
|
||||
{
|
||||
title: 'Article 1'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'Empty part 1',
|
||||
articles: []
|
||||
},
|
||||
{
|
||||
title: 'Empty part 2',
|
||||
articles: []
|
||||
},
|
||||
{
|
||||
title: 'Part 2',
|
||||
articles: [
|
||||
{
|
||||
title: 'Article 2'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'Empty part 3',
|
||||
articles: []
|
||||
}
|
||||
]);
|
||||
});
|
||||
|
||||
it('should convert a deep summary', () => {
|
||||
expectDocument('deep.yaml', [
|
||||
{
|
||||
|
||||
@@ -8,24 +8,20 @@ const { BLOCKS, INLINES } = require('markup-it');
|
||||
*/
|
||||
function articleToBlock(article) {
|
||||
const { title, ref, articles } = article;
|
||||
const text = Text.createFromString(title);
|
||||
|
||||
// Text or link ?
|
||||
const innerNode = ref ? Inline.create({
|
||||
type: INLINES.LINK,
|
||||
nodes: [
|
||||
text
|
||||
],
|
||||
data: {
|
||||
href: ref
|
||||
}
|
||||
}) : text;
|
||||
|
||||
const nodes = [
|
||||
Block.create({
|
||||
type: BLOCKS.TEXT,
|
||||
nodes: [
|
||||
innerNode
|
||||
Inline.create({
|
||||
type: INLINES.LINK,
|
||||
nodes: [
|
||||
Text.createFromString(title)
|
||||
],
|
||||
data: {
|
||||
href: ref || ''
|
||||
}
|
||||
})
|
||||
]
|
||||
})
|
||||
];
|
||||
@@ -85,7 +81,9 @@ function summaryToDocument(summary) {
|
||||
}));
|
||||
}
|
||||
|
||||
nodes.push(articlesToBlock(articles));
|
||||
if (!articles.isEmpty()) {
|
||||
nodes.push(articlesToBlock(articles));
|
||||
}
|
||||
});
|
||||
|
||||
return Document.create({ nodes });
|
||||
|
||||
@@ -21,5 +21,11 @@ nodes:
|
||||
- kind: block
|
||||
type: unstyled
|
||||
nodes:
|
||||
- kind: text
|
||||
text: ''
|
||||
- kind: inline
|
||||
type: link
|
||||
data:
|
||||
href: 'art1.md'
|
||||
nodes:
|
||||
- kind: text
|
||||
text: '' # No title so ignored
|
||||
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
nodes:
|
||||
- kind: block
|
||||
type: header_one
|
||||
nodes:
|
||||
- kind: text
|
||||
text: Summary
|
||||
|
||||
- kind: block
|
||||
type: header_two
|
||||
nodes:
|
||||
- kind: text
|
||||
text: 'Part 1'
|
||||
- kind: block
|
||||
type: unordered_list
|
||||
nodes:
|
||||
- kind: block
|
||||
type: list_item
|
||||
nodes:
|
||||
- kind: block
|
||||
type: unstyled
|
||||
nodes:
|
||||
- kind: text
|
||||
text: 'Article 1'
|
||||
|
||||
- kind: block
|
||||
type: header_two
|
||||
nodes:
|
||||
- kind: text
|
||||
text: 'Empty part 1'
|
||||
|
||||
- kind: block
|
||||
type: header_two
|
||||
nodes:
|
||||
- kind: text
|
||||
text: 'Empty part 2'
|
||||
|
||||
- kind: block
|
||||
type: header_two
|
||||
nodes:
|
||||
- kind: text
|
||||
text: 'Part 2'
|
||||
- kind: block
|
||||
type: unordered_list
|
||||
nodes:
|
||||
- kind: block
|
||||
type: list_item
|
||||
nodes:
|
||||
- kind: block
|
||||
type: unstyled
|
||||
nodes:
|
||||
- kind: text
|
||||
text: 'Article 2'
|
||||
|
||||
- kind: block
|
||||
type: header_two
|
||||
nodes:
|
||||
- kind: text
|
||||
text: 'Empty part 3'
|
||||
@@ -0,0 +1,115 @@
|
||||
nodes:
|
||||
- kind: block
|
||||
type: header_one
|
||||
nodes:
|
||||
- kind: text
|
||||
text: Summary
|
||||
- kind: block
|
||||
type: unordered_list
|
||||
nodes:
|
||||
- kind: block
|
||||
type: list_item
|
||||
nodes:
|
||||
- kind: block
|
||||
type: unstyled
|
||||
nodes:
|
||||
- kind: text
|
||||
text: 'ignored text'
|
||||
- kind: inline
|
||||
type: link
|
||||
data:
|
||||
href: 'art1.md'
|
||||
nodes:
|
||||
- kind: text
|
||||
text: 'Article 1'
|
||||
- kind: text
|
||||
text: ''
|
||||
|
||||
- kind: block
|
||||
type: list_item
|
||||
nodes:
|
||||
- kind: block
|
||||
type: paragraph
|
||||
nodes:
|
||||
- kind: text
|
||||
text: 'Article 2'
|
||||
- kind: block
|
||||
type: paragraph
|
||||
nodes:
|
||||
- kind: text
|
||||
text: 'Ignored'
|
||||
|
||||
- kind: block
|
||||
type: list_item
|
||||
nodes:
|
||||
- kind: block
|
||||
type: paragraph
|
||||
nodes:
|
||||
- kind: text
|
||||
text: 'First paragraph. There is a link further, so should be ignored'
|
||||
|
||||
# Sublist, that is not after a link. Should be ignored
|
||||
- kind: block
|
||||
type: unordered_list
|
||||
nodes:
|
||||
- kind: block
|
||||
type: list_item
|
||||
nodes:
|
||||
- kind: block
|
||||
type: unstyled
|
||||
nodes:
|
||||
- kind: inline
|
||||
type: link
|
||||
data:
|
||||
href: 'ignored.md'
|
||||
nodes:
|
||||
- kind: text
|
||||
text: 'Ignored'
|
||||
|
||||
- kind: block
|
||||
type: paragraph
|
||||
nodes:
|
||||
- kind: inline
|
||||
type: link
|
||||
data:
|
||||
href: 'art3.md'
|
||||
nodes:
|
||||
- kind: text
|
||||
text: 'Article 3'
|
||||
|
||||
# First sublist that is after the link. Parsed as subarticles
|
||||
- kind: block
|
||||
type: unordered_list
|
||||
nodes:
|
||||
- kind: block
|
||||
type: list_item
|
||||
nodes:
|
||||
- kind: block
|
||||
type: unstyled
|
||||
nodes:
|
||||
- kind: inline
|
||||
type: link
|
||||
data:
|
||||
href: 'art2.1.md'
|
||||
nodes:
|
||||
- kind: text
|
||||
text: 'Article 2.1'
|
||||
|
||||
# Ignored because we already parsed the previous list
|
||||
- kind: block
|
||||
type: unordered_list
|
||||
nodes:
|
||||
- kind: block
|
||||
type: list_item
|
||||
nodes:
|
||||
- kind: block
|
||||
type: unstyled
|
||||
nodes:
|
||||
- kind: inline
|
||||
type: link
|
||||
data:
|
||||
href: 'ignored'
|
||||
nodes:
|
||||
- kind: text
|
||||
text: 'ignored'
|
||||
|
||||
@@ -16,8 +16,6 @@ describe('parseReadme', () => {
|
||||
const file = readme.getFile();
|
||||
|
||||
expect(file.exists()).toBeTruthy();
|
||||
expect(readme.title).toBe('Hello');
|
||||
expect(readme.description).toBe('And here is the description.');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
const expect = require('expect');
|
||||
const readDocument = require('./utils/readDocument');
|
||||
const readmeFromDocument = require('../readmeFromDocument');
|
||||
|
||||
function readReadme(filename) {
|
||||
const document = readDocument(filename);
|
||||
return readmeFromDocument(document);
|
||||
}
|
||||
|
||||
describe('readmeFromDocument', () => {
|
||||
|
||||
it('should parse only title', () => {
|
||||
const readme = readReadme('readme/only-title.yaml');
|
||||
expect(readme.title).toBe('Hello World');
|
||||
expect(readme.description).toBe('');
|
||||
});
|
||||
|
||||
it('should parse title and description', () => {
|
||||
const readme = readReadme('readme/normal.yaml');
|
||||
expect(readme.title).toBe('Hello World');
|
||||
expect(readme.description).toBe('This is a description');
|
||||
});
|
||||
|
||||
});
|
||||
@@ -92,22 +92,48 @@ describe('summaryFromDocument', () => {
|
||||
]);
|
||||
});
|
||||
|
||||
it('should parse empty items', () => {
|
||||
it('should ignore empty items', () => {
|
||||
const summary = readSummary('summary/empty-items.yaml');
|
||||
|
||||
expectParts(summary, [
|
||||
{
|
||||
title: '',
|
||||
articles: []
|
||||
}
|
||||
]);
|
||||
});
|
||||
|
||||
it('should parse empty parts', () => {
|
||||
const summary = readSummary('summary/empty-part.yaml');
|
||||
|
||||
expectParts(summary, [
|
||||
{
|
||||
title: 'Part 1',
|
||||
articles: [
|
||||
{
|
||||
title: '',
|
||||
ref: ''
|
||||
},
|
||||
{
|
||||
title: '',
|
||||
ref: ''
|
||||
title: 'Article 1'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'Empty part 1',
|
||||
articles: []
|
||||
},
|
||||
{
|
||||
title: 'Empty part 2',
|
||||
articles: []
|
||||
},
|
||||
{
|
||||
title: 'Part 2',
|
||||
articles: [
|
||||
{
|
||||
title: 'Article 2'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
title: 'Empty part 3',
|
||||
articles: []
|
||||
}
|
||||
]);
|
||||
});
|
||||
@@ -175,4 +201,36 @@ describe('summaryFromDocument', () => {
|
||||
expectParts(summary, [
|
||||
]);
|
||||
});
|
||||
|
||||
it('should be flexible', () => {
|
||||
const summary = readSummary('summary/flexible.yaml');
|
||||
|
||||
expectParts(summary, [
|
||||
{
|
||||
title: '',
|
||||
articles: [
|
||||
{
|
||||
title: 'Article 1',
|
||||
ref: 'art1.md'
|
||||
},
|
||||
{
|
||||
title: 'Article 2',
|
||||
articles: []
|
||||
},
|
||||
{
|
||||
title: 'Article 3',
|
||||
ref: 'art3.md',
|
||||
articles: [
|
||||
{
|
||||
title: 'Article 2.1',
|
||||
ref: 'art2.1.md',
|
||||
articles: []
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
const lookupStructureFile = require('./lookupStructureFile');
|
||||
const readmeFromDocument = require('./readmeFromDocument');
|
||||
const Readme = require('../models/readme');
|
||||
const error = require('../utils/error');
|
||||
|
||||
/**
|
||||
@@ -10,7 +10,6 @@ const error = require('../utils/error');
|
||||
*/
|
||||
function parseReadme(book) {
|
||||
const { logger } = book;
|
||||
const fs = book.getContentFS();
|
||||
|
||||
return lookupStructureFile(book, 'readme')
|
||||
.then((file) => {
|
||||
@@ -19,12 +18,8 @@ function parseReadme(book) {
|
||||
}
|
||||
|
||||
logger.debug.ln(`readme found at ${file.path}`);
|
||||
return file.parse(fs)
|
||||
.then((document) => {
|
||||
let readme = readmeFromDocument(document);
|
||||
readme = readme.setFile(file);
|
||||
return book.set('readme', readme);
|
||||
});
|
||||
|
||||
return book.set('readme', Readme.create({ file }));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
const { BLOCKS } = require('markup-it');
|
||||
const Readme = require('../models/readme');
|
||||
|
||||
/**
|
||||
* Parse a readme from a document.
|
||||
* @param {Document} document
|
||||
* @return {Readme} readme
|
||||
*/
|
||||
function readmeFromDocument(document) {
|
||||
const { nodes } = document;
|
||||
|
||||
const first = nodes.first();
|
||||
const second = nodes.get(1);
|
||||
|
||||
return Readme.create({
|
||||
title: first && first.type == BLOCKS.HEADING_1 ? first.text : '',
|
||||
description: second && second.type == BLOCKS.PARAGRAPH ? second.text : ''
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = readmeFromDocument;
|
||||
@@ -9,17 +9,48 @@ const isLink = node => node.type === INLINES.LINK;
|
||||
/**
|
||||
* Create a summary article from a list item.
|
||||
* @param {Block} item
|
||||
* @return {SummaryArticleLike} article
|
||||
* @return {SummaryArticleLike | Null} article
|
||||
*/
|
||||
function createArticleFromItem(item) {
|
||||
const { nodes } = item;
|
||||
|
||||
const titleParent = nodes.first();
|
||||
const list = nodes.skip(1).find(isList);
|
||||
// Find the link that represents the article's title
|
||||
const linkParent = nodes
|
||||
.filterNot(isList)
|
||||
.find(node => node.findDescendant(isLink));
|
||||
|
||||
// Or find text that could act as title
|
||||
const textParent = nodes.filterNot(node => isList(node) || node.isEmpty).first();
|
||||
|
||||
let title, ref, parent;
|
||||
if (linkParent) {
|
||||
const link = linkParent.findDescendant(isLink);
|
||||
|
||||
if (!link.isEmpty) {
|
||||
parent = linkParent;
|
||||
title = link.text;
|
||||
ref = link.data.get('href');
|
||||
}
|
||||
}
|
||||
|
||||
if (!parent) {
|
||||
// Could not find a proper link
|
||||
|
||||
if (textParent) {
|
||||
parent = textParent;
|
||||
title = textParent.text;
|
||||
ref = null;
|
||||
} else {
|
||||
// This item has no proper title or link
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
const list = nodes
|
||||
// Skip until after the article's title or link
|
||||
.skipUntil(node => node === parent).skip(1)
|
||||
.find(isList);
|
||||
const articles = list ? listArticles(list) : [];
|
||||
const title = titleParent.text;
|
||||
const link = titleParent.findDescendant(isLink);
|
||||
const ref = link ? link.data.get('href') : null;
|
||||
|
||||
return {
|
||||
title,
|
||||
@@ -35,7 +66,9 @@ function createArticleFromItem(item) {
|
||||
*/
|
||||
function listArticles(list) {
|
||||
const { nodes } = list;
|
||||
return nodes.map(item => createArticleFromItem(item));
|
||||
return nodes
|
||||
.map(item => createArticleFromItem(item))
|
||||
.filter(article => Boolean(article));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -46,7 +79,9 @@ function listArticles(list) {
|
||||
function listParts(document) {
|
||||
const { nodes } = document;
|
||||
const parts = [];
|
||||
let title = '';
|
||||
|
||||
// Keep a reference to a part, waiting for its articles
|
||||
let pendingPart;
|
||||
|
||||
nodes.forEach((node) => {
|
||||
const isHeading = (
|
||||
@@ -55,20 +90,36 @@ function listParts(document) {
|
||||
);
|
||||
|
||||
if (isHeading) {
|
||||
title = node.text;
|
||||
if (pendingPart) {
|
||||
// The previous was empty
|
||||
parts.push(pendingPart);
|
||||
}
|
||||
pendingPart = {
|
||||
title: node.text
|
||||
};
|
||||
}
|
||||
|
||||
if (isList(node)) {
|
||||
const articles = listArticles(node);
|
||||
parts.push({
|
||||
title,
|
||||
articles
|
||||
});
|
||||
|
||||
title = '';
|
||||
if (pendingPart) {
|
||||
pendingPart.articles = articles;
|
||||
parts.push(pendingPart);
|
||||
pendingPart = undefined;
|
||||
} else {
|
||||
parts.push({
|
||||
title: '',
|
||||
articles
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (pendingPart) {
|
||||
// The last one was empty
|
||||
parts.push(pendingPart);
|
||||
}
|
||||
|
||||
return List(parts);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
#! /usr/bin/env node
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const lernaConfig = require('../lerna.json');
|
||||
|
||||
// List all the packages
|
||||
const PACKAGES_DIR = path.resolve(__dirname, '../packages');
|
||||
const packages = fs.readdirSync(PACKAGES_DIR);
|
||||
|
||||
function updateDependencies(dependencies) {
|
||||
if (!dependencies) {
|
||||
return;
|
||||
}
|
||||
|
||||
Object.keys(dependencies).map((key) => {
|
||||
if (!packages.includes(key)) {
|
||||
return;
|
||||
}
|
||||
|
||||
dependencies[key] = lernaConfig.version;
|
||||
});
|
||||
}
|
||||
|
||||
packages.forEach((name) => {
|
||||
// Avoid .DS_Store
|
||||
if (name[0] === '.') {
|
||||
return;
|
||||
}
|
||||
|
||||
const pkgPath = path.resolve(PACKAGES_DIR, name, 'package.json');
|
||||
const pkg = require(pkgPath);
|
||||
|
||||
pkg.version = lernaConfig.version;
|
||||
updateDependencies(pkg.dependencies);
|
||||
updateDependencies(pkg.devDependencies);
|
||||
|
||||
const json = JSON.stringify(pkg, null, 2);
|
||||
|
||||
fs.writeFileSync(pkgPath, `${json}\n`, 'utf-8');
|
||||
});
|
||||
Executable
+26
@@ -0,0 +1,26 @@
|
||||
#!/bin/bash
|
||||
|
||||
defaultTag=latest
|
||||
|
||||
echo ""
|
||||
echo "You are trying to publish a new version of GitBook"
|
||||
echo "⚠️ Currently, because of NPM access, this script can only be run by Samy"
|
||||
echo ""
|
||||
echo "Steps:"
|
||||
echo " 1. Enter the new version"
|
||||
echo " 2. Packages will be published on NPM"
|
||||
echo " 3. Commit the changes with message 'Bump version to X 🚀 '"
|
||||
echo " 4. Tag the commit"
|
||||
echo " 5. Push"
|
||||
echo ""
|
||||
|
||||
read -p "Version: " version
|
||||
read -p "NPM Tag (latest or pre) [$defaultTag]:" tag
|
||||
tag=${tag:-$defaultTag}
|
||||
echo ""
|
||||
|
||||
echo "You are going to publish version ${version} on NPM (tagged as ${tag})"
|
||||
echo "Press [ENTER] tp confirm"
|
||||
read
|
||||
|
||||
lerna publish --skip-git --repo-version ${version} --npm-tag ${tag} --force-publish=*
|
||||
Reference in New Issue
Block a user