mirror of
https://github.com/GitbookIO/gitbook.git
synced 2026-09-15 23:25:16 +00:00
Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6bce93d893 | |||
| c9db068227 | |||
| 8a6d36ac4d | |||
| 64622c5945 | |||
| 837813edb0 | |||
| 0d9d62f1a9 | |||
| f7e9abf984 | |||
| dd0579b60d | |||
| b5bb953e47 | |||
| ef4a8ea1b6 | |||
| 49cde96ee7 | |||
| 627be20e48 | |||
| e45bb84b02 | |||
| 4e8876c725 |
@@ -35,7 +35,6 @@ module.exports = function (grunt) {
|
||||
"lodash": 'vendors/lodash',
|
||||
"requireLib": 'vendors/require',
|
||||
"Mousetrap": 'vendors/mousetrap',
|
||||
"mixpanel": 'vendors/mixpanel',
|
||||
"lunr": path.join(__dirname, "node_modules/lunr/lunr")
|
||||
},
|
||||
shim: {
|
||||
@@ -48,9 +47,6 @@ module.exports = function (grunt) {
|
||||
'Mousetrap': {
|
||||
exports: 'Mousetrap'
|
||||
},
|
||||
'mixpanel': {
|
||||
exports: 'mixpanel'
|
||||
},
|
||||
'lunr': {
|
||||
exports: 'lunr'
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ GitBook
|
||||
|
||||
[](https://travis-ci.org/GitbookIO/gitbook)
|
||||
|
||||
GitBook is a command line tool (and Node.js library) for building beautiful programming books and exercises using GitHub/Git and Markdown. You can see an example: [Learn Javascript](http://gitbookio.github.io/javascript/).
|
||||
GitBook is a command line tool (and Node.js library) for building beautiful programming books and exercises using GitHub/Git and Markdown. You can see an example: [Learn Javascript](http://gitbookio.github.io/javascript/). An [editor](https://github.com/GitbookIO/editor) is available for Windows, Mac and Linux. You can follow [@GitBookIO](https://twitter.com/GitBookIO) on Twitter.
|
||||
|
||||

|
||||
|
||||
@@ -39,6 +39,8 @@ Options for commands `build` and `serve` are:
|
||||
--theme <path> Path to theme directory
|
||||
```
|
||||
|
||||
You can publish your books to our index by visiting [GitBook.io](http://www.gitbook.io)
|
||||
|
||||
## Output Formats
|
||||
|
||||
GitBook can generate your book in the following formats:
|
||||
|
||||
+30
-49
@@ -6,6 +6,12 @@ function clean(obj) {
|
||||
return obj && _.omit(obj, ['articles']);
|
||||
}
|
||||
|
||||
function flattenChapters(chapters) {
|
||||
return _.reduce(chapters, function(accu, chapter) {
|
||||
return accu.concat([clean(chapter)].concat(chapter.articles));
|
||||
}, []);
|
||||
}
|
||||
|
||||
// Returns from a summary a map of
|
||||
/*
|
||||
{
|
||||
@@ -20,62 +26,37 @@ function navigation(summary, files) {
|
||||
// Support single files as well as list
|
||||
files = _.isArray(files) ? files : (_.isString(files) ? [files] : null);
|
||||
|
||||
// Mapping of prev/next for a give path
|
||||
var mapping = {};
|
||||
|
||||
// Special README nav
|
||||
var README_NAV = {
|
||||
path: 'README.md',
|
||||
title: 'Introduction',
|
||||
};
|
||||
|
||||
// Walk the chapter/article tree and create navigation entires
|
||||
_.each(summary.chapters, function(chapter, idx, chapters) {
|
||||
// Skip if no path
|
||||
if(!chapter.path) return;
|
||||
|
||||
var currentChapter = clean(chapter);
|
||||
var prevChapter = (idx-1 < 0) ? README_NAV : chapters[idx-1];
|
||||
var nextChapter = (idx+1 >= chapters.length) ? null : chapters[idx+1];
|
||||
|
||||
var prev = (!prevChapter || _.isEmpty(prevChapter.articles)) ?
|
||||
prevChapter : _.last(prevChapter.articles);
|
||||
var next = (!chapter || _.isEmpty(chapter.articles)) ?
|
||||
nextChapter : _.first(chapter.articles);
|
||||
|
||||
// Add chapter mapping
|
||||
mapping[chapter.path] = {
|
||||
title: chapter.title,
|
||||
prev: clean(prev),
|
||||
next: clean(next),
|
||||
level: (idx+1).toString(),
|
||||
};
|
||||
|
||||
// Check a chapter's articles
|
||||
_.each(chapter.articles, function(article, _idx, articles) {
|
||||
// Skip if no path
|
||||
if(!article.path) return;
|
||||
|
||||
var prev = (_idx-1 < 0) ? currentChapter : clean(articles[_idx-1]);
|
||||
var next = (_idx+1 >= articles.length) ? nextChapter : clean(articles[_idx+1]);
|
||||
|
||||
mapping[article.path] = {
|
||||
title: article.title,
|
||||
prev: clean(prev),
|
||||
next: clean(next),
|
||||
level: [idx+1, _idx+1].join('.'),
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
// Hack for README.html
|
||||
mapping['README.md'] = {
|
||||
title: README_NAV.title,
|
||||
prev: null,
|
||||
next: clean(summary.chapters[0]),
|
||||
level: '0',
|
||||
};
|
||||
|
||||
// List of all navNodes
|
||||
var navNodes = [README_NAV].concat(flattenChapters(summary.chapters));
|
||||
var prevNodes = [null].concat(navNodes.slice(0, -1));
|
||||
var nextNodes = navNodes.slice(1).concat([null]);
|
||||
|
||||
// Mapping of prev/next for a give path
|
||||
var mapping = _.chain(_.zip(navNodes, prevNodes, nextNodes))
|
||||
.map(function(nodes) {
|
||||
var current = nodes[0], prev = nodes[1], next = nodes[2];
|
||||
|
||||
// Skip if no path
|
||||
if(!current.path) return null;
|
||||
|
||||
return [current.path, {
|
||||
title: current.title,
|
||||
prev: prev,
|
||||
next: next,
|
||||
level: current.level,
|
||||
}];
|
||||
})
|
||||
.filter()
|
||||
.object()
|
||||
.value();
|
||||
|
||||
// Filter for only files we want
|
||||
if(files) {
|
||||
return _.pick(mapping, files);
|
||||
|
||||
@@ -79,8 +79,14 @@ GitBookRenderer.prototype.image = function(href, title, text) {
|
||||
|
||||
// Relative image, rewrite it depending output
|
||||
if(!parsed.protocol && parsed.path && parsed.path[0] != '/' && o && o.dir && o.outdir) {
|
||||
var outdir = o.outdir.charAt(o.outdir.length - 1) === '/' ? o.outdir : o.outdir + '/';
|
||||
_href = url.resolve(outdir, [o.dir, href].join('/'));
|
||||
// o.dir: directory parent of the file currently in rendering process
|
||||
// o.outdir: directory parent from the html output
|
||||
|
||||
// Absolute file in source
|
||||
_href = path.join(o.dir, _href);
|
||||
|
||||
// make it relative to output
|
||||
_href = path.relative(o.outdir, _href);
|
||||
}
|
||||
|
||||
return GitBookRenderer.super_.prototype.image.call(this, _href, title, text);
|
||||
|
||||
+14
-3
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"name": "gitbook",
|
||||
"version": "0.2.2",
|
||||
"version": "0.2.3",
|
||||
"homepage": "http://www.gitbook.io/",
|
||||
"description": "Library and cmd utility to generate GitBooks",
|
||||
"main": "lib/index.js",
|
||||
"dependencies": {
|
||||
@@ -39,9 +40,19 @@
|
||||
"book",
|
||||
"gitbook"
|
||||
],
|
||||
"author": "Aaron O'Mullan <aaron.omullan@friendco.de>",
|
||||
"author": "FriendCode <contact@friendco.de>",
|
||||
"license": "Apache 2",
|
||||
"bugs": {
|
||||
"url": "https://github.com/GitbookIO/gitbook/issues"
|
||||
}
|
||||
},
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Aaron O'Mullan",
|
||||
"email": "aaron.omullan@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Samy Pessé",
|
||||
"email": "samypesse@gmail.com"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Vendored
+12
@@ -0,0 +1,12 @@
|
||||
# Images Test
|
||||
|
||||
This is a test for images path calculation. It supposed this fiel is in a syntax/ folder
|
||||
|
||||
### #
|
||||
|
||||
[](./preview.png)
|
||||
|
||||
### 2
|
||||
|
||||
[](./preview2.png)
|
||||
|
||||
+30
-4
@@ -36,10 +36,6 @@ describe('Page parsing', function() {
|
||||
assert(LEXED[2].content);
|
||||
});
|
||||
|
||||
it('should make image URLs relative', function() {
|
||||
assert(LEXED[2].content.indexOf('_book/assets/my-pretty-picture.png') !== -1);
|
||||
});
|
||||
|
||||
it('should gen code and content for exercise sections', function() {
|
||||
assert(LEXED[1].content);
|
||||
assert(LEXED[1].code);
|
||||
@@ -94,3 +90,33 @@ describe('Relative links', function() {
|
||||
assert(LEXED[0].content.indexOf('https://github.com/GitBookIO/javascript/blob/src/something.cpp') !== -1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Relative images', function() {
|
||||
it('should keep image relative with considering output directory in site format', function() {
|
||||
var LEXED = loadPage('IMAGES', {
|
||||
// GitHub repo ID
|
||||
repo: 'GitBookIO/javascript',
|
||||
|
||||
// Imaginary folder of markdown file
|
||||
dir: 'syntax',
|
||||
outdir: 'syntax'
|
||||
});
|
||||
|
||||
assert(LEXED[0].content.indexOf('"preview.png"') !== -1);
|
||||
assert(LEXED[0].content.indexOf('"../preview2.png"') !== -1);
|
||||
});
|
||||
|
||||
it('should keep image relative with considering output directory in page format', function() {
|
||||
var LEXED = loadPage('IMAGES', {
|
||||
// GitHub repo ID
|
||||
repo: 'GitBookIO/javascript',
|
||||
|
||||
// Imaginary folder of markdown file
|
||||
dir: 'syntax',
|
||||
outdir: './'
|
||||
});
|
||||
|
||||
assert(LEXED[0].content.indexOf('"syntax/preview.png"') !== -1);
|
||||
assert(LEXED[0].content.indexOf('"preview2.png"') !== -1);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -3,3 +3,5 @@
|
||||
For creating a theme for GitBook, just copy this folder. The theme folder should at least contains two folders: `assets` and `templates`.
|
||||
|
||||
The theme can be changed using the option ```--theme=<path>```
|
||||
|
||||
#### Warning! Theme system is going to change before version 1.0.0
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
@@ -10,12 +10,14 @@ define([
|
||||
var prev, next;
|
||||
var githubCountStars, githubCountWatch;
|
||||
|
||||
var usePushState = !navigator.userAgent.match('CriOS') && (typeof history.pushState !== "undefined");
|
||||
|
||||
var updateHistory = function(url, title) {
|
||||
history.pushState({ path: url }, title, url);
|
||||
};
|
||||
|
||||
var handleNavigation = function(url, push) {
|
||||
if (typeof history.pushState === "undefined") {
|
||||
if (!usePushState) {
|
||||
// Refresh the page to the new URL if pushState not supported
|
||||
location.href = url;
|
||||
return
|
||||
@@ -23,6 +25,8 @@ define([
|
||||
|
||||
return $.get(url)
|
||||
.done(function (html) {
|
||||
if (push) updateHistory(url, null);
|
||||
|
||||
html = html.replace( /<(\/?)(html|head|body)([^>]*)>/ig, function(a,b,c,d){
|
||||
return '<' + b + 'div' + ( b ? '' : ' data-element="' + c + '"' ) + d + '>';
|
||||
});
|
||||
@@ -49,8 +53,6 @@ define([
|
||||
|
||||
// Update state
|
||||
state.update($("html"));
|
||||
|
||||
if (push) updateHistory(url, null);
|
||||
preparePage();
|
||||
})
|
||||
.fail(function () {
|
||||
|
||||
@@ -20,8 +20,11 @@ define([
|
||||
|
||||
$quiz.find(".question").each(function(q) {
|
||||
var result = true;
|
||||
var $answers = $quiz.find(".question-answers").slice(q).find("input[type=radio], input[type=checkbox]");
|
||||
$(this).find("input[type=radio],input[type=checkbox]").each(function(i) {
|
||||
|
||||
var $questions = $(this).find(".question-content").find("input[type=radio], input[type=checkbox]");
|
||||
var $answers = $(this).find(".question-answers").find("input[type=radio], input[type=checkbox]");
|
||||
|
||||
$questions.each(function(i) {
|
||||
var correct = $(this).is(":checked") === $answers.slice(i).first().is(":checked");
|
||||
result = result && correct;
|
||||
if (!correct) {
|
||||
|
||||
@@ -1,13 +1,6 @@
|
||||
define([
|
||||
"lodash",
|
||||
"mixpanel"
|
||||
], function(_, mixpanel) {
|
||||
mixpanel.init("01eb2b950ae09a5fdb15a98dcc5ff20e", {
|
||||
loaded: function() {
|
||||
track("page.start");
|
||||
}
|
||||
});
|
||||
|
||||
"lodash"
|
||||
], function(_) {
|
||||
var isAvailable = function() {
|
||||
return (
|
||||
typeof mixpanel !== "undefined" &&
|
||||
@@ -15,9 +8,14 @@ define([
|
||||
);
|
||||
};
|
||||
|
||||
var track = function(e, data) {
|
||||
var track = function(e, data, t) {
|
||||
if (!isAvailable()) {
|
||||
console.warn("tracking not available!");
|
||||
t = t || 500;
|
||||
setTimeout(function() {
|
||||
console.log(" -> retest tracking");
|
||||
track(e, data, t*2);
|
||||
}, t);
|
||||
return;
|
||||
}
|
||||
console.log("track", e);
|
||||
@@ -26,6 +24,11 @@ define([
|
||||
}));
|
||||
};
|
||||
|
||||
setTimeout(function() {
|
||||
mixpanel.init("01eb2b950ae09a5fdb15a98dcc5ff20e");
|
||||
track("page.start");
|
||||
}, 0);
|
||||
|
||||
return {
|
||||
isAvailable: isAvailable,
|
||||
track: track
|
||||
|
||||
Vendored
-2
@@ -1,2 +0,0 @@
|
||||
(function(e,b){if(!b.__SV){var a,f,i,g;window.mixpanel=b;b._i=[];b.init=function(a,e,d){function f(b,h){var a=h.split(".");2==a.length&&(b=b[a[0]],h=a[1]);b[h]=function(){b.push([h].concat(Array.prototype.slice.call(arguments,0)))}}var c=b;"undefined"!==typeof d?c=b[d]=[]:d="mixpanel";c.people=c.people||[];c.toString=function(b){var a="mixpanel";"mixpanel"!==d&&(a+="."+d);b||(a+=" (stub)");return a};c.people.toString=function(){return c.toString(1)+".people (stub)"};i="disable track track_pageview track_links track_forms register register_once alias unregister identify name_tag set_config people.set people.set_once people.increment people.append people.track_charge people.clear_charges people.delete_user".split(" ");
|
||||
for(g=0;g<i.length;g++)f(c,i[g]);b._i.push([a,e,d])};b.__SV=1.2;a=e.createElement("script");a.type="text/javascript";a.async=!0;a.src=("https:"===e.location.protocol?"https:":"http:")+'//cdn.mxpnl.com/libs/mixpanel-2.2.min.js';f=e.getElementsByTagName("script")[0];f.parentNode.insertBefore(a,f)}})(document,window.mixpanel||[]);
|
||||
@@ -35,11 +35,14 @@
|
||||
{% endblock %}
|
||||
</head>
|
||||
<body>
|
||||
{% block content %}{% endblock %}
|
||||
{% block style %}
|
||||
<link rel="stylesheet" href="{{ staticBase }}/style.css">
|
||||
{% endblock %}
|
||||
{% block content %}{% endblock %}
|
||||
{% block javascript %}
|
||||
<script type="text/javascript">(function(e,b){if(!b.__SV){var a,f,i,g;window.mixpanel=b;b._i=[];b.init=function(a,e,d){function f(b,h){var a=h.split(".");2==a.length&&(b=b[a[0]],h=a[1]);b[h]=function(){b.push([h].concat(Array.prototype.slice.call(arguments,0)))}}var c=b;"undefined"!==typeof d?c=b[d]=[]:d="mixpanel";c.people=c.people||[];c.toString=function(b){var a="mixpanel";"mixpanel"!==d&&(a+="."+d);b||(a+=" (stub)");return a};c.people.toString=function(){return c.toString(1)+".people (stub)"};i="disable track track_pageview track_links track_forms register register_once alias unregister identify name_tag set_config people.set people.set_once people.increment people.append people.track_charge people.clear_charges people.delete_user".split(" ");
|
||||
for(g=0;g<i.length;g++)f(c,i[g]);b._i.push([a,e,d])};b.__SV=1.2;a=e.createElement("script");a.type="text/javascript";a.async=!0;a.src=("https:"===e.location.protocol?"https:":"http:")+'//cdn.mxpnl.com/libs/mixpanel-2.2.min.js';f=e.getElementsByTagName("script")[0];f.parentNode.insertBefore(a,f)}})(document,window.mixpanel||[]);
|
||||
</script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.1.3/ace.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.1.3/mode-javascript.js"></script>
|
||||
<script src="{{ staticBase }}/jsrepl/jsrepl.js" id="jsrepl-script"></script>
|
||||
|
||||
Reference in New Issue
Block a user