mirror of
https://github.com/GitbookIO/gitbook.git
synced 2026-09-26 20:27:00 +00:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2cc23b7e34 | |||
| 61b6848a95 | |||
| 9265b0185a | |||
| 392573a990 | |||
| 554d6a6170 | |||
| 2182baa2e9 | |||
| 7fe189907e |
+1
-1
@@ -28,7 +28,7 @@ module.exports = function (grunt) {
|
||||
baseUrl: "theme/javascript/",
|
||||
out: "theme/assets/app.js",
|
||||
preserveLicenseComments: false,
|
||||
optimize: "none", //"uglify",
|
||||
optimize: "uglify", //"uglify",
|
||||
include: ["requireLib"],
|
||||
paths: {
|
||||
"jQuery": 'vendors/jquery',
|
||||
|
||||
@@ -36,7 +36,7 @@ Options for commands `build` and `serve` are:
|
||||
-o, --output <directory> Path to output directory, defaults to ./_book
|
||||
-f, --format <name> Change generation format, defaults to site, availables are: site, page, pdf, json
|
||||
-i, --intro <intro> Description of the book to generate
|
||||
-gh, --githubHost <url> The url of the github host (defaults to https://github.com/)
|
||||
--githubHost <url> The url of the github host (defaults to https://github.com/)
|
||||
--theme <path> Path to theme directory
|
||||
```
|
||||
|
||||
@@ -89,7 +89,7 @@ An exercise is defined by 4 simple parts:
|
||||
* **Solution** code, being a correct solution to the exercise
|
||||
* **Validation** code that tests the correctness of the user's input
|
||||
|
||||
Exercises need to start and finish with a separation bar (```---``` or ```***```). It should contain 3 code elements (**base**, **solution** and **validation**).
|
||||
Exercises need to start and finish with a separation bar (```---``` or ```***```). It should contain 3 code elements (**base**, **solution** and **validation**). It can contain a 4th element that provides **context** code (functions, imports of libraries etc ... that shouldn't be displayed to the user).
|
||||
|
||||
---
|
||||
|
||||
@@ -107,6 +107,14 @@ Exercises need to start and finish with a separation bar (```---``` or ```***```
|
||||
assert(x == 10);
|
||||
```
|
||||
|
||||
```js
|
||||
// This is context code available everywhere
|
||||
// The user will be able to call magicFunc in his code
|
||||
function magicFunc() {
|
||||
return 3;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### Multi-Languages
|
||||
|
||||
@@ -42,6 +42,7 @@ var buildFunc = function(dir, options) {
|
||||
title: title,
|
||||
description: options.intro,
|
||||
github: githubID,
|
||||
githubHost: options.githubHost,
|
||||
generator: options.format,
|
||||
theme: options.theme
|
||||
})
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@ var buildCommand = function(command, action) {
|
||||
.option('-t, --title <name>', 'Name of the book to generate, defaults to repo name')
|
||||
.option('-i, --intro <intro>', 'Description of the book to generate')
|
||||
.option('-g, --github <repo_path>', 'ID of github repo like : username/repo')
|
||||
.option('-gh, --githubHost <url>', 'The url of the github host (defaults to https://github.com/')
|
||||
.option('--githubHost <url>', 'The url of the github host (defaults to https://github.com/')
|
||||
.option('--theme <path>', 'Path to theme directory')
|
||||
.action(action);
|
||||
}
|
||||
|
||||
+4
-1
@@ -23,7 +23,10 @@ function sectionType(nodes, idx) {
|
||||
type: 'code'
|
||||
}).length;
|
||||
|
||||
if(codeNodes === 3 && (idx % 2) == 1) {
|
||||
if(
|
||||
(codeNodes === 3 || codeNodes === 4) &&
|
||||
(idx % 2) === 1)
|
||||
{
|
||||
return 'exercise';
|
||||
}
|
||||
|
||||
|
||||
@@ -72,6 +72,8 @@ function parsePage(src, options) {
|
||||
base: codeNodes[0].text,
|
||||
solution: codeNodes[1].text,
|
||||
validation: codeNodes[2].text,
|
||||
// Context is optional
|
||||
context: codeNodes[3] ? codeNodes[3].text : null,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ GitBookRenderer.prototype.link = function(href, title, text) {
|
||||
|
||||
var o = this._extra_options;
|
||||
// Relative link, rewrite it to point to github repo
|
||||
if(!parsed.protocol && parsed.path[0] != '/' && o && o.repo && o.dir) {
|
||||
if(!parsed.protocol && parsed.path && parsed.path[0] != '/' && o && o.repo && o.dir) {
|
||||
href = 'https://github.com/' + o.repo + '/blob' + path.normalize(path.join(
|
||||
'/',
|
||||
o.dir,
|
||||
@@ -79,7 +79,7 @@ GitBookRenderer.prototype.image = function(href, title, text) {
|
||||
var o = this._extra_options;
|
||||
|
||||
// Relative image, rewrite it depending output
|
||||
if(!parsed.protocol && parsed.path[0] != '/' && o && o.dir && o.outdir) {
|
||||
if(!parsed.protocol && parsed.path && parsed.path[0] != '/' && o && o.dir && o.outdir) {
|
||||
_href = path.relative(o.outdir, path.normalize(path.join(
|
||||
o.dir,
|
||||
href
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "gitbook",
|
||||
"version": "0.1.2",
|
||||
"version": "0.1.3",
|
||||
"description": "Library and cmd utility to generate GitBooks",
|
||||
"main": "lib/index.js",
|
||||
"dependencies": {
|
||||
|
||||
Vendored
+33
@@ -30,3 +30,36 @@ Some more nice content ....
|
||||
[Cool stuff](http://gitbook.io)
|
||||
|
||||
[Link to another Markdown file](./xyz/file.md)
|
||||
|
||||
Lets go for another exercise but this time with some context :
|
||||
|
||||
---
|
||||
|
||||
Exercise with some context code :
|
||||
|
||||
Using the `double` function provided, build a `quadruple` function
|
||||
|
||||
```py
|
||||
|
||||
```
|
||||
|
||||
```py
|
||||
|
||||
def quadruple(x):
|
||||
return double(double(x))
|
||||
|
||||
```
|
||||
|
||||
```py
|
||||
assert(quadruple(8), 32)
|
||||
```
|
||||
|
||||
```py
|
||||
|
||||
def double(x):
|
||||
return x * 2
|
||||
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
|
||||
+9
-1
@@ -16,7 +16,7 @@ var LINKS_CONTENT = fs.readFileSync(path.join(__dirname, './fixtures/GITHUB_LINK
|
||||
|
||||
describe('Page parsing', function() {
|
||||
it('should detection sections', function() {
|
||||
assert.equal(LEXED.length, 3);
|
||||
assert.equal(LEXED.length, 4);
|
||||
});
|
||||
|
||||
it('should detection section types', function() {
|
||||
@@ -36,6 +36,14 @@ describe('Page parsing', function() {
|
||||
assert(LEXED[1].code.base);
|
||||
assert(LEXED[1].code.solution);
|
||||
assert(LEXED[1].code.validation);
|
||||
assert(LEXED[1].code.context === null);
|
||||
|
||||
assert(LEXED[3].content);
|
||||
assert(LEXED[3].code);
|
||||
assert(LEXED[3].code.base);
|
||||
assert(LEXED[3].code.solution);
|
||||
assert(LEXED[3].code.validation);
|
||||
assert(LEXED[3].code.context);
|
||||
});
|
||||
|
||||
it('should merge sections correctly', function() {
|
||||
|
||||
+1
-21406
File diff suppressed because one or more lines are too long
@@ -8,6 +8,7 @@ define([
|
||||
var prepareExercise = function($exercise) {
|
||||
var codeSolution = $exercise.find(".code-solution").text();
|
||||
var codeValidation = $exercise.find(".code-validation").text();
|
||||
var codeContext = $exercise.find(".code-context").text();
|
||||
|
||||
var editor = ace.edit($exercise.find(".editor").get(0));
|
||||
editor.setTheme("ace/theme/tomorrow");
|
||||
@@ -20,7 +21,7 @@ define([
|
||||
|
||||
analytic.track("exercise.submit");
|
||||
|
||||
execute("javascript", editor.getValue(), codeValidation, function(err, result) {
|
||||
execute("javascript", editor.getValue(), codeValidation, codeContext, function(err, result) {
|
||||
$exercise.toggleClass("return-error", err != null);
|
||||
$exercise.toggleClass("return-success", err == null);
|
||||
if (err) $exercise.find(".alert-danger").text(err.message || err);
|
||||
|
||||
@@ -2,6 +2,7 @@ define(function() {
|
||||
return {
|
||||
id: "javascript",
|
||||
assertCode: "function assert(condition, message) { \nif (!condition) { \n throw message || \"Assertion failed\"; \n } \n }\n",
|
||||
REPL: JSREPL
|
||||
REPL: JSREPL,
|
||||
sep: ";\n",
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
@@ -71,13 +71,21 @@ define([
|
||||
repl.loadLanguage(lang.id, eventHandler);
|
||||
};
|
||||
|
||||
var execute = function(lang, solution, validation, callback) {
|
||||
var execute = function(lang, solution, validation, context, callback) {
|
||||
// Language data
|
||||
var langd = LANGUAGES[lang];
|
||||
|
||||
// Check language is supported
|
||||
if (!LANGUAGES[lang]) return callback(new Error("Language '"+lang+"' not available for execution"));
|
||||
if (!langd) return callback(new Error("Language '"+lang+"' not available for execution"));
|
||||
|
||||
// Validate with validation code
|
||||
var code = [solution, LANGUAGES[lang].assertCode, validation].join(";\n");
|
||||
evalJS(LANGUAGES[lang], code, function(err, res) {
|
||||
var code = [
|
||||
context,
|
||||
solution,
|
||||
langd.assertCode,
|
||||
validation,
|
||||
].join(langd.sep);
|
||||
evalJS(langd, code, function(err, res) {
|
||||
if(err) return callback(err);
|
||||
|
||||
if (res.type == "error") callback(new Error(res.value));
|
||||
@@ -86,4 +94,4 @@ define([
|
||||
};
|
||||
|
||||
return execute;
|
||||
});
|
||||
});
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
|
||||
<pre class="hidden code-solution">{{ section.code.solution }}</pre>
|
||||
<pre class="hidden code-validation">{{ section.code.validation }}</pre>
|
||||
{% if section.code.context %}
|
||||
<pre class="hidden code-context">{{ section.code.context }}</pre>
|
||||
{% endif %}
|
||||
|
||||
<div class="btn-group btn-group-justified">
|
||||
<a href="#" class="btn btn-default action-submit">Submit</a>
|
||||
|
||||
Reference in New Issue
Block a user