mirror of
https://github.com/GitbookIO/gitbook.git
synced 2026-09-21 10:03:31 +00:00
@@ -0,0 +1,17 @@
|
||||
var _ = require('lodash');
|
||||
|
||||
function isExercise(nodes) {
|
||||
var codeType = { type: 'code' };
|
||||
|
||||
// Number of code nodes in section
|
||||
var len = _.filter(nodes, codeType).length;
|
||||
|
||||
return (
|
||||
// Got 3 or 4 code blocks
|
||||
(len === 3 || len === 4) &&
|
||||
// Ensure all nodes are at the end
|
||||
_.all(_.last(nodes, len), codeType)
|
||||
);
|
||||
}
|
||||
|
||||
module.exports = isExercise;
|
||||
@@ -0,0 +1,87 @@
|
||||
var _ = require('lodash');
|
||||
|
||||
function isQuizNode(node) {
|
||||
return (/^[(\[][ x][)\]]/).test(node.text || node);
|
||||
}
|
||||
|
||||
function isTableQuestion(nodes) {
|
||||
var block = questionBlock(nodes);
|
||||
return (
|
||||
block.length === 1 &&
|
||||
block[0].type === 'table' &&
|
||||
_.all(block[0].cells[0].slice(1), isQuizNode)
|
||||
);
|
||||
}
|
||||
|
||||
function isListQuestion(nodes) {
|
||||
var block = questionBlock(nodes);
|
||||
// Counter of when we go in and out of lists
|
||||
var inlist = 0;
|
||||
// Number of lists we found
|
||||
var lists = 0;
|
||||
// Elements found outside a list
|
||||
var outsiders = 0;
|
||||
// Ensure that we have nothing except lists
|
||||
_.each(block, function(node) {
|
||||
if(node.type === 'list_start') {
|
||||
inlist++;
|
||||
} else if(node.type === 'list_end') {
|
||||
inlist--;
|
||||
lists++;
|
||||
} else if(inlist === 0) {
|
||||
// Found non list_start or list_end whilst outside a list
|
||||
outsiders++;
|
||||
}
|
||||
});
|
||||
return lists > 0 && outsiders === 0;
|
||||
}
|
||||
|
||||
function isQuestion(nodes) {
|
||||
return isListQuestion(nodes) || isTableQuestion(nodes);
|
||||
}
|
||||
|
||||
// Remove (optional) paragraph header node and blockquote
|
||||
function questionBlock(nodes) {
|
||||
return nodes.slice(
|
||||
nodes[0].type === 'paragraph' ? 1 : 0,
|
||||
_.findIndex(nodes, { type: 'blockquote_start' })
|
||||
);
|
||||
}
|
||||
|
||||
function splitQuestions(nodes) {
|
||||
// Represents nodes in current question
|
||||
var buffer = [];
|
||||
return _.reduce(nodes, function(accu, node) {
|
||||
// Add node to buffer
|
||||
buffer.push(node);
|
||||
|
||||
// Flush buffer once we hit the end of a question
|
||||
if(node.type === 'blockquote_end') {
|
||||
accu.push(buffer);
|
||||
// Clear buffer
|
||||
buffer = [];
|
||||
}
|
||||
|
||||
return accu;
|
||||
}, []);
|
||||
}
|
||||
|
||||
function isQuiz(nodes) {
|
||||
// Extract potential questions
|
||||
var questions = splitQuestions(
|
||||
// Skip quiz title if there
|
||||
nodes.slice(
|
||||
(nodes[0] && nodes[0].type) === 'paragraph' ? 1 : 0
|
||||
)
|
||||
);
|
||||
|
||||
// Nothing that looks like questions
|
||||
if(questions.length === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Ensure all questions are correctly structured
|
||||
return _.all(questions, isQuestion);
|
||||
}
|
||||
|
||||
module.exports = isQuiz;
|
||||
+3
-53
@@ -1,6 +1,9 @@
|
||||
var _ = require('lodash');
|
||||
var kramed = require('kramed');
|
||||
|
||||
var isExercise = require('./is_exercise');
|
||||
var isQuiz = require('./is_quiz');
|
||||
|
||||
// Split a page up into sections (lesson, exercises, ...)
|
||||
function splitSections(nodes) {
|
||||
var section = [];
|
||||
@@ -17,59 +20,6 @@ function splitSections(nodes) {
|
||||
}, []).concat([section]); // Add remaining nodes
|
||||
}
|
||||
|
||||
function isQuizNode(node) {
|
||||
return (/^[(\[][ x][)\]]/).test(node.text || node);
|
||||
}
|
||||
|
||||
function isExercise(nodes) {
|
||||
var codeType = { type: 'code' };
|
||||
|
||||
// Number of code nodes in section
|
||||
var len = _.filter(nodes, codeType).length;
|
||||
|
||||
return (
|
||||
// Got 3 or 4 code blocks
|
||||
(len === 3 || len === 4) &&
|
||||
// Ensure all nodes are at the end
|
||||
_.all(_.last(nodes, len), codeType)
|
||||
);
|
||||
}
|
||||
|
||||
function isQuiz(nodes) {
|
||||
if (nodes.length < 3) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Support having a first paragraph block
|
||||
// before our series of questions
|
||||
var quizNodes = nodes.slice(nodes[0].type === 'paragraph' ? 1 : 0);
|
||||
|
||||
// No questions
|
||||
if (!_.some(quizNodes, { type: 'blockquote_start' })) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if section has list of questions
|
||||
// or table of questions
|
||||
var listIdx = _.findIndex(quizNodes, { type: 'list_item_start' });
|
||||
var tableIdx = _.findIndex(quizNodes, { type: 'table' });
|
||||
|
||||
if(
|
||||
// List of questions
|
||||
listIdx !== -1 && isQuizNode(quizNodes[listIdx + 1]) ||
|
||||
|
||||
// Table of questions
|
||||
(
|
||||
tableIdx !== -1 &&
|
||||
_.every(quizNodes[tableIdx].cells[0].slice(1), isQuizNode)
|
||||
)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// What is the type of this section
|
||||
function sectionType(nodes, idx) {
|
||||
if(isExercise(nodes)) {
|
||||
|
||||
Vendored
+120
@@ -0,0 +1,120 @@
|
||||
# Learn Node.js by Example
|
||||
|
||||
|
||||
## Requirements
|
||||
|
||||
- [x] A computer with internet access
|
||||
- [ ] Time: 30h (e.g. 2 months 30 mins per day or **1 week intensive**)
|
||||
|
||||
|
||||
## What is Node.js ?
|
||||
|
||||
Node.js lets you *easily* build networked software (websites, applications "apps",
|
||||
using JavaScript).
|
||||
|
||||
Its not "*point-and-click*" like WordPress, SquareSpace or Salesforce;
|
||||
you will need to write some "code". But as I will demonstrate, that's
|
||||
a *lot* easier than it sounds and gives you more power/flexibility
|
||||
and puts you in full control.
|
||||
|
||||
## Node.js is not "Version 1.0" yet can I used it in Production?
|
||||
|
||||
Yes! Some of the biggest organisations/companies in the world
|
||||
are using Node.js in Production systems:
|
||||
|
||||
[Alibaba](https://github.com/alibaba/node-hbase-client),
|
||||
[Ajax.org](Ajax.org),
|
||||
[Box.com](http://tech.blog.box.com/2014/06/node-js-high-availability-at-box/), British Sky Broadcasting (Sky/Now TV),
|
||||
CNN,
|
||||
[Cloudup](https://cloudup.com/),
|
||||
Conde Nast,
|
||||
[DirectTV](http://strongloop.com/strongblog/node-summit-media-companies-embrace-node-js-for-rapidly-developing-responsive-apps/),
|
||||
[Dow Jones](http://nodejs.org/industry),
|
||||
eBay,
|
||||
[FeedHenry](http://www.feedhenry.com/),
|
||||
[GitHub](https://twitter.com/github/status/16979699217465344),
|
||||
[Google](http://venturebeat.com/2012/01/24/node-at-google-mozilla-yahoo/),
|
||||
[Groupon](http://nodeup.com/fiftyeight),
|
||||
HBO,
|
||||
Help.com,
|
||||
[HP](https://github.com/joyent/node/wiki/Projects,-Applications,-and-Companies-Using-Node),
|
||||
iTV,
|
||||
[Joyent](https://www.joyent.com/) (duh!),
|
||||
[Klout](https://klout.com),
|
||||
LinkedIn,
|
||||
McDonalds,
|
||||
[Medium](https://medium.com/the-story),
|
||||
Mozilla,
|
||||
NetFlix,
|
||||
[OpenTable](http://hapijs.com/community),
|
||||
PayPal,
|
||||
Pearson,
|
||||
~~Q~~,
|
||||
[Revolt](http://revolt.tv/),
|
||||
[Square](https://modulus.io/companies-using-node),
|
||||
Tesco,
|
||||
ThomasCook,
|
||||
Trello,
|
||||
Uber,
|
||||
Voxer,
|
||||
Walmart,
|
||||
Wikimedia (in progress of moving to SOA with node!)
|
||||
Yahoo,
|
||||
Yammer,
|
||||
[Yandex](https://www.youtube.com/watch?v=zdCxgdH4wZo),
|
||||
[Zendesk](http://radar.zendesk.com/)
|
||||
|
||||
Want more? See: http://nodejs.org/industry/ and <br />
|
||||
https://github.com/joyent/node/wiki/Projects,-Applications,-and-Companies-Using-Node
|
||||
|
||||
|
||||
# Try it!
|
||||
|
||||
## Download & Install
|
||||
|
||||
> http://nodejs.org/download/
|
||||
|
||||
|
||||
## Node.js (Core) API
|
||||
|
||||
The node.js ("core") has many useful modules.
|
||||
|
||||
Bookmark: [http://nodejs.org/api](http://nodejs.org/api/) (you will come back to it)
|
||||
|
||||
|
||||
|
||||
## Stability (Can we use it?)
|
||||
|
||||
> *Which node.js* ***core*** *package(s) can/should I use?*
|
||||
|
||||
Every core module has a
|
||||
["***Stability Index***"](http://nodejs.org/api/documentation.html#documentation_stability_index)
|
||||
rating on the node.js API.
|
||||
|
||||
**General rule**: If you are being *paid* to write code
|
||||
that runs in node.js, <br /> pick core modules/methods
|
||||
with stability **Stable**, **API Frozen** and **Locked**.
|
||||
|
||||

|
||||
|
||||
|
||||
### Examples
|
||||
|
||||
- [**cluster**](http://nodejs.org/api/cluster.html) is ***Experimental*** - don't use
|
||||
- [**domain**](http://nodejs.org/api/domain.html) is ***Unstable*** - don't use
|
||||
- [**path**](http://nodejs.org/api/path.html) is ***Stable*** - use
|
||||
- [**events**](http://nodejs.org/api/events.html) is ***Frozen*** - use
|
||||
- [**assert**](http://nodejs.org/api/assert.html) is ***Locked*** - use
|
||||
|
||||
Core Modules to Learn
|
||||
|
||||
- path
|
||||
- os
|
||||
|
||||
|
||||
|
||||
Community Modules to Learn:
|
||||
|
||||
- [jscs](https://www.npmjs.org/package/jscs) - code style checker
|
||||
- [q](https://www.npmjs.org/package/q) - promises library
|
||||
- [nd](https://www.npmjs.org/package/nd) - view documentation for a module
|
||||
@@ -122,3 +122,11 @@ describe('Relative images', function() {
|
||||
assert(LEXED[0].content.indexOf('"preview2.png"') !== -1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Section parsing', function() {
|
||||
it('should not have false positive quiz parsing', function() {
|
||||
var LEXED = loadPage('FALSE_QUIZ');
|
||||
|
||||
assert.equal(LEXED[0].type, 'normal');
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user