Compare commits

...

14 Commits

Author SHA1 Message Date
Aaron O'Mullan 6b76032bb1 Bump version to 1.5.0 2014-12-17 17:08:09 +01:00
Aaron O'Mullan 85b09eda56 Add 1.4.2's changes 2014-12-17 17:07:10 +01:00
Aaron O'Mullan c4be78a81f Merge pull request #506 from Nijikokun/feature/clarity-midnight
Clarity: Midnight Theme (Night)
2014-12-16 18:53:09 +01:00
Aaron O'Mullan e7309f71d2 Merge pull request #530 from GitbookIO/fix/cli-error-handling
Robust CLI error handling
2014-12-16 17:46:01 +01:00
Aaron O'Mullan 6c979c9419 Robust CLI error handling
Fixes #528, fixes #524, fixes #518
2014-12-16 16:05:50 +01:00
Aaron O'Mullan 7fd7732345 Bump version to 1.4.2 2014-12-10 23:27:01 +01:00
Aaron O'Mullan 960ef4d945 Fix descriptor and me leak with bad write queues
Node.js for some reason queues up writes from fs.writeFile causing
memory and descriptor leaks, preventing building large books. This is
now fixed

Fixes #336, fixes #454
2014-12-10 16:32:49 +01:00
Aaron O'Mullan 92523fb4b5 Force process.exit at end of build 2014-12-09 17:31:23 +01:00
Samy Pessé 66bb46df22 Merge pull request #516 from jr0cket/patch-1
Add gitbook init command to "how to use" section
2014-12-08 00:46:04 +01:00
John Stevenson 0454710d3b Add gitbook init command to "how to use" section
Highlight that Gitbook can generate the files and directories for a book from its SUMMARY.md file.
2014-12-07 23:44:41 +00:00
Samy Pessé c9a31cc987 Add option isbn for books 2014-12-03 23:19:47 +01:00
Samy Pessé f03c316274 Bump version to 1.4.1 2014-11-30 17:01:47 +01:00
Samy Pessé 001a4f91be Fix command 'install' without arguments 2014-11-30 17:00:12 +01:00
Nijiko Yonskai c52aecdbd5 Initial release 2014-11-22 20:37:06 -08:00
14 changed files with 269 additions and 97 deletions
+10
View File
@@ -1,5 +1,15 @@
# Release notes
## 1.5.0
- Fix `serve` command, broken by `1.4.2`
- Add nicer `dark` theme :)
## 1.4.2
- Force `process.exit` after builds, to prevent (possibly) lingering plugins
## 1.4.1
- Fix command 'install' without arguments
## 1.4.0
- Add command `gitbook install` to install plugins from book.json
- `package.json` is no longer necessary
+7 -1
View File
@@ -16,6 +16,11 @@ GitBook can be installed from **NPM** using:
$ npm install gitbook -g
```
Create the directories and files for a book from its [SUMMARY.md](https://github.com/GitbookIO/gitbook#book-format) file using
```
$ gitbook init
```
You can serve a repository as a book using:
```
@@ -52,9 +57,10 @@ Here are the options that can be stored in this file:
// It's not advised this option in the book.json
"generator": "site",
// Book title and description (defaults are extracted from the README)
// Book metadats (somes are extracted from the README by default)
"title": null,
"description": null,
"isbn": null,
// For ebook format, the extension to use for generation (default is detected from output extension)
// "epub", "pdf", "mobi"
-7
View File
@@ -44,13 +44,6 @@ var makeBuildFunc = function(converter) {
.then(function(output) {
console.log("Successfully built!");
return output;
})
.fail(function(err) {
// Log error
utils.logError(err);
// Exit process with failure code
process.exit(-1);
});
};
};
+31 -31
View File
@@ -12,6 +12,7 @@ var initDir = require("../lib/generate/init");
var fs = require('../lib/generate/fs');
var utils = require('./utils');
var action = utils.action;
var build = require('./build');
var Server = require('./server');
var platform = require("./platform");
@@ -22,13 +23,13 @@ prog
build.command(prog.command('build [source_dir]'))
.description('Build a gitbook from a directory')
.action(build.folder);
.action(action(build.folder));
build.command(prog.command('serve [source_dir]'))
.description('Build then serve a gitbook from a directory')
.option('-p, --port <port>', 'Port for server to listen on', 4000)
.option('--no-watch', 'Disable restart with file watching')
.action(function(dir, options) {
.action(action(function(dir, options) {
var server = new Server();
// init livereload server
@@ -41,9 +42,11 @@ build.command(prog.command('serve [source_dir]'))
});
var generate = function() {
if (server.isRunning()) console.log("Stopping server");
if (server.isRunning()) {
console.log("Stopping server");
}
server.stop()
return server.stop()
.then(function() {
return build.folder(dir, _.extend(options || {}, {
defaultsPlugins: ["livereload"]
@@ -77,14 +80,18 @@ build.command(prog.command('serve [source_dir]'))
console.log('Press CTRL+C to quit ...');
console.log('')
generate();
});
return generate();
}));
build.commandEbook(prog.command('install [source_dir]'))
.description('Install plugins for a book')
.action(function(dir, options) {
.action(action(function(dir, options) {
dir = dir || process.cwd();
console.log("Install plugins in", dir);
genbook.config.read({
return genbook.config.read({
input: dir
})
.then(function(options) {
@@ -92,66 +99,59 @@ build.commandEbook(prog.command('install [source_dir]'))
})
.then(function() {
console.log("Successfully installed plugins!");
})
.fail(function(err) {
// Log error
utils.logError(err);
// Exit process with failure code
process.exit(-1);
});
});
}));
build.commandEbook(prog.command('pdf [source_dir]'))
.description('Build a gitbook as a PDF')
.action(function(dir, options) {
build.file(dir, _.extend(options, {
.action(action(function(dir, options) {
return build.file(dir, _.extend(options, {
extension: "pdf",
format: "ebook"
}));
});
}));
build.commandEbook(prog.command('epub [source_dir]'))
.description('Build a gitbook as a ePub book')
.action(function(dir, options) {
build.file(dir, _.extend(options, {
.action(action(function(dir, options) {
return build.file(dir, _.extend(options, {
extension: "epub",
format: "ebook"
}));
});
}));
build.commandEbook(prog.command('mobi [source_dir]'))
.description('Build a gitbook as a Mobi book')
.action(function(dir, options) {
build.file(dir, _.extend(options, {
.action(action(function(dir, options) {
return build.file(dir, _.extend(options, {
extension: "mobi",
format: "ebook"
}));
});
}));
prog
.command('init [source_dir]')
.description('Create files and folders based on contents of SUMMARY.md')
.action(function(dir) {
.action(action(function(dir) {
dir = dir || process.cwd();
return initDir(dir);
});
}));
prog
.command('publish [source_dir]')
.description('Publish content to the associated gitbook.io book')
.action(function(dir) {
.action(action(function(dir) {
dir = dir || process.cwd();
return platform.publish(dir);
});
}));
prog
.command('git:remote [source_dir] [book_id]')
.description('Adds a git remote to a book repository')
.action(function(dir, bookId) {
.action(action(function(dir, bookId) {
dir = dir || process.cwd();
return platform.remote(dir, bookId);
});
}));
// Parse and fallback to help if no args
if(_.isEmpty(prog.parse(process.argv).args) && process.argv.length === 2) {
+30
View File
@@ -30,6 +30,34 @@ function watch(dir) {
return d.promise;
}
// exit wraps a promise
// and forcefully quits the program when the promise is resolved
function exit(promise) {
promise
.then(function() {
// Prevent badly behaving plugins
// from making the process hang
process.exit(0);
}, function(err) {
// Log error
logError(err);
// Exit process with failure code
process.exit(-1);
});
}
// CLI action wrapper, calling exit when finished
function action(f) {
return function() {
// Call func and get optional promise
var p = f.apply(null, arguments);
// Exit process
return exit(Q(p));
}
}
function logError(err) {
var message = err.message || err;
if (process.env.DEBUG != null) message = err.stack || message;
@@ -60,6 +88,8 @@ function runGitCommand(command, args) {
// Exports
module.exports = {
exit: exit,
action: action,
watch: watch,
logError: logError,
gitCmd: runGitCommand
+2 -1
View File
@@ -17,9 +17,10 @@ var CONFIG = {
// Configuration file to use
"configFile": "book",
// Book title and description (defaults are extracted from the README)
// Book metadats (somes are extracted from the README by default)
"title": null,
"description": null,
"isbn": null,
// For ebook format, the extension to use for generation (default is detected from output extension)
// "epub", "pdf", "mobi"
+1
View File
@@ -30,6 +30,7 @@ Generator.prototype.finish = function() {
"--cover": that.options.cover,
"--title": that.options.title,
"--comments": that.options.description,
"--isbn": that.options.isbn,
"--authors": that.options.author,
"--publisher": "GitBook",
"--chapter": "descendant-or-self::*[contains(concat(' ', normalize-space(@class), ' '), ' book-chapter ')]",
+14 -1
View File
@@ -64,7 +64,20 @@ var getFiles = function(path) {
module.exports = {
list: getFiles,
readFile: Q.denodeify(fs.readFile),
writeFile: Q.denodeify(fs.writeFile),
//writeFile: Q.denodeify(fs.writeFile),
writeFile: function(filename, data, options) {
var d = Q.defer();
try {
fs.writeFileSync(filename, data, options)
} catch(err) {
d.reject(err);
}
d.resolve();
return d.promise;
},
mkdirp: Q.denodeify(fsExtra.mkdirp),
copy: Q.denodeify(fsExtra.copy),
remove: Q.denodeify(fsExtra.remove),
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "gitbook",
"version": "1.4.0",
"version": "1.5.0",
"homepage": "http://www.gitbook.io/",
"description": "Library and cmd utility to generate GitBooks",
"main": "lib/index.js",
File diff suppressed because one or more lines are too long
+84 -18
View File
@@ -16,57 +16,123 @@
}
.book.color-theme-1 .book-body .page-wrapper .page-inner section.normal {
color:@page-color-1;
color: @page-color-1;
a {
color: @page-link-color-1;
}
h1,
h2,
h3,
h4,
h5,
h6 {
color: @page-heading-color-1;
}
h1, h2 {
border-color: @page-heading-border-color-1;
}
h6 {
color: @page-h6-color-1;
}
hr {
background-color: @page-hr-color-1;
}
blockquote {
border-color: @page-blockquote-border-color-1;
}
pre, code {
background: #fdf6e3;
color: #657b83;
border-color: darken(#fdf6e3, 15%);
background: @page-pre-background-1;
color: @page-pre-color-1;
border-color: @page-pre-border-color-1;
@import "./highlight/sepia.less";
}
.highlight {
background-color: @page-highlight-background-1;
}
table {
th, td {
border-color: darken(#fdf6e3, 25%);
border-color: @page-table-header-border-color-1;
}
tr {
background: #fdf6e3;
color: inherit;
border-color: #444;
color: @page-table-row-color-1;
background-color: @page-table-row-background-1;
border-color: @page-table-row-border-color-1;
}
tr:nth-child(2n) {
background-color: darken(#fdf6e3, 5%);
background-color: @page-table-row-odd-background-1;
}
}
}
.book.color-theme-2 .book-body .page-wrapper .page-inner section.normal {
color:@page-color-2;
color: @page-color-2;
a {
color: @page-link-color-2;
}
h1,
h2,
h3,
h4,
h5,
h6 {
color: @page-heading-color-2;
}
h1, h2 {
border-color: @page-heading-border-color-2;
}
h6 {
color: @page-h6-color-2;
}
hr {
background-color: @page-hr-color-2;
}
blockquote {
border-color: @page-blockquote-border-color-2;
}
pre, code {
background: black;
color: #eaeaea;
border-color: #000;
color: @page-pre-color-2;
background: @page-pre-background-2;
border-color: @page-pre-border-color-2;
@import "./highlight/night.less";
}
.highlight {
background-color: @page-highlight-background-2;
}
table {
th, td {
border-color: #444;
border-color: @page-table-header-border-color-2;
}
tr {
background-color: black;
color: #eaeaea;
border-color: #444;
color: @page-table-row-color-2;
background-color: @page-table-row-background-2;
border-color: @page-table-row-border-color-2;
}
tr:nth-child(2n) {
background-color: #222;
background-color: @page-table-row-odd-background-2;
}
}
}
+7 -1
View File
@@ -11,7 +11,7 @@
width: @sidebar-width;
color: @sidebar-color;
background: @sidebar-background;
border-right: 1px solid @sidebar-border;
border-right: @sidebar-border-right;
.transition(left @sidebar-transition-duration ease);
@@ -152,6 +152,7 @@
.book-summary {
color: @sidebar-color-1;
background: @sidebar-background-1;
border-right: @sidebar-border-right-1;
.book-search {
background: @sidebar-search-background-1;
@@ -179,11 +180,13 @@
a, span {
color: @sidebar-link-color-1;
background: @sidebar-link-background-1;
font-weight: @sidebar-link-weight-1;
}
&.active > a, a:hover {
color: @sidebar-link-hover-color-1;
background: @sidebar-link-hover-background-1;
font-weight: @sidebar-link-hover-weight-1;
}
}
}
@@ -197,6 +200,7 @@
.book-summary {
color: @sidebar-color-2;
background: @sidebar-background-2;
border-right: @sidebar-border-right-2;
.book-search {
background: @sidebar-search-background-2;
@@ -224,11 +228,13 @@
a, span {
color: @sidebar-link-color-2;
background: @sidebar-link-background-2;
font-weight: @sidebar-link-weight-2;
}
&.active > a, a:hover {
color: @sidebar-link-hover-color-2;
background: @sidebar-link-hover-background-2;
font-weight: @sidebar-link-hover-weight-2;
}
}
}
+78 -35
View File
@@ -31,7 +31,7 @@
@sidebar-breakpoint: 600px;
@sidebar-color: hsl(207, 15%, 25%);
@sidebar-background: #fafafa;
@sidebar-border: @header-border;
@sidebar-border-right: 1px solid @header-border;
@sidebar-nested-padding: 20px;
@@ -40,7 +40,7 @@
@sidebar-search-input-background: transparent;
@sidebar-search-input-border-color: transparent;
@sidebar-divider-color: @sidebar-border;
@sidebar-divider-color: @header-border;
@sidebar-link-color: @sidebar-color;
@sidebar-link-background: transparent;
@@ -103,12 +103,12 @@
@FontPath: '@{staticPath}/fonts';
@fa-font-path: "@{FontPath}/fontawesome";
@s-font-size: 1.2rem;
@m-font-size: 1.4rem;
@l-font-size: 1.6rem;
@xl-font-size: 2.2rem;
@xxl-font-size: 4.0rem;
@default-font-size: @l-font-size;
@s-font-size: 1.2rem;
@m-font-size: 1.4rem;
@l-font-size: 1.6rem;
@xl-font-size: 2.2rem;
@xxl-font-size: 4.0rem;
@default-font-size: @l-font-size;
/*
,--------.,--.
@@ -123,9 +123,9 @@
@header-background-1: transparent;
@header-background-2: transparent;
@header-button-color-1: #AFA790;
@header-button-color-2: #7e888b;
@header-button-color-2: hsl(230, 17%, 28%);
@header-button-hover-color-1: #73553C;
@header-button-hover-color-2: #C9C9C9;
@header-button-hover-color-2: hsl(60, 100%, 98%);
@header-button-hover-background-1: none;
@header-button-hover-background-2: none;
@header-dropdown-background-1: @sidebar-background-1;
@@ -133,14 +133,16 @@
// Body
@body-background-1: #F3EACB;
@body-background-2: #1d1f21;
@body-background-2: hsl(228, 21%, 14%);
// Sidebar
@sidebar-transition-duration: 250ms;
@sidebar-color-1: #AFA790;
@sidebar-color-2: hsl(207, 15%, 80%);
@sidebar-color-2: hsl(226, 20%, 78%);
@sidebar-background-1: #111;
@sidebar-background-2: #111;
@sidebar-background-2: hsl(229, 20%, 22%);
@sidebar-border-right-1: @sidebar-border-right;
@sidebar-border-right-2: none;
@sidebar-search-background-1: transparent;
@sidebar-search-background-2: transparent;
@@ -148,51 +150,92 @@
@sidebar-search-input-border-color-2: transparent;
@sidebar-divider-color-1: @sidebar-divider-color;
@sidebar-divider-color-2: #1d1f21;
@sidebar-divider-color-2: hsl(230, 19%, 19%);
@sidebar-link-color-1: #877F6A;
@sidebar-link-color-2: hsl(207, 15%, 50%);
@sidebar-link-color-2: hsl(226, 22%, 80%);
@sidebar-link-background-1: transparent;
@sidebar-link-background-2: transparent;
@sidebar-link-weight-1: normal;
@sidebar-link-weight-2: 600;
@sidebar-link-hover-color-1: #704214;
@sidebar-link-hover-color-2: hsl(207, 100%, 50%);
@sidebar-link-hover-color-2: hsl(240, 5%, 96%);
@sidebar-link-hover-background-1: transparent;
@sidebar-link-hover-background-2: transparent;
@sidebar-link-hover-background-2: hsl(233, 19%, 18%);
@sidebar-link-hover-weight-1: normal;
@sidebar-link-hover-weight-2: 600;
@sidebar-icon-color-1: hsl(120, 60%, 50%);
@sidebar-icon-color-2: @sidebar-icon-color-1;
@sidebar-link-completed-1: @sidebar-link-color-1;
@sidebar-link-completed-2: @sidebar-link-color-2;
@sidebar-link-completed-2: hsl(227, 13%, 44%);
@sidebar-link-completed-weight-1: normal;
@sidebar-link-completed-weight-2: normal;
@sidebar-link-completed-weight-2: 600;
// Dropdown
@dropdown-divider-color-1: @sidebar-divider-color-1;
@dropdown-background-1: @sidebar-background-1;
@dropdown-button-color-1: @header-button-color-1;
@dropdown-border-color-1: @sidebar-divider-color-1;
@dropdown-button-hover-color-1: @header-button-hover-color-1;
@dropdown-divider-color-2: @sidebar-divider-color-2;
@dropdown-background-2: @sidebar-background-2;
@dropdown-button-color-2: @header-button-color-2;
@dropdown-border-color-1: @sidebar-divider-color-1;
@dropdown-border-color-2: @sidebar-divider-color-2;
@dropdown-button-hover-color-2: @header-button-hover-color-2;
@dropdown-background-1: @sidebar-background-1;
@dropdown-background-2: @sidebar-background-2;
@dropdown-button-color-1: @header-button-color-1;
@dropdown-button-color-2: hsl(228, 13%, 44%);
@dropdown-button-hover-color-1: @header-button-hover-color-1;
@dropdown-button-hover-color-2: hsl(240, 5%, 96%);
// Page
@page-color-1: #704214;
@page-color-2: #a4b1b1;
@page-background-1: #F3EACB;
@page-background-2: #1d1f21;
@page-color-1: #704214;
@page-color-2: hsl(214, 29%, 80%);
@page-background-1: @body-background-1;
@page-background-2: @body-background-2;
@bar-background-1: #F3EACB;
@bar-background-2: #1d1f21;
@page-link-color-1: inherit;
@page-link-color-2: hsl(193, 61%, 53%);
@page-heading-color-1: inherit;
@page-heading-color-2: hsl(60, 100%, 99%);
@page-heading-border-color-1: inherit;
@page-heading-border-color-2: hsl(230, 17%, 26%);
@page-h6-color-1: inherit;
@page-h6-color-2: hsl(230, 17%, 26%);
@page-hr-color-1: inherit;
@page-hr-color-2: hsl(230, 17%, 26%);
@page-blockquote-border-color-1: inherit;
@page-blockquote-border-color-2: hsl(230, 17%, 26%);
@page-pre-color-1: #657b83;
@page-pre-color-2: hsl(206, 43%, 73%);
@page-pre-background-1: #fdf6e3;
@page-pre-background-2: hsl(229, 20%, 22%);
@page-pre-border-color-1: darken(#fdf6e3, 15%);
@page-pre-border-color-2: hsl(229, 20%, 22%);
@page-highlight-background-1: inherit;
@page-highlight-background-2: hsl(233, 18%, 19%);
@page-table-header-border-color-1: darken(#fdf6e3, 25%);
@page-table-header-border-color-2: hsl(230, 17%, 28%);
@page-table-row-border-color-1: #444;
@page-table-row-border-color-2: hsl(230, 17%, 28%);
@page-table-row-color-1: inherit;
@page-table-row-color-2: hsl(216, 24%, 77%);
@page-table-row-background-1: #fdf6e3;
@page-table-row-background-2: hsl(229, 19%, 22%);
@page-table-row-odd-background-1: darken(#fdf6e3, 5%);
@page-table-row-odd-background-2: hsl(229, 17%, 25%);
// Page Bar
@bar-background-1: @page-background-1;
@bar-background-2: @page-background-2;
// Navigation
@navigation-color-1: @header-button-color-1;
@navigation-color-2: @header-button-color-2;
@navigation-color-2: hsl(224, 19%, 27%);
@navigation-hover-color-1: @header-button-hover-color-1;
@navigation-hover-color-2: @header-button-hover-color-2;
@navigation-hover-color-2: hsl(60, 100%, 98%);
// Basics of a navbar
@navbar-default-border-1: #d5d5d5;
+3
View File
@@ -15,6 +15,9 @@
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<link rel="apple-touch-icon-precomposed" sizes="152x152" href="{{ staticBase }}/images/apple-touch-icon-precomposed-152.png">
<link rel="shortcut icon" href="{{ staticBase }}/images/favicon.ico" type="image/x-icon">
{% if options.isbn %}
<meta name="identifier" content="{{ options.isbn }}" scheme="ISBN">
{% endif %}
{% block head %}{% endblock %}
{{ htmlSnippet("head:end")|default("") }}
</head>