Compare commits

...

7 Commits

Author SHA1 Message Date
Aaron O'Mullan 2cc23b7e34 Bump version to 0.1.3 2014-04-08 17:03:13 -07:00
Aaron O'Mullan 61b6848a95 Uglify output JS theme/assets/app.js 2014-04-08 17:01:43 -07:00
Aaron O'Mullan 9265b0185a Add context code support to exercises (optional)
Partial #52, fixes #49, fixes #46
2014-04-08 16:58:04 -07:00
Aaron O'Mullan 392573a990 Add lexing support for content code in exercises
#52, #49, #46
2014-04-08 15:01:12 -07:00
Aaron O'Mullan 554d6a6170 Fix URL rewriting error on empty URLs
Fixes #54, fixes #59
2014-04-08 14:47:36 -07:00
Samy Pessé 2182baa2e9 Merge pull request #51 from calmdev/fix/gh-enterprise
Fixes --githubHost option for use with Github Enterprise.
2014-04-07 10:42:55 -07:00
Levi Lewis 7fe189907e Fixes --githubHost option for use with Github Enterprise. 2014-04-07 13:11:44 -04:00
15 changed files with 86 additions and 21423 deletions
+1 -1
View File
@@ -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',
+10 -2
View File
@@ -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
+1
View File
@@ -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
View File
@@ -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
View File
@@ -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';
}
+2
View File
@@ -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,
}
};
}
+2 -2
View File
@@ -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
View File
@@ -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": {
+33
View File
@@ -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
View File
@@ -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
View File
File diff suppressed because one or more lines are too long
+2 -1
View File
@@ -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);
+3 -2
View File
@@ -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",
};
});
});
+13 -5
View File
@@ -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>