Compare commits

..

981 Commits

Author SHA1 Message Date
Johan Preynat ad425b9772 Bump version to 3.2.2 2016-10-01 22:35:54 +02:00
Johan Preynat 5238fa352c Rollback to use gitbook-markdown@1.3.2 2016-10-01 22:30:43 +02:00
Johan Preynat 32183b6650 Merge branch 'fix-3.1-version' 2016-10-01 21:49:06 +02:00
Johan Preynat cb3d6a7f01 Correctly handle page parsing errors 2016-10-01 21:47:25 +02:00
Johan Preynat c978f0ab21 Add comment 2016-10-01 21:47:08 +02:00
Samy Pessé 33ff60cee7 Add changes for 3.2.1 2016-09-28 15:56:36 +02:00
Samy Pesse 33d7e022e6 Bump version to 3.2.1 2016-09-28 13:21:24 +02:00
Samy Pesse 09782b964b Update theme-default@1.0.6 2016-09-28 13:10:47 +02:00
Johan Preynat 7938ee8ec6 Use nunjucks@2.5.2 2016-09-28 10:32:14 +02:00
Peter B Smith 2e8e4f63d7 fixing a typo of the word "publishing" (#1536) 2016-09-28 09:49:29 +02:00
jdaviescoates b9fa6c3051 Update examples.md (#1522)
By adding the Loomio and Enspiral handbook examples
2016-09-08 20:38:59 +02:00
Samy Pessé 9c071dade5 Merge pull request #1481 from mcveat/patch-1
Fixed typo
2016-08-04 00:19:11 +02:00
Piotr Adamski 56e44651fa Fixed typo 2016-08-03 22:08:12 +02:00
Samy Pessé 42fac98992 Fix command for getting gitbook version 2016-08-01 09:47:31 +02:00
Samy Pessé 4f5513add0 Create template for GitHub issues 2016-07-25 20:39:31 +02:00
Samy Pesse 90cbfc0596 Add OSX testing on Travis 2016-07-15 11:38:58 +02:00
Samy Pessé 38ab9fa05a Bump version to 3.2.0 2016-07-11 16:48:13 +02:00
Samy Pessé 12e20c5fcc Update theme-default@1.0.5 2016-07-11 16:47:16 +02:00
Samy Pessé 6b103f4532 Fix #1408: fix i18n in website generator and add tests for it 2016-07-11 16:27:22 +02:00
Soreine d4fa5c18a8 editPlugin and getPluginConfig 2016-07-11 15:18:35 +02:00
Soreine 2a116dfdb0 Fix reducedObject when default property is undefined 2016-07-11 15:18:35 +02:00
Samy Pessé 0349f54f3c Export file model 2016-07-07 16:41:05 +02:00
Samy Pessé 695bda312c Bump version to 3.2.0-pre.1 2016-07-05 17:15:48 +02:00
Samy Pessé 144bd4c97a Update gitbook-markdown@2.0.1 2016-07-05 11:07:51 +02:00
Samy Pessé e105983cf8 Add back property "output" to page/template context 2016-07-04 18:08:44 +02:00
Soreine ea3afbed75 Update gitbook-plugin-lunr@1.2.0 2016-07-01 17:52:15 +02:00
Soreine d563abe3df Reduce size of logo to give room to version number 2016-06-30 15:37:31 +02:00
Soreine 70fd4ded29 Update theme-official for doc 2016-06-30 12:15:50 +02:00
Samy Pessé 9ce9388dfc Bump version to 3.2.0-pre.0 2016-06-30 11:09:18 +02:00
Samy Pessé c575ad83ae Update gitbook-markdown@2.0.0 2016-06-30 10:51:46 +02:00
Samy Pessé 936fa1545b Add tests for locationUtils.flatten 2016-06-29 10:32:49 +02:00
Samy Pessé c9c2dde2b6 Add method "isFile" and "isReadme" in SummaryArticle 2016-06-29 10:31:06 +02:00
Samy Pessé d9a1d387c7 Merge pull request #1397 from mpfeil/master
add open and browser args to serve command
2016-06-23 11:40:05 +02:00
Matthias Pfeil bf29d187c8 disable open by default 2016-06-20 17:24:08 +02:00
Matthias Pfeil d86f9b2667 add open and browser args to serve command 2016-06-17 16:00:53 +02:00
Samy Pesse aca4313fc3 Enable long stack support when process.env.CI is true 2016-06-11 12:38:19 +02:00
Samy Pesse 4cb5bb06fb Bump version to 3.1.1 2016-06-10 22:19:09 +02:00
Samy Pesse 24988b75ea Fix extsAsciidoc.js 2016-06-10 22:14:04 +02:00
Samy Pesse 775e858d05 Expose markdown/asciidoc extensions to gitbook module 2016-06-10 22:13:31 +02:00
Samy Pesse 1e3d871c1e Merge branch 'fix/plugins_loading' 2016-06-10 22:08:16 +02:00
Samy Pesse 94a4310c1e Adapt Plugins.loadForBook to use correct order 2016-06-10 22:04:19 +02:00
Samy Pessé e8ee57be83 Start fixing order of plugins in dependencies 2016-06-10 18:34:24 +02:00
Samy Pessé 50a132cb2c Add method "createChildLevel" to SummaryPart 2016-06-10 18:11:22 +02:00
Samy Pessé 59be32a54f Add method .createChildLevel for SummaryArticle 2016-06-10 18:08:56 +02:00
Soreine 4ae7cdb5d1 Mention autocover plugin in docs 2016-06-10 18:03:40 +02:00
Samy Pessé 990a4efeb5 Update gitbook-markdown and gitbook-asciidoc 2016-06-10 17:53:10 +02:00
Samy Pessé 9c927dcf13 Fix #1374 and #1360: apply transform of conrefsLoader using a string, not a buffer 2016-06-10 17:45:30 +02:00
Samy Pessé 7a08b3f109 Fix #1377: fix listing of plugins when using gitbook as a library 2016-06-10 17:15:04 +02:00
Samy Pessé 94d4234cb8 Merge branch 'fix/plugins_order' 2016-06-10 16:44:13 +02:00
Samy Pessé fbc851bc4e Fix listAll to add default plugins after normal ones 2016-06-10 16:43:32 +02:00
Samy Pessé e92b661a2a Adapt sortPlugins to only sort an ordered map of plugins 2016-06-10 16:37:44 +02:00
Soreine b9fe60915f Add tests for insertPart 2016-06-10 15:40:51 +02:00
Samy Pessé 1bf7d092f0 Merge pull request #1363 from todvora/master
Fixed target attribute for external links
2016-06-10 00:28:50 +02:00
Samy Pesse 826d472511 Fix documentation about themes 2016-06-08 20:06:50 +02:00
Samy Pessé a6b1f4bd87 Compare list of plugins sorted to array of names in tests 2016-06-08 15:08:11 +02:00
Samy Pessé 004f91f02c sortPlugins should not be async 2016-06-08 15:02:34 +02:00
Samy Pessé e6c6ec4293 Improve testing for sortPlugins 2016-06-08 14:57:54 +02:00
Soreine a1d3acf065 Fix serve cli using new ConfigModifier.addPlugin 2016-06-08 10:42:27 +02:00
Soreine a732660f59 docs: cover remove extraneous line 2016-06-08 10:35:12 +02:00
Nicolas Gaborit e1bb0638f8 docs: cover, fix formatting 2016-06-08 10:16:54 +02:00
Soreine 788c0c7e7e Adds cover.jpg info 2016-06-08 10:12:42 +02:00
Tomas Dvorak 762fe16a17 fixed target attribute for external links 2016-06-07 18:34:36 +02:00
Samy Pessé 15123805d1 Fix linting error 2016-06-07 16:24:22 +02:00
Samy Pessé 23aecb4f2b Improve output of page to text with frontmatter 2016-06-07 16:23:12 +02:00
Samy Pessé f1d200b81b Rollback frontmatter parsing to js-yaml to be browserify compatible 2016-06-07 14:32:12 +02:00
Samy Pessé b566711ee1 Add method toText to Page 2016-06-07 12:51:35 +02:00
Samy Pessé 22da5aac11 Switch frontmatter parsing to gray-matter 2016-06-07 12:47:16 +02:00
Samy Pessé f7b95102c5 Expose Page model 2016-06-07 12:36:32 +02:00
Samy Pessé ca70c934d6 Split page parsing into parsePageFromString and parsePage
Add tests for parsePageFromString
2016-06-07 12:31:21 +02:00
Samy Pessé 1cc48fa314 Use Immutable instead of lodash for mergeDefaults 2016-06-07 12:06:29 +02:00
Samy Pessé b63b5574d3 Only merge objects in mergeDefaults 2016-06-07 11:40:54 +02:00
Samy Pessé 67106e8698 Improve plugins config modifier 2016-06-07 11:06:53 +02:00
Samy Pessé dc2ab51a88 Update i18n-t and juice 2016-06-07 10:54:34 +02:00
Samy Pessé cedfa186f2 Remove merge-defaults dependency 2016-06-07 10:48:04 +02:00
Samy Pessé 80f0d1bfed Update gitbook-markdown and gitbook-asciidoc to use lodash@4 2016-06-07 10:36:01 +02:00
Samy Pessé 7178ab1f82 Improve Config.toText to return only the required fields 2016-06-07 10:26:28 +02:00
Samy Pesse bf895b707e Improve addPlugin to not append default plugins to the list 2016-06-07 00:56:24 +02:00
Samy Pesse 996170a4ad ConfigModifier.removePlugin should toggle off if default 2016-06-07 00:48:47 +02:00
Samy Pesse aa66a4f928 Expose DEFAULT_PLUGINS as a list of PluginDependency 2016-06-06 22:04:13 +02:00
Samy Pesse 23010fa54a Adapt tests for config modifiers 2016-06-06 21:22:44 +02:00
Samy Pesse 0baebc7979 Change config modifier to work on a config object 2016-06-06 21:20:00 +02:00
Samy Pesse 257158321c Bump version to 3.1.0 2016-06-06 19:51:44 +02:00
Samy Pesse ddf0a41e29 Add method editPlugin to config modifiers 2016-06-06 19:42:44 +02:00
Samy Pesse 357e1e8e96 Add unit tests for postRender 2016-06-06 19:24:12 +02:00
Samy Pesse 7a89f9869a Update gitbook-markdown@1.3.0 and gitbook-asciidoc@1.2.0 2016-06-06 18:07:31 +02:00
Samy Pesse 30fbd22efe Add modifier togglePlugin 2016-06-06 17:27:47 +02:00
Samy Pesse 29df73ba72 Add method "toText" to config 2016-06-06 17:16:53 +02:00
Soreine f8676483c1 Default paths are relative to the current book 2016-06-06 16:55:00 +02:00
Johan Preynat c79a6f2fba Use theme-default@1.0.4 2016-06-06 15:46:44 +02:00
Samy Pessé c38e67ea61 Merge pull request #1344 from GitbookIO/fix/readme-in-summary
Search for README file in whole summary before inserting as first article
2016-06-06 12:18:06 +02:00
Johan Preynat 97a5f8805e Use plugin-fontsettings@2.0.0 2016-06-02 10:24:12 +02:00
Johan Preynat 421fef6ebf Search for README file in whole summary before inserting as first article 2016-05-30 15:07:39 +02:00
Johan Preynat 33406c3082 Merge pull request #1336 from GitbookIO/loading/themes
Load plugins before themes
2016-05-28 11:56:34 +02:00
Johan Preynat c3851889b0 Throw an error if generateMock() cannot create the temp directory 2016-05-27 17:15:23 +02:00
Johan Preynat 4a5de2da6b Use sortPlugins() in loadForBook() 2016-05-27 15:06:20 +02:00
Johan Preynat 1afb23cada Add test file for sortPlugins() 2016-05-27 15:06:08 +02:00
Johan Preynat a3b0f3f868 Export plugins sorting method to load plugins before themes 2016-05-27 15:05:55 +02:00
Johan Preynat 0aa32916d6 Add prefix for theme plugins as constant 2016-05-27 15:05:33 +02:00
Samy Pessé ebe845d46c Bump version to 3.0.3 2016-05-27 12:16:56 +02:00
Samy Pessé edee8d2fc5 Update gitbook-theme-default@1.0.3 2016-05-27 12:07:35 +02:00
Samy Pessé 5f3de0876f Add header 'X-Current-Location' to serve and fix handling of directories 2016-05-27 12:01:28 +02:00
Samy Pessé 2ceab04d01 Increase timeout for tests of plugin installation 2016-05-27 11:40:05 +02:00
Samy Pessé de37de44e8 Add tests for installation of all plugins 2016-05-27 11:18:12 +02:00
Samy Pessé ccb87d5a13 Add unit tests for installPlugin 2016-05-27 11:10:39 +02:00
Samy Pessé e2e0ca3f05 Add test for plugin version resolution 2016-05-27 10:54:56 +02:00
Samy Pessé b33a79704b Switch plugin installation and resolveVersion to use PluginDependency instead of Plugin 2016-05-27 09:38:23 +02:00
Samy Pessé 6def174b84 Merge pull request #1334 from ryanswanson/master
Fixed two issues for handling git URLs for plugins
2016-05-27 09:27:11 +02:00
Samy Pessé 346a18b444 Merge pull request #1335 from GitbookIO/fix/1333
Fix #1333: fix invalid URLs for glossary annotations
2016-05-26 22:30:06 +02:00
Samy Pesse b32685c698 Add test for custom glossary file 2016-05-26 22:01:40 +02:00
Samy Pesse 09b3618da8 Annotate glossary terms before resolving links 2016-05-26 21:38:27 +02:00
Samy Pesse 901328f247 Complete basic tests for glossary 2016-05-26 21:37:10 +02:00
Samy Pesse b47ebaa9d9 Use real glossary name when annotating 2016-05-26 21:10:06 +02:00
Ryan Swanson 465e8d6c0a Fixed two issues for handling git URLs for plugins that are published to git repositories rather than on npmjs.org.
Fixed issue in pluginDependency to dereference 'name' and 'version' using Immutable Map.get(...) accessors since config values are now wrapped by Immutable.fromJS(...) in config.js > setValue(...).  Added associated unit test.

Fixed issue in resolveVersion where a plugin may be using a git URL rather than a semver for the version portion of the plugin config definition.  In addition, refactored the resolveVersion function into a new module to allow for unit testing.  Added associated unit test.
2016-05-26 14:30:29 -04:00
Samy Pessé ecd86ec877 Method for parsing glossary when not listed in summary 2016-05-26 17:26:11 +02:00
Samy Pessé 5d7864154c Start test for glossary generation 2016-05-26 17:25:49 +02:00
Samy Pessé 7b915428f7 Fix #1316: fix regression for supporting uppercase filenames in structure 2016-05-26 11:07:13 +02:00
Samy Pesse 0bce3517fd Bump version to 3.0.2 2016-05-25 21:50:38 +02:00
Samy Pesse 089815a8fd Fix #1328: fix crash when anchor links 2016-05-25 21:49:58 +02:00
Samy Pesse 7e8f1a9632 Bump version to 3.0.1 2016-05-25 20:00:04 +02:00
Samy Pesse 8469648241 Update theme-default@1.0.2 2016-05-25 17:14:15 +02:00
Samy Pessé e7a44358a5 Update Changelog 2016-05-24 15:38:26 +02:00
Samy Pessé fb930d889f Fix anchor breaking links resolution 2016-05-24 15:32:30 +02:00
Samy Pessé 721a75309b Fix #1316: adapt regexp to handle dot in filenames 2016-05-23 13:00:01 +02:00
Samy Pessé b856bff91b Add failing test for #1316 2016-05-23 12:48:46 +02:00
Samy Pesse 0744f000f9 Fix doc for conrefs 2016-05-22 19:59:53 +02:00
Samy Pesse d1e226dba5 Bump version to 3.0.0 2016-05-20 22:18:37 +02:00
Samy Pesse 1923d28d71 Update dependencies 2016-05-20 22:17:44 +02:00
Samy Pessé 484a306adb Fix error with isInRoot when empty root 2016-05-20 21:41:02 +02:00
Samy Pessé 5bfc9f2f56 Fix PathUtils.isInRoot on windows 2016-05-20 21:37:22 +02:00
Samy Pesse 86a65e5287 Improve appveyor configuration 2016-05-20 19:23:51 +02:00
Samy Pesse 956d301dd7 Add node v6 to appveyor matrix 2016-05-20 18:22:44 +02:00
Samy Pesse 00d1a7b5a6 Update theme-default@1.0.1 2016-05-20 18:17:34 +02:00
Samy Pessé 2718c9c017 Fix test command for windows 2016-05-19 10:45:25 +02:00
Samy Pesse 3234c1e03f Fix #1310: enforce language config in language books 2016-05-19 00:15:09 +02:00
Aaron O'Mullan c8f8eece92 Merge pull request #1308 from arebee/patch-1
Fix english phrasing for Node version.
2016-05-19 00:10:08 +02:00
Richard Burte 7394efa9dc Fix english phrasing for Node version. 2016-05-18 09:54:04 -07:00
Samy Pesse 3e4241fc88 Implement renderInline method and missing output methods for API 2016-05-17 19:45:48 +02:00
Samy Pesse a5ae79604c Implement renderBlock method for plugin API 2016-05-17 19:30:28 +02:00
Soreine fc4bdd68a1 Can only use file names 2016-05-17 16:47:52 +02:00
Soreine f83975b022 Mention the structure configuration variable 2016-05-17 16:37:13 +02:00
Soreine 167d3957bf Expose lookup method for parsable files 2016-05-17 12:48:03 +02:00
Samy Pessé a9571fd67d Bump version to 3.0.0-pre.15 2016-05-12 16:53:14 +02:00
Samy Pessé ac87f48ba5 Update theme-default@1.0.0 2016-05-12 16:52:19 +02:00
Samy Pessé 05403f527d Fix bug that can happen when configuration file doesn't exist 2016-05-12 16:45:09 +02:00
Samy Pessé 53c72f0806 Add api method getPageByPath for plugins 2016-05-12 16:29:36 +02:00
Samy Pessé c8c2a61f96 Fix #1289: add option to filter files when listing using fs.listAllFiles 2016-05-12 16:10:11 +02:00
Samy Pessé 08d780d1f6 Fix #1300: parse page frontmatter and content when listing pages 2016-05-12 15:48:02 +02:00
Samy Pessé 2e74fafa36 Add template method "getPageByPath" 2016-05-12 15:12:08 +02:00
Samy Pessé 28ac9ab88a Fix #1299: pass fileExists as global function for template, accept null/undefined as param 2016-05-12 15:04:30 +02:00
Samy Pessé 26acab4dfb Fix generation of ebook for multilingual book (gitbook pdf) 2016-05-12 14:29:25 +02:00
Samy Pessé d4b562e001 Fix get of cover for multilingual books 2016-05-12 14:12:43 +02:00
Soreine 61956e0646 Revert "Extend Book.getLanguageBook"
This reverts commit 7892259fe6.
2016-05-12 14:08:29 +02:00
Soreine 7892259fe6 Extend Book.getLanguageBook 2016-05-12 13:35:29 +02:00
Samy Pessé b97d1c7796 Fix languages not being added to json output 2016-05-12 13:25:09 +02:00
Samy Pessé a091c5b331 Fix path resolution when generating page with conrefs 2016-05-12 12:19:00 +02:00
Samy Pessé 784b3379b5 Improve logging when generating multilingual book 2016-05-12 11:20:27 +02:00
Johan Preynat 62446e75d2 Update book's root folder definition in Changelog 2016-05-12 11:18:00 +02:00
Samy Pessé 8aa2f3075c Fix #1294: multilingual book should extend the book's config 2016-05-12 11:15:13 +02:00
Samy Pessé 839ee0385a Add method "getLanguageBook" to book model 2016-05-12 11:02:37 +02:00
Samy Pesse d6b60c6116 Adapt eslint configuration for mocha 2016-05-11 16:56:18 +02:00
Samy Pesse 9013f02850 Add test for transform option of ConrefLoader 2016-05-11 15:08:10 +02:00
Samy Pesse 961d43f085 Fix #1293: replace block shortcuts when including files 2016-05-11 14:45:54 +02:00
Samy Pessé 7bd49606e3 Merge pull request #1291 from GitbookIO/summary-modifiers
Summary modifiers
2016-05-11 13:57:21 +02:00
Samy Pesse d7c8635350 Increase mocha timeout 2016-05-11 13:57:00 +02:00
Soreine 19e9ff81d2 Tweak insertPart signature 2016-05-11 13:11:32 +02:00
Soreine e137bf632a Adds editArticleRef 2016-05-11 13:11:32 +02:00
Soreine 2fef898a1e Modifier moveArticleAfter 2016-05-11 13:11:32 +02:00
Soreine 0945807184 Greatly simplify moveArticle's implementation 2016-05-11 13:11:32 +02:00
Soreine d85663b153 Tests remove/insert articles and update insert signature 2016-05-11 13:11:31 +02:00
Soreine 481a7d790c Insert/remove part 2016-05-11 13:11:31 +02:00
Samy Pesse ef589a6b13 Switch tests to mocha while keeping jest structure 2016-05-11 13:02:24 +02:00
Samy Pesse d5c4af3377 Add immutable ignore instance for book 2016-05-11 13:02:24 +02:00
Soreine 0b4df4cdf2 Precise h2 headings for Glossary 2016-05-11 10:55:34 +02:00
Samy Pessé d6814dc48e Don't copy config file as asset 2016-05-10 15:23:59 +02:00
Samy Pessé ce50a1d50f Bump version to 3.0.0-pre.14 2016-05-10 14:37:22 +02:00
Samy Pessé a76e018d36 Update theme-default@1.0.0-pre.10 2016-05-10 14:37:05 +02:00
Samy Pessé b06f1fd677 Fix article.depth starting at 2 2016-05-10 14:36:03 +02:00
Samy Pessé 3d8b1880dc Fix page's title in pdf header/footer 2016-05-10 14:25:50 +02:00
Samy Pessé 1a13c8c9bb Add option "--no-live" for command serve 2016-05-10 13:14:32 +02:00
Samy Pessé 852fae3a09 Fix #1232: add option "--no-watch" to disable watcher and live reloading 2016-05-10 13:08:19 +02:00
Samy Pessé d342d31c8e Fix error when summary contains entry without ref 2016-05-10 12:12:19 +02:00
Samy Pesse 5b3f54fbc8 Fix "gitbook init" when article has no ref 2016-05-10 09:55:22 +02:00
Samy Pessé 308ece784c Merge pull request #1288 from todvora/patch-1
Fixed summary encoding
2016-05-10 08:55:40 +02:00
Tomas Dvorak 0758ddf04e Fixed summary encoding 2016-05-10 08:17:52 +02:00
Samy Pesse f24d9aef73 Add test for block replaced with anchors 2016-05-09 22:17:46 +02:00
Samy Pesse f8bb55f258 Adapt unit tests for blocks 2016-05-09 22:01:25 +02:00
Samy Pesse 76daebeb84 Fix unit test for templateBlock using a removed method "getParse" 2016-05-09 18:41:21 +02:00
Samy Pesse b0d366b7e8 Fix linting warning in models/templateBlock.js 2016-05-08 22:45:26 +02:00
Samy Pesse 3d0054dd64 Fix #1286: by default blocks should not be parsable 2016-05-08 22:33:41 +02:00
Samy Pessé 13bc89ff44 Merge pull request #1285 from GitbookIO/api/summary
[WIP] Api for plugins to access summary
2016-05-08 22:28:15 +02:00
Samy Pesse bb910f984e Improve comment for API summary.walk 2016-05-08 22:26:46 +02:00
Samy Pessé e576fdea14 Merge pull request #1278 from dylang/patch-1
bump bash-color to version that has a license
2016-05-08 18:44:53 +02:00
Samy Pesse c7864927ec Add method summary.getArticleByPath to summary api 2016-05-08 11:08:27 +02:00
Samy Pesse 54956de59f Start API for plugins to access the summary 2016-05-08 10:33:45 +02:00
Samy Pesse 2cbd30d1f2 Fix command "gitbook init" 2016-05-07 00:24:12 +02:00
Dylan Greene 55614f1675 bump bash-color to version that has a license
Version currently being used does not have a license making it difficult for companies to use.
2016-05-06 09:56:43 -04:00
Samy Pesse 4f7421993f Bump version to 3.0.0-pre.13 2016-05-06 10:59:52 +02:00
Samy Pesse 32ad7b530e Fix #1266: don't fail on "a" tags without "href" 2016-05-06 10:57:41 +02:00
Samy Pesse ee5d5010f6 Correctly read assets using input fs when copying 2016-05-06 10:54:13 +02:00
Samy Pesse cf7e5884cd Add method readAsStream on fs model 2016-05-06 10:53:55 +02:00
Samy Pesse 11a0a64d9e Add failing test for #1272 2016-05-06 10:36:55 +02:00
Samy Pesse b6051babac Adapt unit tests for new templating post process 2016-05-05 11:09:35 +02:00
Samy Pesse 34947b5e20 Add mode TemplateOutput to represent {content + blocks} from template 2016-05-05 11:00:05 +02:00
Samy Pesse c621380b66 Add tests for replaceShortcuts 2016-05-04 20:18:48 +02:00
Samy Pesse c4b54033ce Fix #1268: fix shortcuts of template block not being applied 2016-05-04 19:01:31 +02:00
Samy Pesse 4d85d6eb6e Fix #1267: don't fail when "node_modules" folder doesn't exist 2016-05-04 17:41:15 +02:00
Samy Pessé cc9274c9af Bump version to 3.0.0-pre.12 2016-05-04 13:50:52 +02:00
Johan Preynat bbdf7efc34 Fix location.relative(dir, file) trailing slash if file is a directory 2016-05-04 11:51:39 +02:00
Samy Pessé 38a986995a Merge pull request #1264 from GitbookIO/fix/plugin-resources
Fix Loading plugin resources
2016-05-04 10:33:29 +02:00
Johan Preynat ee8d35df7a Update Plugins.listResources() to use the prepared resources list 2016-05-04 10:30:11 +02:00
Johan Preynat be411cd5ff Update copyPluginAssets to use prepared resources 2016-05-04 10:27:21 +02:00
Johan Preynat 2104019171 List resources per plugin in website generator onInit() 2016-05-04 10:26:57 +02:00
Johan Preynat 4e564707df Add resources to website generator state 2016-05-04 10:26:06 +02:00
Johan Preynat da8611e0c3 Add global method resolve(fileName) 2016-05-04 10:25:37 +02:00
Samy Pessé 5d11641a5f Merge pull request #1260 from GitbookIO/move-article
Adds move and remove article modifier.
2016-05-04 09:47:50 +02:00
Samy Pessé 24d38e4fcf Fix #1263: Fix page generation for AsciiDoc 2016-05-04 09:30:09 +02:00
Samy Pessé efb65a8413 Remove filter for pdf/epub/mobi files when outputting 2016-05-03 17:18:13 +02:00
Soreine 3fc90554f5 Add tests, and fixes. 2016-05-03 16:02:58 +02:00
Soreine 4ebe28faae Update insert specification 2016-05-03 13:11:32 +02:00
Soreine 693171cb05 Adds move and remove article modifier. 2016-05-03 12:37:26 +02:00
Samy Pessé 42a2d090aa Bump version to 3.0.0-pre.11 2016-05-03 12:15:30 +02:00
Samy Pessé c84eaa83dd Merge pull request #1259 from GitbookIO/png-data-uri
Adding data-uri support for PNG Images in Books
2016-05-03 12:10:09 +02:00
Johan Preynat 74c3ff80cb lib/models/config.js: Fix wrong call to PluginDependency.listToArray() to PluginDependency.listFromArray() 2016-05-03 12:04:52 +02:00
Johan Preynat 5893d3ee64 lib/parse/parseConfig.js: Remove unused require 2016-05-03 12:04:04 +02:00
Johan Preynat 7f435c56a0 lib/output/modifiers/inlineAssets.js: Add inlinePng() modifier 2016-05-03 11:30:02 +02:00
Johan Preynat 59b7100cf6 lib/output/modifiers/__tests__/inlinePng.js: Add test file for inlinePng modifier 2016-05-03 11:29:40 +02:00
Johan Preynat 0923d1aa24 lib/output/modifiers/inlinePng.js: Add modifier to save inline PNG images 2016-05-03 11:29:17 +02:00
Johan Preynat ffe6c36f2f lib/output/modifiers/resolveImages.js: Don't resolve images when src is a data URI 2016-05-03 11:28:39 +02:00
Johan Preynat 8c4752c5d8 lib/utils/__tests__/location.js: Add location.isDataURI() test file 2016-05-03 11:27:36 +02:00
Johan Preynat d6202e522b lib/utils/images.js: Add convertInlinePNG() method 2016-05-03 11:27:05 +02:00
Johan Preynat 50a24c62c5 lib/utils/location.js: Add isDataURI() method 2016-05-03 11:26:38 +02:00
Soreine 6b17d08892 Adds default file naming utilities in Book model 2016-05-03 11:17:27 +02:00
Samy Pesse 79c91fd8c5 Log npm version being used when running gitbook install 2016-05-02 22:18:19 +02:00
Samy Pesse 95764258ab Update dependencies 2016-05-02 22:16:51 +02:00
Samy Pesse 41e6872557 Merge branch 'fix/plugins_deps' 2016-05-02 22:02:45 +02:00
Samy Pesse 30c96c37c2 Adapt Plugin.listAll to use a list of PluginDependency 2016-05-02 22:02:24 +02:00
Samy Pesse 20f1cf3dff Enable promise long stack trace when testing or debugging 2016-05-02 22:01:05 +02:00
Samy Pesse 8de0d6186e Fix mock fs for windows testing 2016-05-02 19:16:06 +02:00
Samy Pesse edd7d8aefe Update gitbook-asciidoc@1.1.4 2016-05-02 18:45:17 +02:00
Samy Pesse a8da4903f4 Update gitbook-asciidoc@1.1.3 to fix error on linux 2016-05-02 17:27:18 +02:00
Samy Pesse c8df5033f7 Update gitbook-asciidoc@1.1.2 2016-05-02 17:25:41 +02:00
Samy Pesse 412f418da3 Update gitbook-markdown@1.2.3 2016-05-02 17:15:54 +02:00
Johan Preynat 3782d21069 lib/output/ebook/onPage.js: Fix missing page's filepath at Modifiers.inlineAssets() call 2016-05-02 16:54:14 +02:00
Johan Preynat 82a29f4470 lib/models/languages.js: Use lang.ref 2016-05-02 16:37:47 +02:00
Johan Preynat 4a65326b24 Update jest@12.0.2 2016-05-02 16:37:24 +02:00
Johan Preynat d75d8729be lib/output/ebook/onFinish.js: Use lowercase summary.html filename from themes 2016-05-02 16:26:00 +02:00
Samy Pessé c87060454e Add model for plugin dependencies in the book.json 2016-05-02 16:24:20 +02:00
Samy Pessé bbba52c7ff Update gitbook-markdown and gitbook-asciidoc 2016-05-02 16:21:44 +02:00
Samy Pessé 33418bdb33 Document method in utils/command.js 2016-05-02 15:21:08 +02:00
Samy Pessé de47db2b66 Fix escaping of ebook-convert options 2016-05-02 15:09:10 +02:00
Johan Preynat fa6fcffbe1 Improve lib/plugins/__tests__/findInstalled.js 2016-05-02 15:06:02 +02:00
Samy Pessé 93d3f11891 Fix js error when using node < 4.x 2016-05-02 15:03:29 +02:00
Johan Preynat 59479f10fc Fix lib/plugins/__tests__/findInstalled.js 2016-05-02 14:46:54 +02:00
Samy Pessé 11e72253d4 Bump version to 3.0.0-pre.10 2016-05-02 14:40:54 +02:00
Samy Pessé 37fca9c88a Update theme-default@1.0.0-pre.9 2016-05-02 14:39:39 +02:00
Johan Preynat 6d67048e98 Use gitbook-plugin-search@2.2.1 2016-05-02 14:36:23 +02:00
Johan Preynat c516a5c1bd lib/fs/node.js: Use fresh-require@1.0.3 to read uncached configuration files 2016-05-02 14:34:34 +02:00
Johan Preynat 429431c13c lib/api/deprecate.js: Fix deprecateRenameMethod() 2016-05-02 14:05:11 +02:00
Samy Pessé b80dfd7b9a Add method contentLink as deprecated for plugin API 2016-05-02 13:50:51 +02:00
Samy Pessé 4c144b6ceb Fix Plugins.listAll to handle strings 2016-05-02 13:42:18 +02:00
Samy Pessé 718e32773a Add method removePlugin to ConfigModifier 2016-05-02 13:41:07 +02:00
Samy Pessé fb75d5d3ee Add this.gitbook.version 2016-05-02 13:41:07 +02:00
Samy Pessé 99bbcbebfc Fix modifiers for ebook format 2016-05-02 13:41:07 +02:00
Soreine 289e4b5dc1 Tweak Summary.toText doc 2016-05-02 13:38:51 +02:00
Johan Preynat a974dcdab6 lib/templating/postRender.js: Fix missing argument to engine.getBlock() 2016-05-02 13:32:27 +02:00
Samy Pessé 9a48620152 Document encodeGlobal api 2016-05-02 10:02:46 +02:00
Samy Pessé e444b3a402 Fix launch of livereload server 2016-05-02 09:59:44 +02:00
Samy Pessé fabf4f0c0a Enable livereload plugin when serving content 2016-05-02 09:56:32 +02:00
Samy Pessé d467888d6a Improve timing debug 2016-05-02 09:47:11 +02:00
Samy Pessé eb46311561 getArticleByPath is now a global function for template instead of a filter 2016-05-02 09:38:24 +02:00
Samy Pessé 63839bb0a7 Fix apply of async html modifiers 2016-05-02 09:29:49 +02:00
Samy Pessé 793fada0fb Add test for async template block 2016-05-02 09:19:57 +02:00
Samy Pessé 494ba78156 Complete api method template.applyBlock 2016-05-02 09:14:01 +02:00
Samy Pessé 9816b27ebf Update nunjucks@2.4.2 2016-05-02 09:06:59 +02:00
Samy Pessé 1c43b7891b Log resolved version when installing plugins 2016-05-02 09:02:36 +02:00
Samy Pessé 9d7739213e Remove should from git.js test 2016-05-02 08:57:18 +02:00
Samy Pessé 2ab5f6a305 Fix case of helper/resolveFileToUrl.js 2016-05-02 08:53:32 +02:00
Samy Pesse c73103969f Add signature for api template.applyBlock 2016-05-01 23:27:38 +02:00
Samy Pesse 6cbbdf5d5b Improve spacing when installing plugins 2016-05-01 22:58:25 +02:00
Samy Pesse 3a48435497 Cleanup folder before generating output 2016-05-01 19:35:50 +02:00
Samy Pesse 084925de8b Improve plugin loading to not fake module errors 2016-05-01 19:07:57 +02:00
Samy Pesse 5bac2fe695 Fix #1253: add instructions for generating ebook in docs 2016-05-01 16:15:19 +02:00
Samy Pesse 2c29fb241f Always log timing infos 2016-05-01 15:55:27 +02:00
Johan Preynat 77dc11bcc2 lib/cli/options.js: Return pure JS Array for CLI log options 2016-05-01 12:09:58 +02:00
Samy Pesse 5154622566 Add @soreine and @jpreynat to authors list 2016-04-30 23:50:47 +02:00
Samy Pesse c681cd286a Remove lodash dependency 2016-04-30 23:07:43 +02:00
Samy Pesse c1d53ec11f Switch parsers to a model 2016-04-30 22:06:16 +02:00
Samy Pesse 36b49c66c6 Merge branch 'fixes' 2016-04-30 20:15:08 +02:00
Samy Pesse 80b8e340da Fix add global env to templateEngine 2016-04-30 20:08:04 +02:00
Samy Pesse b51470db39 Add tests for conrefs loader 2016-04-30 20:06:43 +02:00
Samy Pesse a5f4596f8d Add tests for templateEngine 2016-04-30 19:00:35 +02:00
Johan Preynat 5f3c3760c0 lib/models/templateBlock.js: Fix convert blocks to pure JS array before passing to parser.parseUntilBlocks() 2016-04-30 17:05:30 +02:00
Johan Preynat 8b05885d57 lib/models/templateBlock.js: Use function for Ext() instead of var 2016-04-30 17:05:30 +02:00
Johan Preynat d9d7ab4ee5 lib/models/templateBlock.js: Add test file lib/models/__tests__/templateBlock.js 2016-04-30 17:05:30 +02:00
Samy Pesse 30bce5f9bb Add option "--timing" to mesure gitbook performances 2016-04-30 14:37:44 +02:00
Samy Pesse fbe0282738 Add tests for git utility 2016-04-30 12:30:56 +02:00
Samy Pesse 5bad08b9a0 Add this.generator as deprecated 2016-04-30 12:14:43 +02:00
Samy Pesse 310691bca2 Use areIdenticalPaths for Summary.getByPath 2016-04-29 23:43:01 +02:00
Samy Pesse 8f7967acd0 Log page causing error when a bug occurs during generation 2016-04-29 23:32:41 +02:00
Samy Pesse faf18476b1 Don't fail if page doesn't exist 2016-04-29 23:23:54 +02:00
Samy Pesse 9acccad23a Fix validation of configuration for plugins 2016-04-29 23:19:33 +02:00
Samy Pesse db1a0aedf8 Fix listing of plugins when contains "-" 2016-04-29 23:13:31 +02:00
Samy Pesse 01a26fda25 Fix linting error 2016-04-29 20:18:28 +02:00
Samy Pessé 0229272b0a Add api this.readFile and this.readFileAsString 2016-04-29 17:46:59 +02:00
Samy Pessé c817acff09 Add context for page templates 2016-04-29 17:40:35 +02:00
Samy Pessé a5eec81819 Fix context for page template 2016-04-29 17:34:33 +02:00
Samy Pessé 98f70879bd Complete ebook generation using ebook-convert 2016-04-29 16:50:50 +02:00
Samy Pessé ceb4627f4e Use API to create context for filters/blocks 2016-04-29 15:30:56 +02:00
Samy Pessé 8d9d4fe23f Merge remote-tracking branch 'origin/fixes' into fixes 2016-04-29 15:28:01 +02:00
Samy Pessé 730298110c Add ebook commands pdf/mobi/epub 2016-04-29 15:27:53 +02:00
Johan Preynat 8578f7d0d1 lib/api/encodePage.js: Fix deprecated page.progress assignment 2016-04-29 15:16:56 +02:00
Samy Pessé 07a5daefb0 Generate SUMMARY.html for ebook output 2016-04-29 15:09:11 +02:00
Samy Pessé 0ed524bce5 Correctly setup configuration for plugins in multilingual books 2016-04-29 15:08:54 +02:00
Johan Preynat 94199af7b2 Add location.areIdenticalPaths(p1,p2) to effectively compare two paths 2016-04-29 14:38:12 +02:00
Johan Preynat b8d7a00f58 Find installed gitbook-plugins in node_modules folder 2016-04-29 14:38:12 +02:00
Johan Preynat aca963befc Fix typo 2016-04-29 14:38:12 +02:00
Samy Pessé 3ea4e334bf It should generate index for languages 2016-04-29 13:04:54 +02:00
Samy Pessé 9955fa8c29 Use plugin assets from parent when language book 2016-04-29 12:46:31 +02:00
Samy Pessé fb37a6bcab Inherit plugins list from parent output when generating multilingual book 2016-04-29 11:31:54 +02:00
Samy Pessé 4f8bdbb518 Add tests for parsing a book with option "root" 2016-04-29 11:11:42 +02:00
Samy Pessé 73c190891d Fix parsing of multilingual books 2016-04-29 10:58:25 +02:00
Samy Pessé 93e701f471 Complete deprecated page.progress and this.navigation 2016-04-29 10:17:16 +02:00
Samy Pesse 68b9bf7e38 Encode navigation for compatibility with gitbook v2 2016-04-28 22:45:50 +02:00
Samy Pesse 826f90505c Add command "init" 2016-04-28 21:25:58 +02:00
Samy Pessé 7ae36f16c8 Add base for deprecated page.naviation 2016-04-28 15:45:25 +02:00
Samy Pessé 281f6d5535 Extend timeout for tests 2016-04-28 15:36:54 +02:00
Samy Pessé b4072a06c4 Add basic tests for website generator 2016-04-28 15:28:46 +02:00
Samy Pessé cb3ee423c9 Add basic tests for json generator 2016-04-28 15:20:25 +02:00
Samy Pessé 1360a744a7 Export more models 2016-04-28 15:02:24 +02:00
Samy Pessé f3058598dc Always generate a README.json as introduction of json output 2016-04-28 14:42:07 +02:00
Samy Pessé 94db0f6ec9 Fix typo in JSONUtils.encodeBook 2016-04-28 14:39:11 +02:00
Samy Pessé f08732095d Copy readme.json from main language for json output of multilingual 2016-04-28 14:37:19 +02:00
Samy Pessé f946650ddb Add "next" and "previous" to page JSON repr 2016-04-28 14:28:41 +02:00
Samy Pessé 14fd6bbdce Add tests for PathUtils 2016-04-28 14:16:15 +02:00
Samy Pessé 5059e8df34 Add modifiers to edit article and insert in summary 2016-04-28 14:12:21 +02:00
Samy Pessé 3d405a1ac5 Fix ref in summary when parsed without ref 2016-04-28 14:03:58 +02:00
Samy Pessé 78e00db018 Add tests for SummaryModifier.editPartTitle 2016-04-28 11:35:30 +02:00
Samy Pessé e62bc31e63 Add method setSummary to book 2016-04-28 11:17:33 +02:00
Samy Pessé 4763f1342c Add base modifiers for summary as SummaryModifier 2016-04-28 11:15:51 +02:00
Samy Pessé 9413e53b00 Add tests for parseIgnore 2016-04-28 10:37:52 +02:00
Samy Pessé 35d352bbeb Handle correctly ignored file in multilanguages book 2016-04-28 09:59:34 +02:00
Samy Pesse 8dd5e0c250 Add comments for todos 2016-04-27 22:42:09 +02:00
Samy Pesse 139e487998 Correctly resolve images starting with / 2016-04-27 22:36:59 +02:00
Samy Pesse 9bb0a3fbd3 Add tests for svg inliner 2016-04-27 22:18:33 +02:00
Samy Pessé 9a1a6f2625 Document cli/server.js 2016-04-27 18:02:49 +02:00
Samy Pessé e781d6d2b1 Add test for assets inliner 2016-04-27 17:58:35 +02:00
Samy Pessé 5b342b50ce Add language property to book for multilingual 2016-04-27 16:41:17 +02:00
Samy Pessé 869822d180 Use orderedMap for language books 2016-04-27 16:26:16 +02:00
Samy Pessé e50422bce5 Use code TemplateBlock to highlight code 2016-04-27 16:22:17 +02:00
Samy Pessé 999882e723 Add test for highlightCode html modifier 2016-04-27 15:42:55 +02:00
Samy Pessé d68dc82159 Merge remote-tracking branch 'origin/fixes' into fixes 2016-04-27 15:12:25 +02:00
Samy Pessé cc9fdd0032 Generate multilingual books 2016-04-27 15:12:18 +02:00
Soreine 503cc4a729 Check for stdout, for browser compatibility 2016-04-27 14:52:26 +02:00
Samy Pessé d585269228 Correctly ignore summary and templates from assets 2016-04-27 14:37:02 +02:00
Samy Pessé 50f535b910 Fix plugin's config validation 2016-04-27 14:31:45 +02:00
Samy Pessé 978bdd149e Add browser specific index.js 2016-04-27 14:18:23 +02:00
Samy Pessé a9d558e891 Add method ".toText" on glossary and summary 2016-04-27 14:11:45 +02:00
Samy Pessé 8291eb58df Complete api method output.toURL 2016-04-27 13:53:32 +02:00
Samy Pessé 7298dec353 Add plugins.resources for template context 2016-04-27 13:47:12 +02:00
Samy Pessé 7574b01863 Merge remote-tracking branch 'origin/fixes' into fixes 2016-04-27 13:13:38 +02:00
Samy Pessé 98e739a12b Add JS context for template 2016-04-27 13:13:27 +02:00
Soreine 262ce03e46 Exposes FS in public interface 2016-04-27 13:12:51 +02:00
Samy Pessé 1906691a35 Fix order of plugins assets copy 2016-04-27 12:48:40 +02:00
Samy Pessé 4ca23b84a4 Fix filters for theme templates 2016-04-27 12:08:00 +02:00
Samy Pessé b05eb8440b Don;t log deprecation warning for own logic 2016-04-27 10:38:54 +02:00
Samy Pessé f4de7748f5 Complete generator name in plugins API 2016-04-27 09:59:09 +02:00
Samy Pessé 93c26a839b Add this.book and this.options as deprecated 2016-04-27 09:42:40 +02:00
Samy Pesse 878e7441f2 Stop running test on node 0.12 for windows 2016-04-26 23:19:19 +02:00
Samy Pesse 27d387e3e1 Load i18n translations 2016-04-26 21:48:56 +02:00
Samy Pesse 7b7e4f60bc Correctly set log level 2016-04-26 20:49:20 +02:00
Samy Pesse 8bac111acf Add base for plugin JS api 2016-04-26 17:02:59 +02:00
Samy Pesse 7a46d3b497 Add command "serve" 2016-04-26 15:51:52 +02:00
Samy Pesse 357aa92e31 Add default filters to theme templating engine 2016-04-26 15:50:11 +02:00
Samy Pesse fa17f16716 Add base for commands
Improve plugins installation
2016-04-26 15:23:28 +02:00
Samy Pesse ce99c8c706 Add more tests for summary 2016-04-26 14:25:54 +02:00
Samy Pesse be828cf004 Add duration to final log for generation 2016-04-26 14:12:26 +02:00
Samy Pesse 1057bb15d3 Complete method getByPath of Summary 2016-04-26 13:03:53 +02:00
Samy Pesse ea5e8891a8 Add test for readme parsing 2016-04-26 11:17:47 +02:00
Samy Pesse 57d83f082a Add basic tests for summary parsing 2016-04-26 11:15:50 +02:00
Samy Pesse 8a3f80ba82 Add test for parsing glossary 2016-04-26 11:00:36 +02:00
Samy Pesse 374ebd6f7a Add mock fs and tests for it 2016-04-26 10:23:37 +02:00
Samy Pesse ab2ebefe2b Copy resources from plugins to output folder 2016-04-25 22:30:41 +02:00
Samy Pesse c34a9f6213 Copy assets from themes to output folder 2016-04-25 21:13:17 +02:00
Samy Pessé f5df41c75f Enable extension "do" 2016-04-25 15:44:20 +02:00
Samy Pessé 0c2dc06cb7 Fix resolution of theme's templates 2016-04-25 15:36:18 +02:00
Samy Pessé 4552ccd7d7 Add loader for themes 2016-04-25 14:44:49 +02:00
Samy Pessé 525bcd8295 Disable travis tests on 0.12 2016-04-25 14:37:49 +02:00
Samy Pessé ac2ad8d8b5 Add conrefs loader for templating 2016-04-25 14:29:51 +02:00
Samy Pessé 14ce495e9e Add more tests for LocationUtils 2016-04-25 14:15:28 +02:00
Samy Pessé 4aed2cf652 Add post processing for templates 2016-04-25 13:52:56 +02:00
Samy Pessé 244fb0ca28 Replace shortcuts in templating 2016-04-25 12:24:59 +02:00
Samy Pessé f6e123f1ed Add base rendering for template 2016-04-25 11:58:55 +02:00
Samy Pessé e1e4e7f011 Add tests for link resolution 2016-04-25 11:28:21 +02:00
Samy Pessé 814b6ff489 Complete json format 2016-04-25 11:05:06 +02:00
Samy Pessé 3aa17ab1f4 Convert markdown to html for pages 2016-04-25 10:58:10 +02:00
Samy Pessé 4646ed8f4a Fix plugins loading 2016-04-25 10:32:44 +02:00
Samy Pesse 3f5c8acb3c Add fiel for testing resolveLinks 2016-04-24 23:45:47 +02:00
Samy Pesse 93b257314a Add default filters and blocks 2016-04-24 19:12:03 +02:00
Samy Pesse 19a1db8cb4 Add base structure for templating 2016-04-24 18:52:37 +02:00
Samy Pesse c3275a4aa9 Parse multilingual books 2016-04-24 00:15:38 +02:00
Samy Pesse 927185d95c add test for modifier "annotateText" 2016-04-23 23:58:08 +02:00
Samy Pesse a3df6c6f0c Add assets inliner modifier for HTML 2016-04-23 21:10:53 +02:00
Samy Pesse e1fa977b5b Add json encoding utils 2016-04-23 17:10:16 +02:00
Samy Pesse ce95f316b9 Add method to be article by level 2016-04-23 11:22:20 +02:00
Samy Pessé a162af5a75 Add base for calling hook on page/global 2016-04-22 22:58:37 +02:00
Samy Pessé fb0ea4610d Add base utils for generation 2016-04-22 22:21:34 +02:00
Samy Pessé 4f86a9978b Add test for config 2016-04-22 11:56:34 +02:00
Samy Pessé cc78b880ce Add utils to install plugins 2016-04-22 11:33:25 +02:00
Samy Pessé 4336fdb241 Base 2016-04-22 11:00:21 +02:00
Samy Pessé 87db7cf1d4 Merge remote-tracking branch 'origin/master' 2016-04-20 17:26:49 +02:00
Samy Pessé 09ff802c7e When using structure.readme, fix link to readme to resolve to index.html 2016-04-20 17:26:13 +02:00
Johan Preynat 71b59b1950 Correctly detect promises from block.process in TemplateEngine.applyBlock() 2016-04-20 15:59:53 +02:00
Samy Pessé a3300ad9c6 Comment template code 2016-04-20 15:02:39 +02:00
Samy Pessé 8f40d4affa Fix reliability of template.self in macro import 2016-04-20 10:03:04 +02:00
Samy Pessé 560f3fcccb Update plugin-search@2.2.0 2016-04-20 09:42:11 +02:00
Samy Pesse ecaadf63c5 Correctly ignore structure file (only in root folder) 2016-04-20 00:06:45 +02:00
Samy Pesse d490a6e0b4 Correctly load plugins when using "root" option 2016-04-19 17:40:01 +02:00
Samy Pesse 53ced205b8 Ensure "template" is always set when rendering a template 2016-04-19 15:46:37 +02:00
Samy Pesse 61c4983949 Fix template context should be global in nunjucks for theming
Fix pdf_footer and pdf_header template not rendering
2016-04-19 15:33:35 +02:00
Samy Pesse fb862f466f Bump version to 3.0.0-pre.9 2016-04-19 14:18:01 +02:00
Samy Pesse 8d51300386 Bump version to 2.1.0 2016-04-19 14:16:51 +02:00
Samy Pesse c4b413563d Update theme-default@1.0.0-pre.8 2016-04-19 14:14:59 +02:00
Samy Pesse 8f852971f9 Cleanup book.js 2016-04-19 14:12:01 +02:00
Johan Preynat 3c54c89464 Use page.content if modified or fallback to page.sections in plugins hooks 2016-04-19 10:02:41 +02:00
Samy Pessé d07aa13822 Add tests for page hook 2016-04-18 17:14:55 +02:00
Samy Pessé c218f7d0e3 Correctly set template.self in all cases 2016-04-18 16:56:50 +02:00
Samy Pessé 72ad872e90 Fix js error when using output without root 2016-04-18 14:26:24 +02:00
Samy Pessé 854f244d22 Fix infinite loop on this.options 2016-04-18 14:17:51 +02:00
Samy Pessé 9acbb223db Add generator and output property as deprecated in config 2016-04-18 14:16:22 +02:00
Johan Preynat c59fc687db Ensure plugins compatibility with page.sections 2016-04-18 14:10:19 +02:00
Samy Pessé 0791b917f1 Add context for readme 2016-04-18 12:49:31 +02:00
Samy Pessé ba182ce8e4 Fix tests for copy of website theme 2016-04-15 11:33:38 +02:00
Samy Pessé 663291c515 Output context as global for themes 2016-04-15 11:33:24 +02:00
Samy Pessé 99253eecea Bump version to 3.0.0-pre.8 2016-04-14 15:02:49 +02:00
Samy Pessé 916a02cb36 Update plugins search@2.0.0 and theme-default@1.0.0-pre.7 2016-04-14 15:00:25 +02:00
Samy Pessé 114c4abcd1 Add method for theme: template.getJSContext 2016-04-14 14:51:42 +02:00
Samy Pessé e1e3d11932 Add lunr as default plugin 2016-04-14 14:51:22 +02:00
Samy Pessé df46217c78 Improve description extraction and adapt unit tests 2016-04-14 10:07:51 +02:00
Samy Pessé d18cc92396 Pass template to block's context 2016-04-14 09:51:56 +02:00
Samy Pessé 8f63b4b790 Remove unused variable 2016-04-13 17:32:01 +02:00
Samy Pessé ce7de93936 Improve block parsing to handle args/kwargs on subblocks 2016-04-13 16:22:53 +02:00
Johan Preynat ef2a24fe6f Add trailing dots to page.description when longer than 300 characters 2016-04-13 16:00:16 +02:00
Samy Pessé 038cd0155b Add filter "getArticleByPath" for theme templates 2016-04-13 11:48:29 +02:00
Samy Pessé fb430ac1ed Increase size of extracted description 2016-04-13 10:55:32 +02:00
Johan Preynat 53cfa3703b Update page context for plugins hooks 2016-04-13 09:33:26 +02:00
Johan Preynat 7ed9e8d145 Update plugin-fontsettings@1.0.3 / plugin-sharing@1.0.2 2016-04-12 17:05:32 +02:00
Samy Pessé 93e0b0cbea Watch _layouts when serving 2016-04-12 13:53:58 +02:00
Samy Pessé 0118bd3168 Cleanup code to list plugins 2016-04-11 12:29:53 +02:00
Samy Pessé 07d5245a5f Bump version to 3.0.0-pre.7 2016-04-11 09:59:58 +02:00
Samy Pessé 6b844213ec Update theme-default@1.0.0-pre.6 2016-04-11 09:59:18 +02:00
Samy Pessé dabdeb8a80 Fix #1195: fix external images and fix test for it 2016-04-11 09:56:13 +02:00
Samy Pessé ecd56315e6 Merge pull request #1220 from seanlane/patch-1
Fix minor spelling error.
2016-04-11 09:34:15 +02:00
Sean Lane 15b9e839e9 Fix minor spelling error. 2016-04-10 14:31:49 -06:00
Samy Pesse d7f7dcd47b Switch to ignore@3.1.1 2016-04-10 22:28:29 +02:00
Samy Pessé b1981e09b8 Fix generator deprecation warning being shown for each call 2016-04-10 18:20:51 +02:00
Samy Pessé c9edd0a795 Load plugins from book parent in multilingual book 2016-04-09 12:16:17 +02:00
Samy Pesse d83e0716bb Add test for main language in json output 2016-04-08 23:58:42 +02:00
Samy Pessé aed38afff3 Bump version to 3.0.0-pre.6 2016-04-08 16:35:35 +02:00
Samy Pessé 1df522e6ec Update node modules 2016-04-08 16:34:53 +02:00
Samy Pessé bd4ef2354e Merge pull request #1216 from GitbookIO/fix/ignore
Fix #1215: fix ignore rules not working
2016-04-08 15:48:33 +02:00
Samy Pessé 32a49a6969 Inherit ignore rules of output from book 2016-04-08 15:46:46 +02:00
Samy Pessé 21806687e6 Add base tests for fiailng ignore 2016-04-08 15:23:46 +02:00
Samy Pessé 7ade91a091 Disable ssh test when ci 2016-04-08 15:11:54 +02:00
Samy Pessé 4e41f96d89 Add "languages" property to all json files for multilingual book 2016-04-08 14:42:37 +02:00
Johan Preynat 325c32b4c9 Update gitbook-plugin-highlight@2.0.2 2016-04-06 10:50:03 +02:00
Samy Pessé 7d6606a8e5 Merge pull request #1202 from qjcg/patch-1
Proofreading
2016-04-06 09:19:37 +02:00
Samy Pessé c887d520eb Update github-slugid@1.0.1 2016-04-04 11:05:42 +02:00
John Gosset e6050fc558 Proofreading
A few proofreading changes with clarity in mind.
2016-03-31 13:23:15 -04:00
Samy Pessé cae4853334 Merge pull request #1194 from jashaj/master
Fix for incorrect splitting the plugin name/version
2016-03-24 21:50:26 +01:00
Jasha Joachimsthal 9ef2bebfe9 Misinterpreted second argument of String.prototype.split. Remainder of the array must be joined instead. 2016-03-24 21:21:23 +01:00
Samy Pessé 53294af810 Merge pull request #1192 from jashaj/master
Limit splitting plugin name for git with authentication
2016-03-24 16:54:29 +01:00
Jasha Joachimsthal 7d21c815a5 Limit splitting plugin name for git+ssh 2016-03-24 15:23:28 +01:00
Samy Pessé e07719a86c Fix template search paths to use plugins listed first 2016-03-22 10:59:25 +01:00
Soreine fa5bee6ca3 Import paragraph about Escaping nunchuck from old doc. 2016-03-21 15:07:22 +01:00
Samy Pessé 3a43ef2c3f Add doc for inline rendering 2016-03-18 11:55:24 +01:00
Samy Pessé 55deab03cd Add test for blocks markdown/asciidoc/markup 2016-03-18 11:26:31 +01:00
Samy Pessé edda84fefd Add block "markdown", "asciidoc" and "markup" 2016-03-18 11:20:57 +01:00
Samy Pessé 10b191f631 Use stabler block anchor in template output 2016-03-18 11:17:26 +01:00
Samy Pessé d5a575c5e0 Fix context for template block/filters 2016-03-18 11:14:04 +01:00
Samy Pessé 82d8c3e2d9 Add method renderInline and renderBlock to book 2016-03-18 11:10:58 +01:00
Samy Pessé bc0c8dbcf3 Update nunjucks@2.4.1 2016-03-18 11:07:21 +01:00
Samy Pessé de0245ff40 Update nunjucks@2.4.1 2016-03-18 11:03:22 +01:00
Samy Pessé 7f56ff0281 Fix doc for paragraph 2016-03-17 11:53:28 +01:00
Samy Pessé 2cfbf5411c Add question about text direction in the faq 2016-03-17 10:41:34 +01:00
Samy Pessé f70da1c82a Fix links in readme 2016-03-15 12:40:40 +01:00
Samy Pessé 0b4db49f57 Merge pull request #1181 from GitbookIO/feature/allplugins_tpl
All plugins can extend templates/theme
2016-03-15 12:37:52 +01:00
Samy Pessé fbffd54aa2 Load all plugins, even dependencies of plugins 2016-03-15 12:37:25 +01:00
Samy Pessé 4d19a33af2 Add method registry.list to list all plugins for a book 2016-03-15 11:43:37 +01:00
Samy Pessé 9d67a0e656 Add theme for extending theme from book 2016-03-11 11:21:47 +01:00
Samy Pessé 093005bfd9 Fix FSLoader for relative paths 2016-03-11 10:51:36 +01:00
Samy Pessé 514883f0bd Create new loader for nunjucks to avoid infinite loop 2016-03-11 10:43:37 +01:00
Samy Pessé 27681aad98 Update nunjucks@2.4.0 2016-03-11 10:20:26 +01:00
Samy Pessé 0d367da776 Use complete list of plugins for templates resolution / i18n / assets 2016-03-09 16:45:27 +01:00
Samy Pessé c499a8a13a Add back gitbook.generator property as deprecated 2016-03-09 15:50:38 +01:00
Samy Pessé 64a6de751d Change documentation's title 2016-03-09 15:22:04 +01:00
Samy Pessé d39f0d6ff0 Add "output" variables for templating 2016-03-09 15:18:57 +01:00
Samy Pessé bdbfbf7300 Merge doc for ebook and cover 2016-03-09 11:10:52 +01:00
Samy Pessé ccac3d2c3c Publish compleet reference of markdown syntax for gitbook 2016-03-08 17:26:36 +01:00
Samy Pessé f07278490f Add question about rtl to faq 2016-03-08 09:26:46 +01:00
Samy Pessé f1880fc53c Fix incorrect link in themes doc 2016-03-07 15:20:27 +01:00
Samy Pessé e8fe4a2dea Improve docs for plugins 2016-03-07 15:15:41 +01:00
Samy Pessé 1d79507665 Add book to templating context 2016-03-07 14:52:30 +01:00
Samy Pessé f05dc67887 Improve version suggestion 2016-03-07 14:06:58 +01:00
Samy Pessé ca5e57c3b7 Bump version to 3.0.0-pre.5 2016-03-07 12:26:52 +01:00
Samy Pessé 6b1fabdd92 Update theme-default@1.0.0-pre.5 2016-03-07 12:26:22 +01:00
Samy Pessé 35f0581c17 Bump version to 3.0.0-pre.4 2016-03-07 11:16:43 +01:00
Samy Pessé c79f02fe48 Add sitemap plugin for docs 2016-03-07 11:16:27 +01:00
Samy Pessé ec028a1c0d Add deprecated methods isSubBook and contentPath 2016-03-07 11:16:13 +01:00
Samy Pessé e3155dd13a Update plugin-search@1.2.0 2016-03-07 11:00:16 +01:00
Samy Pessé b61254dda6 Add more deprecated api 2016-03-07 11:00:01 +01:00
Samy Pessé b4bdf97cfe Fix linting errors 2016-03-07 10:40:25 +01:00
Samy Pessé bf98984012 Add link to slack 2016-03-07 10:28:44 +01:00
Samy Pessé 77258cbbc9 Improve intro for doc 2016-03-07 10:27:31 +01:00
Samy Pessé 4150455c3e Improve docs 2016-03-07 10:10:38 +01:00
Samy Pessé 008aacb5c2 Fix log when installing plugins 2016-03-07 09:41:59 +01:00
Samy Pessé d12d6a6a46 Fix deprecated method root for send module 2016-03-07 09:41:05 +01:00
Samy Pessé ef7594b8f7 Remove section about autocover 2016-03-07 09:38:56 +01:00
Soreine 6a73217740 Adds section for covers 2016-03-06 09:08:48 +01:00
Samy Pesse 47c44fca89 Add changelog for master 2016-03-05 22:39:11 +01:00
Samy Pesse 6fa63a5c35 Fix #1172: Fix second argument for ebook generation 2016-03-05 22:37:25 +01:00
Samy Pessé 29533908c2 Merge pull request #1168 from GitbookIO/enhancement/doc
v3 doc review
2016-03-05 15:14:17 +01:00
Soreine 74a1e9dee2 Corrects paths. And reformulate associated FAQ 2016-03-03 16:39:18 +01:00
Soreine b3662e07c1 End of review 2016-03-03 16:39:18 +01:00
Soreine 200e0c58c9 More precise git url ? 2016-03-03 16:39:17 +01:00
Soreine e67286c51d Reviewing, first part 2016-03-03 16:39:17 +01:00
Soreine 603622e337 Update plugin-highlight version to 2.0.0 2016-03-03 16:38:09 +01:00
Samy Pessé 5c2a435a25 Update everything (npm, etc) 2016-03-02 11:22:24 +01:00
Samy Pessé 4afcd722ae Fix page description tests 2016-03-02 11:22:12 +01:00
Samy Pessé 21d6964230 Extend "page" with frontmatter attributes 2016-03-02 11:11:39 +01:00
Samy Pessé 4499ccc501 Explicitly use current version as gitbook version to build 2016-03-02 10:01:32 +01:00
Samy Pessé abbca568d1 Bump version to 3.0.0-pre.3 2016-03-02 09:29:30 +01:00
Samy Pesse 40e49d0ac9 Change json format version to follow major version of gitbook 2016-03-01 22:29:09 +01:00
Samy Pessé 8d9a0a91f0 Add test for plugin installation from github 2016-03-01 16:51:47 +01:00
Samy Pessé 15640dfdf0 Add lint to jsonlint 2016-03-01 16:31:29 +01:00
Samy Pesse 2f5dde5d2f Fix links in documentation 2016-02-29 22:00:55 +01:00
Samy Pesse a9a8a04bca Tweaks in documentation 2016-02-29 21:59:05 +01:00
Samy Pesse c08e5ce62c Improve structure of doc 2016-02-29 21:50:48 +01:00
Samy Pessé ec353e179d Remove .gitbook and add "root" option 2016-02-29 17:35:12 +01:00
Samy Pessé 496f253e69 Don't copy _layouts to output 2016-02-29 10:43:53 +01:00
Samy Pessé e436115a4a Bump version to 3.0.0-pre.2 2016-02-29 09:16:00 +01:00
Samy Pessé 1c61f93b5f Add simple test for exports 2016-02-29 09:14:43 +01:00
Samy Pessé 0494f7d1fd Fix #1165: correctly normalize path in summary to accept unicode 2016-02-28 21:54:03 +01:00
Samy Pessé 4aa66338fc Add init command 2016-02-28 14:47:34 +01:00
Samy Pessé 8cda844ef1 Export output for plugins context 2016-02-28 12:46:47 +01:00
Samy Pesse dde1ef92f0 Add doc for ls-remote 2016-02-27 22:47:42 +01:00
Samy Pesse 999f8b481f Improve setup doc 2016-02-27 22:45:30 +01:00
Samy Pessé 294951f22a Change note in changelog 2016-02-26 10:07:11 +01:00
Samy Pessé 2619737f64 Bump version to 3.0.0-pre.1 2016-02-26 10:06:11 +01:00
Samy Pessé 445a90defb Simplify readme 2016-02-26 10:05:20 +01:00
Samy Pessé d3d64f636c Merge pull request #1109 from GitbookIO/3.0.0
Version 3.0.0
2016-02-26 09:41:26 +01:00
Samy Pessé eef072693b Update theme-default@1.0.0-pre.4 2016-02-26 09:40:58 +01:00
Samy Pessé 43c5f8d340 Don't add glossary to context when non existant 2016-02-26 09:25:11 +01:00
Samy Pessé b344d65302 Fix exec of svgexport on windows 2016-02-25 20:32:08 +01:00
Samy Pessé ce967f35ca Fix error message when svgexport is not installed 2016-02-25 19:21:27 +01:00
Samy Pessé 80718cc783 Fix some path normalization on windows 2016-02-25 19:15:47 +01:00
Samy Pessé 73f22332ec Update theme-default@1.0.0-pre.3 2016-02-25 16:39:25 +01:00
Samy Pessé e963b6b65d Add documentation for front matter 2016-02-25 16:37:40 +01:00
Samy Pessé 327e90e8ec Extract description from page's front matter
Fixes #1079 and #795
2016-02-25 15:43:55 +01:00
Samy Pessé 9253b764fa Don't pass cover to ebook-convert if non existant 2016-02-25 15:12:04 +01:00
Samy Pessé 393aed6270 Improve error msg for ebook generation 2016-02-25 15:09:57 +01:00
Samy Pessé b240d6a8fc Add filter fileExists 2016-02-25 14:50:58 +01:00
Samy Pessé 3cda0643fb Improve command "parse" 2016-02-25 14:45:16 +01:00
Samy Pessé 1ba63675d5 Support "sections" from gitbook 2 as deprecated for page hooks 2016-02-25 14:41:46 +01:00
Samy Pessé 32f52f2d95 Call page hooks during transformation to HTML 2016-02-25 14:26:27 +01:00
Samy Pessé 9215edc0a0 Remove option defaultPlugins and simplify loading 2016-02-25 14:17:31 +01:00
Samy Pessé 25ae21dae3 Call hook "init" during generation 2016-02-25 12:18:40 +01:00
Samy Pessé 94393bef4b Call hooks finish and finish:before 2016-02-25 12:13:31 +01:00
Samy Pessé 4f29183685 Document pdf options 2016-02-25 12:10:58 +01:00
Samy Pessé edecf56dd6 Use hook for configuration 2016-02-25 12:03:33 +01:00
Samy Pessé 08754bc626 Improve the faq 2016-02-25 11:59:45 +01:00
Samy Pessé 702542f408 Remove duplicate between book.* and config.* 2016-02-25 11:50:20 +01:00
Samy Pessé 6990b371a6 Add link to doc about .gitbook in faq 2016-02-25 11:47:41 +01:00
Samy Pessé 8020d9045b Improve header with edit button and version 2016-02-25 11:44:55 +01:00
Samy Pessé 34bb52a051 Improve templating documentation 2016-02-25 11:38:54 +01:00
Samy Pessé a2e0bc267c Improve documentation 2016-02-25 11:15:59 +01:00
Samy Pessé d86a95b5e1 Add json format version to the json output 2016-02-25 10:51:58 +01:00
Samy Pessé 585ed46034 Change "description" to "title" in config schema 2016-02-25 10:24:32 +01:00
Samy Pessé 82a4f80cd2 Use jsonschema to validate configuration 2016-02-25 10:12:46 +01:00
Samy Pessé f47a3968b7 Add tests for multilingual book and json output 2016-02-25 08:59:10 +01:00
Samy Pesse 0b592dd5c6 Add doc about languages 2016-02-24 23:02:00 +01:00
Samy Pesse addf6ade9a Add doc for glossary 2016-02-24 22:51:32 +01:00
Samy Pesse d7d0429169 Add doc section about summary 2016-02-24 22:42:11 +01:00
Samy Pesse 4bf5dc6646 Add section about ignoring files 2016-02-24 22:29:19 +01:00
Samy Pessé 5b20027f2e Use cover file from main book in multilingual book (when no cover is set for language) 2016-02-24 18:24:49 +01:00
Samy Pessé 4499f71dba Improve log when generation is finished 2016-02-24 18:12:23 +01:00
Samy Pessé 81b734c151 Fix generation of ebooks in multilanguages 2016-02-24 18:11:01 +01:00
Samy Pessé 0b4a6b5362 Output folder is an option for FolderOutput 2016-02-24 18:07:17 +01:00
Samy Pessé 3a0636046e Fix binding to context for plugin blocks 2016-02-24 17:20:48 +01:00
Samy Pessé 52eccb29e4 Add property depth to article and pages 2016-02-24 17:19:52 +01:00
Samy Pessé 86e4a935e2 Improve logging 2016-02-24 17:12:38 +01:00
Samy Pessé 1fa952b930 Fix inclusion of block using a simple function 2016-02-24 17:02:34 +01:00
Samy Pessé 78e11bc6be By default escape html in code blocks 2016-02-24 16:53:46 +01:00
Samy Pessé 40cc20e06e Load plugins once 2016-02-24 16:53:33 +01:00
Samy Pessé c223f970ec Rollback to gitbook-markdown@1.0.3 2016-02-24 16:29:12 +01:00
Samy Pessé daa80dc949 Fix conrefs loader with filename starting with / 2016-02-24 14:20:53 +01:00
Samy Pessé 255a78a534 Fix path option for template error 2016-02-24 14:10:37 +01:00
Samy Pessé 6faa469bf5 Fix install command: load config before running install 2016-02-24 14:06:56 +01:00
Samy Pessé eeefac4964 Update gitbook-markdown@1.1.1 2016-02-24 13:57:09 +01:00
Samy Pessé eb4770085a Update gitbook-markdown@1.1.0 2016-02-24 13:53:57 +01:00
Samy Pessé 1ed63ce4f5 Add context for multi-lingual books 2016-02-24 13:52:15 +01:00
Samy Pessé e85ad95bcf Generate multi-lingual index 2016-02-24 13:35:59 +01:00
Samy Pessé bd73c79787 Don't copy assets for each language book, but only for main book 2016-02-24 12:56:26 +01:00
Samy Pessé b244d506bd Correctly setup summary instance when file doesn't exist 2016-02-24 12:45:25 +01:00
Samy Pessé 44f03865c0 Add changelog for .gitbook 2016-02-24 12:14:20 +01:00
Samy Pessé 72dfb4f11d Ignore etst plugins and docs when linting 2016-02-23 15:26:28 +01:00
Samy Pessé 6b0a4f20bf Add documentation for .gitbook 2016-02-23 15:25:50 +01:00
Samy Pessé f052aacee1 Add .gitbook to locate book inside repository 2016-02-23 15:05:32 +01:00
Samy Pesse 13e2ff8035 Adapt test for paths to run on windows 2016-02-22 23:52:38 +01:00
Samy Pesse 199e61e01c Remove pdf file 2016-02-22 23:51:22 +01:00
Samy Pessé 1bf6abf338 Pass options to context of theme 2016-02-22 16:58:47 +01:00
Samy Pessé c7b1d72bf0 Add basic test for ebook generation 2016-02-22 15:46:53 +01:00
Samy Pessé 0b3bdcb219 Add tests for blocks from plugins 2016-02-22 15:39:36 +01:00
Samy Pessé 6653307fda Add tests for context of filters 2016-02-22 15:34:35 +01:00
Samy Pessé 642ba72a1d Load all filters and blocks from plugins in output's template 2016-02-22 14:50:55 +01:00
Samy Pessé 71144db09c Normalize context for plugins 2016-02-22 13:54:52 +01:00
Samy Pessé 395bd62663 Provide "plugins" context to theme templates 2016-02-22 12:31:02 +01:00
Samy Pessé d8fd6430ed Copy plugins resources to website output 2016-02-22 11:15:34 +01:00
Samy Pessé 1e243281c7 Add test for resources listing 2016-02-22 10:36:28 +01:00
Samy Pessé de23494409 Change gitignore to commit tests plugins 2016-02-22 10:20:43 +01:00
Samy Pessé b23d3a9f37 Add test for extension of book's configuration 2016-02-22 10:16:38 +01:00
Samy Pessé de31b90080 Add validation of plugin's config after loading 2016-02-22 10:11:44 +01:00
Samy Pessé ccc585ca1f Add doc for plugins 2016-02-22 08:59:19 +01:00
Samy Pessé 4dbe81cb66 Add base changelog 2016-02-22 08:54:46 +01:00
Samy Pessé d139d1d1bd Add "template.theme" and "template.default" variables 2016-02-21 19:41:38 +01:00
Samy Pessé a186544fad Add defaults filters to website tpl engine 2016-02-21 19:28:20 +01:00
Samy Pessé 7de152539d Fix order of search paths for nunjucks 2016-02-21 19:08:39 +01:00
Samy Pessé 1e486a16bd Update theme-default@1.0.0-pre.2 2016-02-21 18:48:50 +01:00
Samy Pessé 7f9c24eedb Fix test for file.mtime 2016-02-21 18:43:37 +01:00
Samy Pessé 8a3396deba Add releases notes to documentation 2016-02-21 18:38:27 +01:00
Samy Pessé 96d5b37196 Update 1.0.0-pre.1 of theme-default 2016-02-21 18:38:11 +01:00
Samy Pessé 7b2e332f6c Complete ebook command to output one file 2016-02-21 18:33:07 +01:00
Samy Pessé ab541c1653 Fix generation of pdf header/footer 2016-02-21 18:23:59 +01:00
Samy Pessé 5f058f2ceb Disable directoryIndex for ebook generation 2016-02-21 18:08:36 +01:00
Samy Pessé 360381dd9f Fix write of SUMMARY.html in ebook format 2016-02-21 17:48:06 +01:00
Samy Pessé cef4096b39 Add cli commands to build ebooks 2016-02-21 17:24:26 +01:00
Samy Pessé a9c96c1afa Fix resolve of relatives images in assets inliner 2016-02-21 17:23:07 +01:00
Samy Pessé a446deaff3 Complete generator for ebooks 2016-02-21 15:52:04 +01:00
Samy Pessé e5dd987d03 Add i18n filter fro themes 2016-02-21 13:29:17 +01:00
Samy Pessé 51fd8ae08c Simplify .next and .prev for articles 2016-02-21 12:05:31 +01:00
Samy Pessé 884540e565 Fix .next and .prev for summary's articles to use parts 2016-02-21 11:56:14 +01:00
Samy Pessé ca1313e891 Extend configuration with infos from readme 2016-02-21 11:28:55 +01:00
Samy Pessé 8df18746fa Add debug log when copying theme 2016-02-21 11:22:41 +01:00
Samy Pessé 40f829ce54 Add docs for setup gitbook 2016-02-21 11:01:49 +01:00
Samy Pessé e16b3e35f4 Setup summary for documentation 2016-02-21 01:02:38 +01:00
Samy Pessé 2f15e26ffa Fix context for templating and page 2016-02-21 01:02:20 +01:00
Samy Pessé b4cdbc6534 Add custom filters for dates to templating engine 2016-02-21 00:42:11 +01:00
Samy Pessé 0a93ffd76b Ignore node_modules during login 2016-02-21 00:33:10 +01:00
Samy Pessé 98e9848c4a Add title to summary's parts 2016-02-21 00:28:59 +01:00
Samy Pessé 42bb5fccb8 Change glossary to enforce use of h2 2016-02-20 17:39:11 +01:00
Samy Pessé fb921788b9 Fix page.toHTML by using .content directly 2016-02-20 17:35:10 +01:00
Samy Pessé 847c6b9aa2 Fix error in blocks detection with nunjucks 2016-02-20 17:32:32 +01:00
Samy Pessé cafbcd4097 Complete normalization of summary with level and multiples parts 2016-02-20 17:18:18 +01:00
Samy Pessé a22539a91e Add new gitbook-markdown and gitbook-asciidoc 2016-02-20 16:02:51 +01:00
Samy Pesse 89378c3883 Update graceful-fs@4 2016-02-18 20:32:11 +01:00
Samy Pesse f763e1dc42 Lint after travis tests 2016-02-18 19:19:09 +01:00
Samy Pesse ea13e3cec4 Change default theme repository 2016-02-18 19:06:23 +01:00
Samy Pessé 3d3302e547 Add detection of text direction and provide: 'page.dir' 2016-02-18 17:50:10 +01:00
Samy Pessé 95d81d02a1 Fix resolve of images 2016-02-18 17:03:37 +01:00
Samy Pessé 8401a674c3 Add test for navigation in summary 2016-02-18 16:34:11 +01:00
Samy Pessé 3fcf1a7723 Dont fail if summary doesn't exist 2016-02-18 15:23:15 +01:00
Samy Pessé 1a3ee78459 Accept external url in summary 2016-02-18 15:23:01 +01:00
Samy Pessé b99c499d2e Add back serve command 2016-02-18 15:08:34 +01:00
Samy Pessé 709b388dfc Fix path calcul to be coherant 2016-02-18 14:47:53 +01:00
Samy Pessé 6e83240233 Glossary should be output as a normal page 2016-02-18 13:58:10 +01:00
Samy Pessé 202c235c66 Add tests for path utils module 2016-02-18 12:15:53 +01:00
Samy Pessé 576d773fec Correctly map filenames for website output 2016-02-18 12:13:24 +01:00
Samy Pessé 58a930e456 Add "level" to TOCArticle 2016-02-18 11:50:33 +01:00
Samy Pessé 52206ce9d0 Add test for copy of assets in website generator 2016-02-18 10:53:57 +01:00
Samy Pessé 1de9d5683b Copy assets to output (website) 2016-02-18 10:45:50 +01:00
Samy Pessé b66242db98 Add filter resolveAsset to template for website 2016-02-18 10:04:23 +01:00
Samy Pesse 004ac88516 Add method .hook to plugins 2016-02-17 21:43:54 +01:00
Samy Pesse 3d1eac234a Move comment about substack/node-resolve#81 2016-02-17 21:35:25 +01:00
Samy Pesse a78e52812f Remove write operations from virtual fs 2016-02-17 21:29:25 +01:00
Samy Pesse 5993e6c791 Ignore headings for annotations 2016-02-17 21:25:53 +01:00
Samy Pesse 1ec8b7c324 Add glossary as a normal page 2016-02-17 21:25:08 +01:00
Samy Pesse e75002a96d Improve annotation with glossary terms 2016-02-17 21:03:00 +01:00
Samy Pesse a68364d4d7 Add test for location 2016-02-17 21:02:42 +01:00
Samy Pessé 2b5e836a33 Fix and improve tests for links in page 2016-02-17 17:38:39 +01:00
Samy Pessé 9caa9c39e5 Use _layouts folders as base for templates 2016-02-17 17:34:27 +01:00
Samy Pessé 096bdaba7a Fix #537: don't add index.html to links 2016-02-17 17:18:19 +01:00
Samy Pessé d22c1f57e5 Generate index.html instead of README.html 2016-02-17 17:04:23 +01:00
Samy Pessé dac00be7b5 Add some doc about theming 2016-02-17 16:51:21 +01:00
Samy Pessé 4e7cb9b23f Load template engine for website output using theme configuration 2016-02-17 16:20:45 +01:00
Samy Pessé 5fdee2cb5e Add file website output tests 2016-02-17 15:59:27 +01:00
Samy Pessé 1db3f3deab Don't fail if plugin is "empty" 2016-02-17 15:58:35 +01:00
Samy Pessé b2af55ac63 Wrap error when loading plugin 2016-02-17 15:53:37 +01:00
Samy Pessé 40cdc285b6 Don't build context in templating engine 2016-02-17 15:18:49 +01:00
Samy Pessé 46f017e68b Add type to file object in templating context 2016-02-17 15:08:26 +01:00
Samy Pessé 1769ac2c2d Don't output config in json format 2016-02-17 15:08:08 +01:00
Samy Pessé 067bdcda2d Add "config" to templating context 2016-02-17 15:07:56 +01:00
Samy Pessé 3bc1934966 Add faq in documentation 2016-02-17 15:07:19 +01:00
Samy Pessé 6ee9a3a64c Remove old theme 2016-02-17 14:07:15 +01:00
Samy Pessé c0196c97a5 Add context for summary 2016-02-17 13:59:52 +01:00
Samy Pessé 96105d6ba0 Extend templating context (and json output) 2016-02-17 13:39:20 +01:00
Samy Pessé 853ba6079c Correctly clean and ignore output folder 2016-02-17 13:30:45 +01:00
Samy Pessé b6104c64fe Use same json for page context and json builds 2016-02-17 13:12:34 +01:00
Samy Pessé e95678cf3a Add tests for installation of plugins 2016-02-17 12:55:46 +01:00
Samy Pessé e2c21051aa Add method install to plugins manager 2016-02-17 12:02:58 +01:00
Samy Pessé 7c575e1b43 Fix loading of plugins 2016-02-17 11:52:31 +01:00
Samy Pessé c89c253f29 Adapt ebook output 2016-02-17 11:26:36 +01:00
Samy Pessé f54685e216 Change format of conrefs and folder mixins 2016-02-17 11:25:57 +01:00
Samy Pessé 8141bcb3b6 Add command 'parse' for gitbook-cli 2016-02-17 10:11:33 +01:00
Samy Pesse db3d21db49 Start commands for plugins installation 2016-02-16 23:30:08 +01:00
Samy Pesse ca85c0ecf3 Add method to install plugin from npm
Add tests for it
2016-02-16 18:46:16 +01:00
Samy Pesse 702db46f20 Add base for plugin linking/installation 2016-02-16 15:53:12 +01:00
Samy Pesse 327d0bf5c5 Validate plugin after loading 2016-02-16 15:42:24 +01:00
Samy Pesse 2375296e67 Add base _setup for pluginslist 2016-02-15 22:39:26 +01:00
Samy Pesse b4fcd2da14 Plugins should be relative to output 2016-02-15 21:14:25 +01:00
Samy Pesse e3c92cce77 Add name to json and website build
And inherit from conrefsLoader
2016-02-15 16:24:13 +01:00
Samy Pessé 1141d34f07 Add tests for args in blocks 2016-02-15 14:19:30 +01:00
Samy Pessé 354fe12742 Fix addBlock for template engine
Add test for code block
2016-02-15 14:07:26 +01:00
Samy Pessé 1b19c66603 Complete page.previous and page.next variables 2016-02-15 09:55:12 +01:00
Samy Pessé d7077fc7db Add test for page.title variable 2016-02-15 09:44:05 +01:00
Samy Pessé d6bd4a0d67 Add test for file variables in templating 2016-02-14 23:05:37 +01:00
Samy Pessé 8628c87be4 Interpolate template before running it 2016-02-14 22:55:48 +01:00
Samy Pessé fef822145d Move conrefs to a separate mixin 2016-02-14 22:49:55 +01:00
Samy Pessé cfefa7d579 Add .next and .prev to TOCArticle 2016-02-14 19:27:58 +01:00
Samy Pessé def115fe0f Add base for templating documentation 2016-02-14 19:07:04 +01:00
Samy Pessé 01a7c6f4e0 Add help chapter about variables 2016-02-14 17:41:55 +01:00
Samy Pessé 0e86cdeb4a Add code blocks normalization 2016-02-14 15:26:15 +01:00
Samy Pessé a65f888a77 Start moving template and conrefs on Output 2016-02-14 11:10:08 +01:00
Samy Pessé 71059e3ea3 Ignore Summary and Langs in output 2016-02-13 15:51:14 +01:00
Samy Pessé ee3faaad11 Complete assets inliner 2016-02-13 15:28:07 +01:00
Samy Pessé d2aad34935 Improve performance of svg conversion 2016-02-13 15:04:18 +01:00
Samy Pesse d8ed34beba Add method to fetch remote image with AssetsInliner 2016-02-13 13:56:04 +01:00
Samy Pesse 3154d37e41 Add more test for svg 2016-02-13 10:49:56 +01:00
Samy Pesse 272f30af53 Complete test for convertion of svgs 2016-02-13 10:43:22 +01:00
Samy Pesse 4c6717e234 Add conversion of svg to png for assets inliner 2016-02-12 23:57:43 +01:00
Samy Pesse 39b6562d14 Add pipeline to outline svg as png 2016-02-12 21:59:49 +01:00
Samy Pesse 0d966fe197 Separate output in FolderOutput and base 2016-02-12 21:25:43 +01:00
Samy Pesse 82f94b010f Remove concept of generator, to merge it with Output 2016-02-12 20:48:51 +01:00
Samy Pesse 4555c541a8 Replace links to page of summary by html links 2016-02-12 19:20:32 +01:00
Samy Pesse a853a51a0b Complete test for heading IDs 2016-02-12 18:53:00 +01:00
Samy Pesse 756694c029 Page output a simple html string 2016-02-11 22:12:07 +01:00
Samy Pesse 669f3b3984 Add base for normalizing html 2016-02-11 21:44:38 +01:00
Samy Pesse e7eed2abbe Complete conrefs in parsing 2016-02-11 18:18:33 +01:00
Samy Pesse 98a13cf487 Add conrefs loader for nunjucks 2016-02-11 17:30:58 +01:00
Samy Pesse 7f9aa214a4 Cleaner module for managing git refs 2016-02-11 17:10:59 +01:00
Samy Pesse 347a536a4e Add git urls parsing and tests 2016-02-11 16:35:41 +01:00
Samy Pesse 5cf0abaf2b Add documentation for conrefs 2016-02-11 15:36:05 +01:00
Samy Pessé 09c6f025a1 For multilingual book, copy readme from main book 2016-02-11 14:01:52 +01:00
Samy Pessé f47208528b Normalize fs access 2016-02-11 13:58:26 +01:00
Samy Pessé 87d90a65ac Stat file when parsing page 2016-02-11 13:31:19 +01:00
Samy Pessé 02cff8c72c Add base for page parsing 2016-02-11 11:53:32 +01:00
Samy Pessé a67993ac0b Add assertion for should to test existence of file 2016-02-11 11:14:52 +01:00
Samy Pessé e540d25665 Normalize templating error 2016-02-11 10:08:36 +01:00
Samy Pessé 52c4dc49cf Normalize errors 2016-02-11 10:07:15 +01:00
Samy Pessé 44ad70320a Correctly setup folder when outputting 2016-02-11 09:43:36 +01:00
Samy Pessé 2b8e1c0b11 Add configuration for inner docs 2016-02-11 09:35:47 +01:00
Samy Pessé 85a2ce9065 Add base for inner documentation 2016-02-11 09:34:47 +01:00
Samy Pessé a24aa79dbf Add base for templating 2016-01-31 17:01:50 +01:00
Samy Pessé 633de85180 Improve plugin loading to elimate false-negative 2016-01-29 12:28:51 +01:00
Samy Pessé f32d03eb88 Add base for loading plugins 2016-01-29 12:21:57 +01:00
Samy Pessé e83d63c2aa Index page of summary when parsing 2016-01-28 23:42:00 +01:00
Samy Pessé ff30ba62ba Add order for tests 2016-01-28 23:23:56 +01:00
Samy Pessé ea98444dc0 Add parsing of summary and tests 2016-01-28 23:19:39 +01:00
Samy Pessé 328c3a7d51 Correctly create sub-book 2016-01-28 18:42:21 +01:00
Samy Pessé 4b465bedea Fix tests for languages parsing 2016-01-28 18:39:44 +01:00
Samy Pessé 461ef2c68e Add unit tests for langs 2016-01-28 17:35:32 +01:00
Samy Pessé 46efdacd6d Fix book.resolve 2016-01-28 16:29:09 +01:00
Samy Pessé a063cc1a53 Add base for langs parsing 2016-01-28 16:27:29 +01:00
Samy Pessé 36f2f5d52e Add method glossary.find 2016-01-27 22:51:07 +01:00
Samy Pessé ddc99104d4 Add unit tests for glossary parsing 2016-01-27 22:48:23 +01:00
Samy Pessé 8d277e9108 Add parsing of the glossary 2016-01-27 21:56:00 +01:00
Samy Pessé f305d57ab7 Add more classes structures 2016-01-27 10:24:06 +01:00
Samy Pessé 877f2e477b Start rewrite 2016-01-22 21:04:36 +01:00
Samy Pessé c8e2fc0e57 Fix typo in config_default.js 2016-01-21 16:15:14 +01:00
Aaron O'Mullan 4cb9cbb5ae Merge pull request #1097 from egasato/master
Slight changes in Catalan and Spanish translations.
2016-01-15 16:09:43 +01:00
Esaú García Sánchez-Torija 6f3be56223 Slightly changes in the Spanish translation.
I changed LANGS_CHOOSE, SEARCH_TOGGLE, SEARCH_PLACEHOLDER, SHARE_TOGGLE and SHARE_ON properties to be more appropiate (more informal).
2016-01-15 14:07:07 +01:00
Esaú García Sánchez-Torija c638c108d2 Translated font settings.
I translated to Catalan the Spanish font settings I used as template but I forgot to translate previously. I also changed LANGS_CHOOSE, SEARCH_TOGGLE, SEARCH_PLACEHOLDER, SHARE_TOGGLE and SHARE_ON properties to be more appropiate (more informal).
2016-01-15 14:04:58 +01:00
Samy Pessé d8f5aa680d Bump version to 2.6.7 2016-01-13 16:28:09 +01:00
Samy Pessé f2b585e446 Add @egasato as Catalan translator 2016-01-13 16:25:28 +01:00
Samy Pessé 78f91e0037 Merge pull request #1072 from egasato/patch-1
Catalan translation.
2016-01-13 16:24:33 +01:00
Samy Pessé 3f3c156697 Add @turankonan as Turkish translator 2016-01-13 16:24:22 +01:00
Samy Pessé 4627bf5d1f Merge pull request #1075 from turankonan/master
Turkish translation
2016-01-13 16:23:00 +01:00
Samy Pessé 93a144984a Merge pull request #1091 from gitname/gitname-patch-2
Fix typo
2016-01-13 16:22:16 +01:00
Samy Pessé 2d0784440c Fix support for encoded entities in filename 2016-01-13 16:21:52 +01:00
gitname 05a083437f Fix typo 2016-01-09 21:44:30 -08:00
gitname d4b5f59f92 Convert run-on sentence into two sentences 2016-01-09 21:43:49 -08:00
Turan Konan ff53fb6db0 Turkish translation 2016-01-03 22:55:49 +02:00
Esaú García Sánchez-Torija 534b3908cc Catalan translation. 2015-12-30 13:18:43 +01:00
Samy Pessé 7ea2369810 Merge pull request #1066 from hirofumi1987/master
Fixed Japanese translation
2015-12-21 08:40:29 +01:00
hirofumi_i 4d96ec10c1 Fixed Japanese translation 2015-12-21 12:39:19 +09:00
Samy Pesse a37ee3457a Bump version to 2.6.6 2015-12-16 21:02:49 +01:00
Samy Pesse 6969bb9a5c Fix include of css in pdf header/footer 2015-12-16 20:55:06 +01:00
Samy Pessé 4567041456 Bump version to 2.6.5 2015-12-11 14:48:13 +01:00
Samy Pessé 49f09e46da Fix support for local styles 2015-12-11 14:40:20 +01:00
Samy Pessé becd027563 Check style existence on output folder instead of source 2015-12-11 14:31:08 +01:00
Samy Pessé 6eb1605be6 Fix #1041 : fix glossary terms being replaced in script (ex: math) 2015-12-08 15:27:11 +01:00
Samy Pessé 5c16aec096 Use gitbook-markdown-css@1.0.1 2015-12-04 15:43:51 +01:00
Samy Pessé 835e2dc1fb Bump version to 2.6.4 2015-12-02 13:29:04 +01:00
Samy Pessé e2378ab29a Update gitbook-parsers@0.8.9 2015-12-02 13:25:13 +01:00
Samy Pesse 0f1d7eb391 Bump version to 2.6.3 2015-12-02 10:12:49 +01:00
Samy Pesse dd358b8b95 Update gitbook-parsers@0.8.8 2015-12-02 10:11:06 +01:00
Samy Pessé 21cf5fcaf4 Bump version to 2.6.2 2015-11-25 11:56:29 +01:00
Samy Pessé 8c7509759b Update nunjucks@2.2.0 2015-11-25 11:54:19 +01:00
Samy Pessé dc9ac0d0ff Compile js 2015-11-25 11:52:50 +01:00
Samy Pessé 93b401ca9f Add trailing slash to gitbook.state.root, fix value of gitbook.state.bookRoot 2015-11-25 11:49:55 +01:00
Samy Pessé b137d8270a Bump version to 2.6.1 2015-11-25 11:02:15 +01:00
Samy Pessé 6db7757451 Fix gitbook.state.innerLanguage: use camel case 2015-11-25 11:01:17 +01:00
Samy Pessé 43fd42b757 Bump version to 2.6.0 2015-11-25 10:54:09 +01:00
Samy Pessé 5d1c4d2b9f Fix #926: use zh-hans instead of zh-cn and ja instead of jp 2015-11-25 10:52:36 +01:00
Samy Pessé 425acd8bf6 Follow github style: change color of h6 headings 2015-11-25 10:42:36 +01:00
Samy Pessé 414160e0df Merge pull request #1027 from GitbookIO/revert-1020-remove-font-smooth
Revert "Fix small font rendering issue on Macs"
2015-11-25 10:32:28 +01:00
Samy Pessé 117c6aefe8 Revert "Fix small font rendering issue on Macs" 2015-11-25 10:32:17 +01:00
Samy Pessé 13d584d39a Merge pull request #1020 from dylang/remove-font-smooth
Fix small font rendering issue on Macs
2015-11-25 10:28:23 +01:00
Samy Pessé 9bc89c24f5 Fix #1023: close sidebar after clicking a link on mobile 2015-11-25 10:25:58 +01:00
Samy Pessé 5a8c4d5a4e Cleanup lib/generators/json.js 2015-11-25 10:14:34 +01:00
Samy Pessé 98da83a552 Fix urijs dependency on linux 2015-11-25 10:08:24 +01:00
Samy Pessé 5344a30a3b Generate css 2015-11-25 10:05:16 +01:00
Samy Pessé d5d6b3673e Add bookRoot to gitbook.state 2015-11-25 10:05:05 +01:00
Samy Pessé d2a2fe88d1 Update urijs@1.17.0 and tiny-lr 2015-11-25 10:04:44 +01:00
Samy Pesse ced44c86ce Fix #1022: fix bottom margin for lists 2015-11-24 23:38:26 +01:00
Samy Pessé ee402ad444 Merge pull request #1018 from atilacamurca/patch-1
Update README.md
2015-11-19 12:24:42 +01:00
Dylan Greene 3d2155eb66 Make fonts nicer on Macs
Removed the `antialias` setting which tells Chrome to not use native font rendering and instead use something from the late 2010's that isn't subpixel-friendly and looks very blocky. This used to be required when OS X browsers didn't antialias by default because it made fonts look bolder than on Windows. This has since been fixed and we are advised to not use `-webkit-font-smooth`.

https://developer.mozilla.org/en-US/docs/Web/CSS/font-smooth
2015-11-17 16:15:33 -05:00
Samy Pessé bd24b03548 Add @buren to AUTHORS 2015-11-16 22:04:41 +01:00
Samy Pessé 5cb55a0f37 Merge pull request #1019 from buren/sv-locale
Add Swedish translation
2015-11-16 22:02:49 +01:00
Jacob Burenstam 163242f80f Add Swedish translation 2015-11-16 22:00:16 +01:00
Átila Camurça Alves 266bfcb8bf Update README.md
There is an extra space in the command line example that enable debug mode.
2015-11-16 16:45:33 -03:00
Samy Pessé d82fa02669 Update plugin-search@1.1.0 2015-11-16 13:09:05 +01:00
Samy Pessé 3a5207a0d2 Merge pull request #1016 from GitbookIO/fix/999
Fix #999: detection of structure should be case incensitive
2015-11-16 10:39:29 +01:00
Samy Pessé e38f3bb884 Improve book.findFile to be case incensitive 2015-11-16 10:31:24 +01:00
Samy Pessé 751cdd9b3b Add test for #999 2015-11-16 10:30:10 +01:00
Samy Pessé 8df6bdca89 Update node version for travis and appveyor tests 2015-11-16 10:18:52 +01:00
Samy Pessé f9df7545ad Merge pull request #1014 from GitbookIO/fix/1013
Fix #1013: prioritize structure defined in book.json
2015-11-16 10:16:52 +01:00
Samy Pessé 9b7a90afef Test first extension of structure itself in book.findFile 2015-11-16 10:06:31 +01:00
Samy Pessé 2ae83b3247 Add failing test for #1013 2015-11-16 09:55:45 +01:00
Samy Pessé 5d907f234e Merge pull request #1005 from mjanda/master
Czech translation
2015-11-07 21:56:28 +01:00
Marek Janda 3a005c4f13 Czech translation 2015-11-07 21:51:27 +01:00
Marek Janda 6c2f50470a Czech translation 2015-11-07 21:00:45 +01:00
Samy Pessé d233783942 Fix bottom margin of blockquote 2015-11-05 11:33:21 +01:00
Samy Pessé 3d9e4c80a2 Bump version to 2.5.2 2015-11-03 09:32:35 +01:00
Samy Pessé a7f49015c1 Fix custom styles for ebook 2015-11-03 09:25:51 +01:00
Samy Pessé 68ed2631dc Correctly show space between toolbar icon and text in buttons 2015-11-02 17:16:43 +01:00
Samy Pessé 2814fea67e Trigger "start" before "page.change" 2015-11-02 16:57:08 +01:00
Samy Pessé 3388be9db6 Update app.js 2015-10-27 23:11:55 +01:00
Samy Pessé 9b89319820 Bump version to 2.5.1 2015-10-27 23:11:31 +01:00
Samy Pessé ad34089df5 Merge changelog for 2.5.0 2015-10-27 23:10:29 +01:00
Samy Pessé 7a4c6bc326 Fix calcul of root in gitbook.state when serving index.html as / 2015-10-27 18:44:04 +01:00
Samy Pessé 6ab386ae35 Bump version to 2.5.0 2015-10-27 13:25:52 +01:00
Samy Pessé 0abbfde912 Add chapterTitle to app build 2015-10-27 12:19:54 +01:00
Samy Pessé 0521defb63 Add 'chapterTitle' to gitbook.state api 2015-10-27 12:18:04 +01:00
Samy Pessé ea4d96610f Compatibility for require of plugins 2015-10-24 21:36:17 +02:00
Samy Pessé 4bc56564b4 Comment gitbook.state api 2015-10-22 16:12:21 +02:00
Samy Pessé 013f7f09da Add gitbook.state.filepath
Fix gitbook.state.root
2015-10-22 16:11:05 +02:00
Samy Pessé f082de1f92 Bump version to 2.5.0-beta.7 2015-10-22 13:52:19 +02:00
Samy Pessé ad39dc8c0c Update app.js 2015-10-22 13:50:05 +02:00
Samy Pessé 481a76319f Provide gitbook.state.root to plugins 2015-10-22 13:49:28 +02:00
Samy Pessé 27a43d5aea Merge pull request #986 from GitbookIO/fix/heading_ids
Normalize ID for headings
2015-10-21 18:05:40 +02:00
Samy Pessé df1d5a0680 Correctly generate id if none found 2015-10-21 17:58:06 +02:00
Samy Pessé 722109faf0 Update gitbook-parsers@0.8.7 2015-10-21 16:22:47 +02:00
Samy Pessé d4dca7736a Update gitbook-parsers@0.8.6 2015-10-21 16:15:56 +02:00
Samy Pessé 4e90becd52 Use Arial as default font 2015-10-21 15:54:45 +02:00
Samy Pessé 26890e94eb Bump version to 2.5.0-beta.6 2015-10-20 18:20:44 +02:00
Samy Pessé 55c83f9a59 Use helvetica by default for pdf 2015-10-20 18:09:51 +02:00
Samy Pessé b837d82878 Fix default style for pdf footer and header 2015-10-20 18:02:23 +02:00
Samy Pessé cbdcdb1e0f Fix #974: correctly handle query in image urls 2015-10-20 17:22:01 +02:00
Samy Pessé 4fea85289e Merge pull request #983 from GitbookIO/fix/982
Fix #982: correctly handle templating in imported content
2015-10-20 17:09:15 +02:00
Samy Pessé ba5f9132c9 Fix #982: fix shortcuts for included templates 2015-10-20 17:08:44 +02:00
Samy Pessé 991681daa2 Add failing test for #982 2015-10-20 16:38:48 +02:00
Samy Pessé 2faf53e16b Bump version to 2.5.0-beta.5 2015-10-16 13:48:27 +02:00
Samy Pessé 5430ed99de Update gitbook-parsers@0.8.5 2015-10-16 13:47:09 +02:00
Samy Pessé fef4dfd05e Fix position of sidebar toggle button 2015-10-14 13:35:03 +02:00
Samy Pessé 05943db3b5 Bump version to 2.5.0-beta.4 2015-10-14 13:16:49 +02:00
Samy Pessé 682fabd1ef Fix position of glossary icon relative to sidebar toggler 2015-10-14 13:15:36 +02:00
Samy Pessé ee8ccc6d7e Fix legacy properties book.options.input, ... 2015-10-14 12:31:37 +02:00
Samy Pessé 8ee0bcac2a Bump version to 2.5.0-beta.3 2015-10-14 11:54:58 +02:00
Samy Pessé 0c4ad74788 Fix resolve of plugins for prereleases 2015-10-14 11:54:12 +02:00
Samy Pessé 7d944e4f1f Fix instruction for local developement 2015-10-14 11:48:27 +02:00
Samy Pessé 67b2394c16 Bump version to 2.5.0-beta.2 2015-10-14 11:39:23 +02:00
Samy Pessé 269d08a35f Correctly handle pre-version for plugins checks 2015-10-13 15:50:54 +02:00
Samy Pessé f626e83e48 Bump version to 2.5.0-beta.1 2015-10-13 15:21:20 +02:00
Samy Pessé 8ba18cd587 Merge pull request #979 from GitbookIO/feature/plugins_config
Improvements for plugin configurations
2015-10-13 15:14:26 +02:00
Samy Pessé 54c12fea89 Set default config for all plugins 2015-10-13 15:05:46 +02:00
Samy Pessé afb5ce71ce Update gitbook-plugin-sharing@1.0.1 2015-10-13 14:56:59 +02:00
Samy Pessé 6fef6acf10 Correctly apply defaults config to pluginsConfig 2015-10-13 14:55:39 +02:00
Samy Pessé a27411401b Update gitbook-plugin-fontsettings@1.0.2 2015-10-13 14:48:09 +02:00
Samy Pessé 3718fc319b Fix error in accessing plugins config 2015-10-13 14:47:33 +02:00
Samy Pessé c6c9463f8c Update gitbook-plugin-search@1.0.2 2015-10-13 14:38:54 +02:00
Samy Pessé b410685318 Update gitbook-plugin-search@1.0.1 2015-10-13 14:34:29 +02:00
Samy Pessé b742b29259 Add tests for plugins config validation 2015-10-13 14:31:11 +02:00
Samy Pessé df5d27ab61 Use jsonschema to valid and default plugins config 2015-10-13 13:56:46 +02:00
Samy Pessé 2870155c0b Fix js error 2015-10-12 10:45:13 +02:00
Samy Pessé 9ba1075f48 Add hook "config" to transform configuration before generation 2015-10-12 10:43:14 +02:00
Samy Pessé 4ae5b2e050 Merge pull request #959 from GitbookIO/improvements/ebooks
Improvements for ebooks
2015-10-08 20:58:57 +02:00
Samy Pessé 4369bd8f5e Fix copy of assets and js path in gulpfile 2015-10-06 14:23:10 +02:00
Samy Pessé 321b24a7b9 Don't copy assets for ebook to website bundle 2015-10-06 14:21:02 +02:00
Samy Pessé 22e0c1fb54 Fix css being used for pdf footer and header 2015-10-06 13:35:04 +02:00
Samy Pessé ba65e3c020 Adapt tests 2015-10-06 13:26:32 +02:00
Samy Pessé c19ab952e3 Only add page count on pdf/epub 2015-10-06 13:20:20 +02:00
Samy Pessé ecc29087b5 Fix summary page counter for epub low resolution 2015-10-06 13:10:51 +02:00
Samy Pessé 87e056de64 Change markdown -> markup in less mixins 2015-10-06 13:05:32 +02:00
Samy Pessé 761200529f Adapt glossary and summary for pdf/epub to new markup style 2015-10-06 13:03:52 +02:00
Samy Pessé 770351916e Cleaner markup css 2015-10-06 12:45:25 +02:00
Samy Pessé 4b7d957b47 Use black links in mobi files 2015-10-06 10:38:09 +02:00
Samy Pessé a1c03c18a5 Improve support of glossary page in pdf 2015-10-06 10:00:49 +02:00
Samy Pesse 5d376b054f Handle correctly rtl for toc in ebooks 2015-10-06 09:47:41 +02:00
Samy Pesse 277d13c2bb Center title for table of content 2015-10-06 09:47:25 +02:00
Samy Pesse 4a9389d80a Improve display of table of contents for ebooks 2015-10-06 09:47:15 +02:00
Samy Pesse 33593c13ae Inline css for footer/header templates 2015-10-06 09:47:04 +02:00
Samy Pesse eef82c18c2 Remove bottom border on h1 and h2 2015-10-06 09:45:31 +02:00
Samy Pessé 7363580095 Fix glossary page using a "section" instead of a "div" 2015-10-06 09:45:22 +02:00
Samy Pessé 23a46b0597 Remove margin on first header of a page (ebook)
Avoid breaking in code blocks
2015-10-06 09:45:06 +02:00
Samy Pessé 51c79f294c Add css to footer/header for pdf 2015-10-06 09:44:54 +02:00
Samy Pessé ce1e0e1873 Merge pull request #964 from GitbookIO/features/plugin_api
Better APIs for Plugins
2015-10-06 09:42:49 +02:00
Samy Pessé c2775b3b63 Export jQuery for plugins compatibility 2015-10-06 09:37:01 +02:00
Samy Pessé bcb224d1cb Add more node.js versions to travis-ci 2015-10-05 23:06:46 +02:00
Samy Pessé 8bc5f22866 Add search plugin to dependencies 2015-10-05 17:22:47 +02:00
Samy Pessé c3f2ef02c4 Adapt tests for new default plugins 2015-10-05 17:16:37 +02:00
Samy Pessé 08e2c90d9d Don't fail when can't write to localstorage 2015-10-05 17:11:55 +02:00
Samy Pessé d2bb2ba454 Remove style for search 2015-10-05 17:07:25 +02:00
Samy Pessé ba912318cd Tweak some details for browserify compatibility 2015-10-05 16:49:37 +02:00
Samy Pessé 3d1f057373 Switch to gulp/browserify 2015-10-05 16:47:19 +02:00
Samy Pessé 0679807517 Define specific action for toggling summary 2015-10-05 16:02:03 +02:00
Samy Pessé 7f0e4803e2 Start removing search and lunr from core 2015-10-05 15:55:39 +02:00
Samy Pessé fa76029a17 Adapt tests for new default plugins 2015-10-05 14:24:55 +02:00
Samy Pessé 376c68957f Remove sharing 2015-10-05 13:53:19 +02:00
Samy Pessé 222ec8d4b9 Correctly reset buttons when page changed 2015-10-05 12:13:54 +02:00
Samy Pessé 90715c1944 Remove fontsettings from core and add plugin as default 2015-10-05 12:07:19 +02:00
Samy Pessé 801e1b6059 Add api to extend toolbar 2015-10-05 12:07:02 +02:00
Samy Pessé 14bb659b75 Update lodash for client side code 2015-10-05 10:43:21 +02:00
Samy Pessé eab3c50288 Add sharing plugin as default 2015-10-05 10:32:43 +02:00
Samy Pessé 74396e7240 Add method book.formatString 2015-10-05 10:07:04 +02:00
Samy Pessé 6c2539e886 Move Book.init in another file 2015-10-05 09:54:40 +02:00
Samy Pessé aba25d8521 Add eslint instead of jshint 2015-10-05 09:54:28 +02:00
Samy Pessé f0c97756de Bump version to 2.4.3 2015-10-01 14:07:32 +02:00
Samy Pessé f14c57d4c2 Merge pull request #955 from mstade/patch-1
Change nunjucks dependency to v2.1.0
2015-10-01 12:03:21 +02:00
Marcus Stade b6f60cc8ad Change nunjucks dependency to v2.1.0
Looks like mozilla/nunjucks#504 was merged and released in v2.1.0, so this changes `package.json` to no longer depend on a specific commit. Incidentally, this also solves a problem where corporate firewalls blocks npm from pulling in straight from github repos.
2015-10-01 12:01:52 +02:00
Samy Pessé 170516d343 Add ukranian translation 2015-09-28 21:01:28 +02:00
Samy Pessé c931e91bef Fix #952: add configuration for index maximum size 2015-09-28 20:54:45 +02:00
Samy Pessé db9151ae36 Update gitbook-parsers@0.8.3 2015-09-28 20:40:02 +02:00
Samy Pessé f2d86b6d69 Add slack button in readme 2015-09-23 12:19:04 +02:00
Samy Pessé 534cdd091b Add link to slack community channel 2015-09-23 12:16:22 +02:00
Samy Pessé fdf4a48638 Bump version to 2.4.2 2015-09-22 23:30:42 +02:00
Samy Pessé 58a3c5634e Improve installation of plugins to not install default ones 2015-09-22 23:25:15 +02:00
Samy Pessé f0ddb6e89f Merge branch 'fix/inline_code_html' 2015-09-22 22:46:19 +02:00
Samy Pessé 2b408db7cb Update gitbook-plugin-highlight@1.0.3 2015-09-22 22:45:55 +02:00
Samy Pessé 4e4bd23e2b Handle html param from code block output 2015-09-22 22:41:13 +02:00
Samy Pessé 62d0eb606e Add test for inline code block with html tags 2015-09-22 22:36:35 +02:00
Samy Pessé 0e9beeae14 Fix #941: limit size of lunr index 2015-09-22 12:36:18 +02:00
Samy Pessé 5e4dbdee24 Disable auto code highlighting (language should be specified) 2015-09-21 16:19:42 +02:00
Samy Pessé 9435dae6cd Fix #939: don't check gitbook version for sub-books (checked for parent) 2015-09-21 09:41:29 +02:00
Samy Pessé 813210bf47 Throw correct error in configuration 2015-09-20 23:27:39 +02:00
Samy Pessé c372dfc544 Bump version to 2.4.1 2015-09-19 00:32:43 +02:00
Samy Pessé ac77200683 Fix disabling a default plugin 2015-09-19 00:31:32 +02:00
Samy Pessé f5afbc90a4 Add more tests for blocks args/kwargs 2015-09-17 11:21:55 +02:00
Samy Pessé b24760c819 Bump version to 2.4.0 2015-09-15 14:32:11 +02:00
Samy Pessé 6732957e42 Merge pull request #930 from GitbookIO/jshint
Add config for jshint and fix lint errors
2015-09-15 14:21:27 +02:00
Samy Pessé 1fd0006859 Lint all tests 2015-09-15 14:20:32 +02:00
Samy Pessé 5a205346e3 Jshint all files 2015-09-15 13:57:21 +02:00
Samy Pessé e193004659 Fix passing context to block functions
Add test for it
2015-09-15 13:36:02 +02:00
Samy Pessé fe3a9c33d0 Improve code style for book.js and index.js 2015-09-15 13:16:26 +02:00
Samy Pessé d83116b88f Add jshint configuration 2015-09-15 13:16:06 +02:00
Samy Pessé 5f56098ae7 Fix stupid error that passed tests because "context" was global 2015-09-15 12:38:13 +02:00
Samy Pessé 0f935f4372 Merge pull request #806 from aschempp/aria-roles
Aria roles for accessibility
2015-09-15 12:29:12 +02:00
Samy Pessé df5c5a8c01 Merge pull request #919 from gaearon/fix-cmd-click
Don't react when user wants to open a link in a new tab
2015-09-15 12:28:32 +02:00
Samy Pessé 57a0c3bad8 Merge pull request #929 from GitbookIO/feature/improve_resolve
Improve paths resolving for conrefs
2015-09-15 12:27:07 +02:00
Samy Pessé 2a52326a45 Improve conrefs to handle all absolute file paths correctly
Add test for it
2015-09-15 12:22:54 +02:00
Samy Pessé 87e4ee1eeb Handle absolute file correctly for conrefs
Add test for absolute file for conrefs
2015-09-15 11:48:18 +02:00
Samy Pessé 45833eea9a Add test for navigation
Update mocha and should
2015-09-15 11:31:50 +02:00
Samy Pessé baf10e9b15 Improve book.resolve to ensure file is in the book
Adapt tests to plugin-highlight
2015-09-15 11:09:08 +02:00
Samy Pessé 463a947df1 Change text for editor 2015-09-15 09:47:34 +02:00
Samy Pessé cceebb4fd9 Merge branch 'improve/template-blocks' 2015-09-15 09:37:43 +02:00
Samy Pessé afd5465a61 Merge pull request #928 from GitbookIO/feature/highlight_block
Code highlighting extended by plugins
2015-09-14 18:26:26 +02:00
Samy Pesse fe604733de Change name of highlight test plugin 2015-09-14 12:05:51 +02:00
Samy Pesse da22f9f39f Update css without highlight.js
Add highlight as default plugin to be loaded
2015-09-14 11:57:54 +02:00
Samy Pesse 284ebbf75d Add highlight as default plugin 2015-09-14 11:47:56 +02:00
Samy Pesse 2c08ccad87 Pass language as kwargs to code block
Improve tests for extending code highlighting
2015-09-14 11:41:01 +02:00
Samy Pesse fa4e234bab Add base test for extending code highlighting 2015-09-14 11:28:14 +02:00
Samy Pesse 35c4179ca1 Use block code for highlight pre/code
Cleanup correctly predefined blocks
2015-09-14 11:21:16 +02:00
Dan Abramov c14ba7ce34 Don't react when user wants to open a link in a new tab
Fixes #846
2015-09-12 21:31:40 +03:00
Samy Pesse 601ce3add3 Add default blocks (html and code) 2015-09-12 19:25:01 +02:00
Samy Pesse 08ff39fd0b Remove highlight.js dependency 2015-09-12 19:23:07 +02:00
Samy Pesse 82a6ee3875 Add test for replacing highlighting 2015-09-12 18:21:35 +02:00
Samy Pessé 3bf592f870 Bump version to 2.3.3 2015-09-10 11:26:15 +02:00
Samy Pessé 241e205717 Merge pull request #912 from GitbookIO/fix/538
Fix 538: duplicate entries without paths are ignored
2015-09-10 09:59:45 +02:00
Samy Pessé fb2720ea8d Update gitbook-parsers@0.8.2 2015-09-10 09:57:04 +02:00
Samy Pessé 14853befda Add test for init with deep summary 2015-09-10 09:56:18 +02:00
Aaron O'Mullan d699dff872 Use Book.resolve when possible
For added consistency
2015-07-31 15:08:56 +02:00
Andreas Schempp dbc75f7352 Add role and html5 markup for the main navigation 2015-06-18 20:29:11 +02:00
Andreas Schempp db841a8578 Added basic ARIA roles for screenreaders 2015-06-18 20:23:12 +02:00
482 changed files with 16136 additions and 10654 deletions
+4
View File
@@ -0,0 +1,4 @@
docs/**/*
_book/**/*
node_modules/**/*
test/**/*
+22
View File
@@ -0,0 +1,22 @@
{
"rules": {
"indent": [ 2, 4 ],
"quotes": [ 2, "single" ],
"linebreak-style": [ 2, "unix" ],
"semi": [ 2, "always" ],
"no-unused-vars": [ 2, {
"vars": "all",
"args": "none"
} ],
"spaced-comment": [ 2, "always" ]
},
"env": {
"node": true,
"browser": true,
"mocha": true
},
"globals": {
"expect": true
},
"extends": "eslint:recommended"
}
+19
View File
@@ -0,0 +1,19 @@
Thank you for giving us your feedback! We listed some guidelines to help you:
If possible, open separate issues for each bug report. Avoid grouping bugs that are unrelated.
### What is the current behavior?
If the current behavior is a bug, please provide the steps to reproduce. if possible, provide the GitBook version being used (`gitbook -V`) and the system infromations (OS and version).
### What is the expected behavior?
How do you think, or how would you like it should behave.
#### For GitBook.com
Provide, if possible, your username and the URL of the concerned book.
----
The GitBook Team
+8 -4
View File
@@ -22,10 +22,14 @@ build/Release
# Dependency directory
# Deployed apps should consider commenting this line out:
# see https://npmjs.org/doc/faq.html#Should-I-check-my-node_modules-folder-into-git
node_modules
theme/javascript/vendors
theme/vendors
/node_modules
# vim swapfile
*.swp
# Output of documentation
_book
book.pdf
book.epub
book.mobi
+8 -3
View File
@@ -1,7 +1,12 @@
sudo: false
language: node_js
os:
- linux
- osx
node_js:
- "0.11"
- "0.10"
- "stable"
- "4.1"
before_install:
- npm install svgexport -g
- npm install svgexport -g
after_success:
- npm run lint
+14 -3
View File
@@ -7,9 +7,10 @@ Names below are ordered by first contribution.
Author
------
- Samy Pessé <samypesse@gmail.com> (@SamyPesse)
- Aaron O'Mullan <aaron.omullan@gmail.com> (@AaronO)
- Samy Pessé <samy@gitbook.com> (@SamyPesse)
- Aaron O'Mullan <aaron@gitbook.com> (@AaronO)
- Johan Preynat <johan@gitbook.com> (@jpreynat)
- Nicolas Gaborit <nicolas@gitbook.com> (@soreine)
Contributors
------------
@@ -55,3 +56,13 @@ Translators
- Hong Nguyen (@nghong)
- Hebrew
- @a-moses
- Ukrainian
- @Karnaukhov
- Czech
- @mjanda
- Swedish
- Jacob Burenstam (@buren)
- Turkish
- Turan Konan (@turankonan)
- Catalan
- Esaú García Sánchez-Torija (@egasato)
+147
View File
@@ -2,6 +2,153 @@
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).
## 3.2.2
- Fix catching parsing errors leading to possible missing pages in generated book
- Rollback markdown parser to `kramed` until `markup-it` is stable enough
## 3.2.1
- Fix bug on Firefox when navigating to an url containing an hash
- Update nunjucks to fix JS error when page contains a lot of templating blocks
## 3.2.0
- Switch markdown parser from `kramed` to `markup-it`
- Fix support of `|` in tables
- Fix access to `output.name` in templating
- Fix i18n for website and PDF
- Fix minor scrolling issues on website
- Improve options of default search indexer (keywords, disabling per pages)
- Improve pertinence of search results
## 3.1.1
- Fix order of plugins during loading
- Fix error when using math and conrefs
- Fix target attribute for external links
- Fix serve command
## 3.1.0
- Always load themes after plugins
- README/Introduction doesn't require to be the first entry in the summary
- Highlight active entry in summary when scrolling a page with anchors
- Support empty parts in summary
## 3.0.3
- Fix redirection in `gitbook serve` when accessing a folder without trailing slash
- Fix links/annotations for glossary not being correctly resolved
- Fix regression for supporting uppercase filenames in structure files
- Fix `gitbook install` when using Git URLs for plugins
## 3.0.2
- Fix crash for anchor links
## 3.0.1
- Fix regression in link resolution when contain anchor
- Fix `structure.<name>` configuration not supporting filenames with dots
## 3.0.0
- Summary can contain external links and anchors (Fix [#776](https://github.com/GitbookIO/gitbook/issues/776))
- Summary can contain differents entitled sections
- Glossary is generated as a normal page
- Headings are no longer annotated with glossary terms
- Themes are now published as a plugin, with ability to extend it from the book source
- `links.sidebar` configuration is no longer supported, use summary sections instead
- `pdf.headerTemplate` and `pdf.footerTemplate` have been replaced by a template in theme/book: `_layout/ebook/pdf_header.html` and `_layout/ebook/pdf_footer.html`
- Markdown parser is now using CommonMark
- Root folder for the book can be specified in the `"root"` property of the `book.json` file
- Multi-lingual books share assets folder
- YAML front matter is parsed and can extend page's properties
- Fix `uk` translation
- Fix heading ID including dashes
- Fix error in code highlighting for unknown languages
- Fix data-uri images being handled as external images
- Accept SSH url as plugin version
- Add templating blocks `markdown`, `asciidoc` and `markup`
- Better search experience
- Better default theme, more responsive and cleaner
## 2.6.7
- Fix bug with filenames including spaces
- Add Turkish and Catalan translations
## 2.6.6
- Fix custom CSS that are generated by plugins for PDF output
## 2.6.5
- Fix support for plugins generating custom stylesheets (`styles-less` and `styles-sass`)
- Fix glossary terms being replaced in script (ex: math)
## 2.6.4
- Fix regression introduced by `2.6.3` of single HTML tags in markdown
## 2.6.3
- Fix parsing bug with inline HTML in Markdown
## 2.6.2
- Fix `gitbook.state.bookRoot`, `gitbook.state.root` now has a trailing slash
- Update nunjucks to 2.2.0
## 2.6.1
- Use CamelCase for `gitbook.state.innerLanguage`
## 2.6.0
- Close sidebar after clicking a link on mobile
- Add root for multilingual books: `gitbook.state.bookRoot`
- Fix color of h6 headings
- Fix bottom margin of lists and blockquotes
- Add Swedish translation (`sv`)
- Add Czech translation (`cs`)
- Fix locale names for `zh-hans` and `jp`
- Update plugin `search` to fix crashes
- Aceept case-incensitive structure files (README, GLOSSARY, etc)
## 2.5.2
- Fix custom stylesheets for ebook generation
- Trigger event `start` before `page.change`
## 2.5.1
- Fix calcul of `gitbook.state.root` when serving HTML index as `/`
## 2.5.0
- Font settings, sharing and search are externalized as default plugins
- Plugins can define a configuration schema in the manifest, this schema will be used to validate configuration during build
- New Node.js API for plugin: `book.formatString(type, content)`
- New client side API for website plugins: `gitbook.toolbar.createButton(opts)`
- Better header/footer for PDF, CSS wil be inlined to easily style the header/footer
- Cleaner table of contents for ebooks
- Support for RTL in ebook's table of contents
- Better colors for mobi (links and code blocks)
- Fix installation of plugins when using a pre-release
- Fix support for pre-releases
- Update asciidoc parser to remove git dependency
- Fix templating in imported content
- Fix querystring in image urls
- Normalize heading IDs like GitHub
- Use Arial as default font for PDFs
- Add `root`, `chapterTitle` and `filepath` to `gitbook.state` JS API
## 2.4.3
- Add ukrainian translation (`uk`)
- Add `book.json` configuration for maximum size of search index
- Improve reliability of summary parser
## 2.4.2
- Default plugins should not be installed by `gitbook install`
- Limit search index size to avoid crash during generation
- Fix code highlighting for html without language specified
- Fix warning message for gitbook version when building a multilingual book
## 2.4.1
- Fix disabling of default plugins, ex: `-highlight`
## 2.4.0
- Fix page being updated when user wants to open a link in a new tab
- Plugins can now replaced default code highlighter
- Add semantic information for screen readers (web version)
- Content references accept absolute paths, resolved to book folder
- Improve overall reliability
## 2.3.3
- Fix bug in SUMMARY parsing preventing multiple entries without filenames
## 2.3.2
- Fix blocks (like maths) in Asciidoc
- Fix error when checking gitbook version
-96
View File
@@ -1,96 +0,0 @@
module.exports = function (grunt) {
var path = require("path");
// Load NPM tasks
grunt.loadNpmTasks('grunt-contrib-copy');
grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks('grunt-contrib-requirejs');
grunt.loadNpmTasks("grunt-bower-install-simple");
// Init GRUNT configuraton
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
'bower-install-simple': {
options: {
color: true,
production: false,
directory: "theme/vendors"
}
},
less: {
development: {
options: {
compress: true,
yuicompress: true,
optimization: 2
},
files: {
"theme/assets/style.css": "theme/stylesheets/website.less",
"theme/assets/print.css": "theme/stylesheets/ebook.less"
}
}
},
requirejs: {
compile: {
options: {
name: "gitbook",
baseUrl: "theme/javascript/",
out: "theme/assets/app.js",
preserveLicenseComments: false,
optimize: "uglify",
include: ["requireLib"],
paths: {
"jQuery": '../vendors/jquery/dist/jquery',
"lodash": '../vendors/lodash/dist/lodash',
"requireLib": '../vendors/requirejs/require',
"Mousetrap": '../vendors/mousetrap/mousetrap',
"lunr": '../vendors/lunr.js/lunr',
"URIjs": '../vendors/URIjs/src/',
"ace": '../vendors/ace-builds/src-noconflict/'
},
shim: {
'jQuery': {
exports: '$'
},
'lodash': {
exports: '_'
},
'Mousetrap': {
exports: 'Mousetrap'
},
'lunr': {
exports: 'lunr'
}
}
}
}
},
copy: {
vendors: {
files: [
{
expand: true,
cwd: 'theme/vendors/fontawesome/fonts/',
src: ['**'],
dest: 'theme/assets/fonts/fontawesome/',
filter: 'isFile'
}
]
}
}
});
grunt.registerTask("bower-install", [ "bower-install-simple" ]);
// Build
grunt.registerTask('build', [
'bower-install',
'less',
'requirejs',
'copy:vendors'
]);
grunt.registerTask('default', [
'build'
]);
};
+23 -201
View File
@@ -4,226 +4,48 @@ GitBook
[![NPM version](https://badge.fury.io/js/gitbook.svg)](http://badge.fury.io/js/gitbook)
[![Linux Build Status](https://travis-ci.org/GitbookIO/gitbook.png?branch=master)](https://travis-ci.org/GitbookIO/gitbook)
[![Windows Build status](https://ci.appveyor.com/api/projects/status/63nlflxcwmb2pue6?svg=true)](https://ci.appveyor.com/project/GitBook/gitbook)
[![Slack Status](https://slack.gitbook.com/badge.svg)](https://slack.gitbook.com)
GitBook is a command line tool (and Node.js library) for building beautiful books using GitHub/Git and Markdown (or AsciiDoc). Here is an example: [Learn Javascript](https://www.gitbook.com/book/GitBookIO/javascript).
You can publish and host book easily online using [gitbook.com](https://www.gitbook.com), a web-editor is [also available](https://www.gitbook.com/editor).
You can publish and host books easily online using [gitbook.com](https://www.gitbook.com). A desktop editor is [also available](https://www.gitbook.com/editor).
Stay updated by following [@GitBookIO](https://twitter.com/GitBookIO) on Twitter or [GitBook](https://www.facebook.com/gitbookcom) on Facebook.
Check out the [GitBook Community Slack Channel](https://slack.gitbook.com), Stay updated by following [@GitBookIO](https://twitter.com/GitBookIO) on Twitter or [GitBook](https://www.facebook.com/gitbookcom) on Facebook.
Complete documentation is available at [help.gitbook.com](http://help.gitbook.com/).
Complete documentation is available at [toolchain.gitbook.com](http://toolchain.gitbook.com/).
![Image](https://raw.github.com/GitbookIO/gitbook/master/preview.png)
## How to use it:
## Getting started
GitBook can be installed from **NPM** using:
GitBook can be used either on your computer for building local books or on GitBook.com for hosting them. To get started, check out [the installation instructions in the documentation](docs/setup.md).
```
$ npm install gitbook-cli -g
```
## Usage examples
Create the directories and files for a book from its [SUMMARY.md](https://github.com/GitbookIO/gitbook#book-format) file (if existing) using
GitBook can be used to create book, public documentation, enterprise manual, thesis, research papers, etc.
```
$ gitbook init
```
You can find a [list of real-world examples](docs/examples.md) in the documentation.
You can serve a repository as a book using:
## Help and Support
```
$ gitbook serve
```
Or simply build the static website using:
```
$ gitbook build
```
We're always happy to help out with your books or any other questions you might have. You can ask a question on the following contact form at [gitbook.com/contact](https://www.gitbook.com/contact) or signal an issue on [GitHub](https://github.com/GitbookIO/gitbook).
## Features
* [Output as a website or ebook (pdf, epub, mobi)](http://help.gitbook.com/format/output.html)
* [Multi-Languages](http://help.gitbook.com/format/languages.html)
* [Glossary](http://help.gitbook.com/format/glossary.html)
* [Cover](http://help.gitbook.com/format/cover.html)
* [AsciiDoc Support](http://help.gitbook.com/format/asciidoc.html)
* [Variables and Templating](http://help.gitbook.com/format/templating.html)
* [Content References](http://help.gitbook.com/format/conrefs.html)
* [Plugins](http://help.gitbook.com/format/plugins.html)
* Interractive reader website:
* Search
* Font Settings (Serif, Sans Serif)
* Themes: white, sepia, night
## Output Formats
GitBook can generate your book in the following formats:
* **Static Website**: This is the default format. It generates a complete interactive static website that can be, for example, hosted on GitHub Pages.
* **eBook**: You need to have [ebook-convert](http://manual.calibre-ebook.com/cli/ebook-convert.html) installed. You can specify the eBook filename as the second argument, otherwise `book` will be used.
* Generate a **PDF** using: `gitbook pdf ./myrepo ./mybook.pdf`
* Generate a **ePub** using: `gitbook epub ./myrepo ./mybook.epub`
* Generate a **MOBI** using: `gitbook mobi ./myrepo ./mybook.mobi`
* **JSON**: This format is used for debugging or extracting metadata from a book. Generate this format using: ```gitbook build ./myrepo --format=json```.
## Book Format
A book is a Git repository containing at least 2 files: `README.md` and `SUMMARY.md`.
#### README.md
Typically, this should be the introduction for your book. It will be automatically added to the final summary.
#### SUMMARY.md
The `SUMMARY.md` defines your book's structure. It should contain a list of chapters, linking to their respective pages.
Example:
```markdown
# Summary
This is the summary of my book.
* [section 1](section1/README.md)
* [example 1](section1/example1.md)
* [example 2](section1/example2.md)
* [section 2](section2/README.md)
* [example 1](section2/example1.md)
```
Files that are not included in `SUMMARY.md` will not be processed by `gitbook`.
#### Multi-Languages
GitBook supports building books written in multiple languages. Each language should be a sub-directory following the normal GitBook format, and a file named `LANGS.md` should be present at the root of the repository with the following format:
```markdown
* [English](en/)
* [French](fr/)
* [Español](es/)
```
You can see a complete example with the [Learn Git](https://github.com/GitbookIO/git) book.
#### Glossary
Allows you to specify terms and their respective definitions to be displayed in the glossary. Based on those terms, `gitbook` will automatically build an index and highlight those terms in pages.
The `GLOSSARY.md` format is very simple :
```markdown
# term
Definition for this term
# Another term
With it's definition, this can contain bold text and all other kinds of inline markup ...
```
#### Variables and Templating
A set of variables can be defined in the `book.json`:
```js
{
"variables": {
"host": "mybook.com"
}
}
```
These variables can be used in the markdown files:
```
The host is {{ book.host }}
```
You can also use condition with these variables:
```
{% if book.host == "mybook.com" %}
{% else %}
{% endif %}
```
Variables of `book.json` are available in the `book` namespace. You can also access informations about the `file` itself and the `gitbook` version:
```
My file is {{ file.path }}
Modified at {{ file.mtime }}
Book built with GitBook {{ gitbook.version }}
```
#### Content References
You can use "content references," or conrefs, when writing books or documentation using GitBook.
Include a file from the same book:
```
{% include "./test.md" %}
```
or from a git repository (with a specific revision):
```
{% include "git+https://github.com/GitbookIO/documentation.git/README.md#1.0.1" %}
```
Includes can be used with variables (see [Variables and Templating](#variables-and-templating)):
```
{% include book.ref_doc_readme %}
```
#### Ignoring files & folders
GitBook will read the `.gitignore`, `.bookignore` and `.ignore` files to get a list of files and folders to skip. (The format inside those files follows the same convention as `.gitignore`).
Best practices for the `.gitignore` is to ignore build files from **node.js** (`node_modules`, ...) and build files from GitBook: `_book`, `*.epub`, `*.mobi` and `*.pdf` ([Download GitBook.gitignore](https://github.com/github/gitignore/blob/master/GitBook.gitignore)).
#### Cover
A cover image can be set by creating a file: **/cover.jpg**.
The best resolution is **1800x2360**. The generation of the cover can be done automatically using the plugin [autocover](https://github.com/GitbookIO/plugin-autocover).
A small version of the cover can also be set by creating a file: **/cover_small.jpg**.
#### AsciiDoc
Since version 2.0.0, AsciiDoc can be used instead of Markdown, simply replace the `.md` by the `.adoc` extension. Chapters in the summary are detected from an ordered list in the `SUMMARY.adoc`.
* Write using [Markdown](http://toolchain.gitbook.com/syntax/markdown.html) or [AsciiDoc](http://toolchain.gitbook.com/syntax/asciidoc.html)
* Output as a website or [ebook (pdf, epub, mobi)](http://toolchain.gitbook.com/ebook.html)
* [Multi-Languages](http://toolchain.gitbook.com/languages.html)
* [Lexicon / Glossary](http://toolchain.gitbook.com/lexicon.html)
* [Cover](http://toolchain.gitbook.com/ebook.html)
* [Variables and Templating](http://toolchain.gitbook.com/templating/)
* [Content References](http://toolchain.gitbook.com/templating/conrefs.html)
* [Plugins](http://toolchain.gitbook.com/plugins/)
* [Beautiful default theme](https://github.com/GitbookIO/theme-default)
## Publish your book
The platform [GitBook.com](https://www.gitbook.com/) is like an "Heroku for books": you can create a book on it (public, paid, or private) and update it using **git push**.
The platform [GitBook.com](https://www.gitbook.com/) is like an "Heroku for books": you can create a book on it (public, or private) and update it using **git push**.
## Plugins
## Licensing
Plugins can be used to extend your book's functionality. Read [GitbookIO/plugin](https://github.com/GitbookIO/plugin) for more information about how to build a plugin for GitBook.
Plugins needed to build a book can be installed using: `gitbook install ./`. You can find plugins at [plugins.gitbook.com](http://plugins.gitbook.com).
## Debugging
You can use the options `--log=debug` and `--debug` to get better error messages (with stack trace). For example:
```
$ gitbook build ./ -- log=debug --debug
```
#### How to use the latest commit from GitBook in gitbook-cli
To use the latest commit from `GitBook/gitbook` with `gitbook-cli`:
```
$ git clone https://github.com/GitbookIO/gitbook.git ./gitbook
$ gitbook versions:link 2.0.0 ./gitbook
```
Now the version tag `2.0.0` wil be associated with the `./gitbook` folder.
You can uninstall it using: `gitbook versions:uninstall 2.0.0`.
GitBook is licensed under the Apache License, Version 2.0. See [LICENSE](LICENSE) for the full license text.
+11 -2
View File
@@ -5,13 +5,18 @@ init:
# Test against these versions of Node.js.
environment:
matrix:
- nodejs_version: "0.10"
- nodejs_version: "0.11"
- nodejs_version: "6"
- nodejs_version: "5"
- nodejs_version: "4"
matrix:
fast_finish: true
# Install scripts. (runs after repo cloning)
install:
# Get the latest stable version of Node.js or io.js
- ps: Install-Product node $env:nodejs_version
- set CI=true
# install svgexport
- npm install svgexport -g
# install modules
@@ -27,3 +32,7 @@ test_script:
# Don't actually build.
build: off
# Clone only last commit
shallow_clone: true
clone_depth: 1
+4 -3
View File
@@ -1,7 +1,8 @@
#! /usr/bin/env node
/* eslint-disable no-console */
var color = require('bash-color');
console.log(color.red("You need to install 'gitbook-cli' to have access to the gitbook command anywhere on your system."));
console.log(color.red("If you've installed this package globally, you need to uninstall it."));
console.log(color.red(">> Run 'npm uninstall -g gitbook' then 'npm install -g gitbook-cli'"));
console.log(color.red('You need to install "gitbook-cli" to have access to the gitbook command anywhere on your system.'));
console.log(color.red('If you\'ve installed this package globally, you need to uninstall it.'));
console.log(color.red('>> Run "npm uninstall -g gitbook" then "npm install -g gitbook-cli"'));
+23
View File
@@ -0,0 +1,23 @@
var pkg = require('./package.json');
module.exports = {
// Documentation for GitBook is stored under "docs"
root: './docs',
title: 'GitBook Toolchain Documentation',
// Enforce use of GitBook v3
gitbook: '3.1.1',
// Use the "official" theme
plugins: ['theme-official@2.1.1', '-sharing', '-fontsettings', 'sitemap'],
variables: {
version: pkg.version
},
pluginsConfig: {
sitemap: {
hostname: 'https://toolchain.gitbook.com'
}
}
};
-13
View File
@@ -1,13 +0,0 @@
{
"name": "GitBook",
"version": "1.0.0",
"dependencies": {
"jquery": "2.1.1",
"lodash": "2.4.1",
"requirejs": "2.1.11",
"URIjs": "1.13.1",
"mousetrap": "1.4.6",
"lunr.js": "0.5.2",
"fontawesome": "4.1.0"
}
}
+26
View File
@@ -0,0 +1,26 @@
# GitBook Toolchain Documentation
This document aims to be a comprehensive guide to GitBook. It contains the full documentation for version **{{ book.version }}**. Help for GitBook.com specific questions can be found at [help.gitbook.com](https://help.gitbook.com).
### What is GitBook?
GitBook is a command line tool (and Node.js library) for building beautiful books using GitHub/Git and Markdown (or AsciiDoc). . This documentation has been generated using GitBook.
GitBook can output your content as a website ([customizable](themes/README.md) and [extensibles](plugins/README.md)) or as an ebook (PDF, ePub or Mobi).
[GitBook.com](https://www.gitbook.com) is the online platform to create and host books built using the GitBook format. It offers hosting, collaboration features and an [easy-to-use editor](https://www.gitbook.com/editor).
### Help and Support
We're always happy to help out with your books or any other questions you might have. You can ask a question on the following contact form at [gitbook.com/contact](https://www.gitbook.com/contact) or signal an issue on [GitHub](https://github.com/GitbookIO/gitbook).
Check out the [GitBook Community Slack Channel](https://slack.gitbook.com), Stay updated by following [@GitBookIO](https://twitter.com/GitBookIO) on Twitter or [GitBook](https://www.facebook.com/gitbookcom) on Facebook.
### FAQ
Some questions are frequently asked. If you have a problem you should [check this out](faq.md) first.
### Contribute to this documentation
You can contribute to improve this documentation on [GitHub](https://github.com/GitbookIO/gitbook) by signaling issues or proposing changes.
+50
View File
@@ -0,0 +1,50 @@
# Summary
### Getting Started
* [About this documentation](README.md)
* [Installation and Setup](setup.md)
### Your Content
* [Directory structure](structure.md)
* [Pages and Summary](pages.md)
* [Configuration](config.md)
* [Glossary](lexicon.md)
* [Multi-Lingual](languages.md)
* [Markdown](syntax/markdown.md)
* [Headings](syntax/markdown.md#headings)
* [Paragraphs](syntax/markdown.md#paragraphs)
* [Lists](syntax/markdown.md#lists)
* [Links](syntax/markdown.md#links)
* [Images](syntax/markdown.md#images)
* [Blockquotes](syntax/markdown.md#blockquotes)
* [Tables](syntax/markdown.md#tables)
* [Code](syntax/markdown.md#code)
* [HTML](syntax/markdown.md#html)
* [Footnotes](syntax/markdown.md#footnotes)
* [AsciiDoc](syntax/asciidoc.md)
* [eBook and PDF](ebook.md)
### Customization
* [Templating](templating/README.md)
* [Content References](templating/conrefs.md)
* [Variables](templating/variables.md)
* [Builtin](templating/builtin.md)
* [Plugins](plugins/README.md)
* [Create a plugin](plugins/create.md)
* [Hooks](plugins/hooks.md)
* [Blocks](plugins/blocks.md)
* [Filters](plugins/filters.md)
* [API & Context](plugins/api.md)
* [Test your plugin](plugins/testing.md)
* [Theming](themes/README.md)
--
* [FAQ](faq.md)
* [Examples](examples.md)
* [Release notes](https://github.com/GitbookIO/gitbook/blob/master/CHANGES.md)
+26
View File
@@ -0,0 +1,26 @@
{% extends template.self %}
{% block header_nav %}
<a href="https://github.com/GitbookIO/gitbook/blob/master/docs/{{ file.path }}" target="_blank" class="btn btn-link pull-right hidden-xs">
<i class="octicon octicon-mark-github"></i> Edit on GitHub
</a>
<a href="{{ "faq.md"|resolveFile }}" class="btn btn-link pull-right hidden-xs">
F.A.Q
</a>
<a href="https://github.com/GitbookIO/gitbook/blob/master/CHANGES.md" target="_blank" class="btn btn-link pull-right hidden-xs">
{{ book.version }}
</a>
{% endblock %}
{% block page %}
{{ super() }}
<hr>
<div class="btn-group btn-group-justified">
{% if page.previous and page.previous.path %}
<a class="btn" href="{{ page.previous.path|resolveFile }}"><b>Previous:</b> {{ page.previous.title }}</a>
{% endif %}
{% if page.next and page.next.path %}
<a class="btn" href="{{ page.next.path|resolveFile }}"><b>Next:</b> {{ page.next.title }}</a>
{% endif %}
</div>
{% endblock %}
+55
View File
@@ -0,0 +1,55 @@
# Configuration
GitBook allows you to customize your book using a flexible configuration. These options are specified in a `book.json` file. For authors unfamiliar with the JSON syntax, you can validate the syntax using tools such as [JSONlint](http://jsonlint.com).
### General Settings
| Variable | Description |
| -------- | ----------- |
| `root` | Path to the root folder containing all the book's files, except `book.json`|
| `structure` | To specify paths for Readme, Summary, Glossary etc. See [Structure paragraph](#structure). |
| `title` | Title of your book, default value is extracted from the README. On GitBook.com this field is pre-filled. |
| `description` | Description of your book, default value is extracted from the README. On GitBook.com this field is pre-filled. |
| `author` | Name of the author. On GitBook.com this field is pre-filled. |
| `isbn` | ISBN of the book |
| `language` | [ISO code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) of the book's language, default value is `en` |
| `direction` | Text's direction. Can be `rtl` or `ltr`, the default value depends on the value of `language` |
| `gitbook` | Version of GitBook that should be used. Uses the [SemVer](http://semver.org) specification and accepts conditions like `">= 3.0.0"` |
### Plugins
Plugins and their configurations are specified in the `book.json`. See [the plugins section](plugins/README.md) for more details.
Since version 3.0.0, GitBook can use themes. See [the theming section](themes/README.md) for more details.
| Variable | Description |
| -------- | ----------- |
| `plugins` | List of plugins to load |
| `pluginsConfig` |Configuration for plugins |
### Structure
In addition to the `root` variable, you can tell Gitbook the name of the files for Readme, Summary, Glossary, Languages (instead of using the default names such as `README.md`).
These files must be at the root of your book (or the root of every language book). Paths such as `dir/MY_README.md` are not accepted.
| Variable | Description |
| -------- | ----------- |
| `structure.readme` | Readme file name (defaults to `README.md`) |
| `structure.summary` | Summary file name (defaults to `SUMMARY.md`) |
| `structure.glossary` | Glossary file name (defaults to `GLOSSARY.md`) |
| `structure.languages` | Languages file name (defaults to `LANGS.md`) |
### PDF Options
PDF Output can be customized using a set of options in the `book.json`:
| Variable | Description |
| -------- | ----------- |
| `pdf.pageNumbers` | Add page numbers to the bottom of every page (default is `true`) |
| `pdf.fontSize` | Base font size (default is `12`) |
| `pdf.fontFamily` | Base font family (default is `Arial`) |
| `pdf.paperSize` | Paper size, options are `'a0', 'a1', 'a2', 'a3', 'a4', 'a5', 'a6', 'b0', 'b1', 'b2', 'b3', 'b4', 'b5', 'b6', 'legal', 'letter'` (default is `a4`) |
| `pdf.margin.top` | Top margin (default is `56`) |
| `pdf.margin.bottom` | Bottom margin (default is `56`) |
| `pdf.margin.right` | Right margin (default is `62`) |
| `pdf.margin.left` | Left margin (default is `62`) |
+41
View File
@@ -0,0 +1,41 @@
# Generating eBooks and PDFs
GitBook can generates a website, but can also output content as ebook (ePub, Mobi, PDF).
```
# Generate a PDF file
$ gitbook pdf ./ ./mybook.pdf
# Generate an ePub file
$ gitbook epub ./ ./mybook.epub
# Generate a Mobi file
$ gitbook mobi ./ ./mybook.mobi
```
### Installing ebook-convert
`ebook-convert` is required to generate ebooks (epub, mobi, pdf).
##### OS X
Download the [Calibre application](https://calibre-ebook.com/download). After moving the `calibre.app` to your Applications folder create a symbolic link to the ebook-convert tool:
```
$ sudo ln -s ~/Applications/calibre.app/Contents/MacOS/ebook-convert /usr/bin
```
You can replace `/usr/bin` with any directory that is in your $PATH.
### Cover
Covers are used for all the ebook formats. You can either provide one yourself, or generate one using the [autocover plugin](https://plugins.gitbook.com/plugin/autocover).
To provide a cover, place a **`cover.jpg`** file at the root directory of your book. Adding a **`cover_small.jpg`** will specify a smaller version of the cover. The cover should be a **JPEG** file.
A good cover should respect the following guidelines:
* Size of 1800x2360 pixels for `cover.jpg`, 200x262 for `cover_small.jpg`
* No border
* Clearly visible book title
* Any important text should be visible in the small version
+29
View File
@@ -0,0 +1,29 @@
---
description: Real world examples of content published using GitBook.
---
# Examples
More than 50,000 books have been published on [GitBook.com](https://www.gitbook.com/explore).
### Books
- [Front-end Handbook](https://www.gitbook.com/book/frontendmasters/front-end-handbook/details) by [Cody Lindley](http://codylindley.com)
- [How to make an Operating System](https://www.gitbook.com/book/samypesse/how-to-create-an-operating-system/details) by [@SamyPesse](https://github.com/SamyPesse)
- [Building Web Apps with Go](https://www.gitbook.com/book/codegangsta/building-web-apps-with-go/details) by [@codegangsta](https://github.com/codegangsta)
- [Django Girls Tutorial](http://tutorial.djangogirls.org/en/index.html) by [Django Girls](https://djangogirls.org)
- [Linux Inside](https://www.gitbook.com/book/0xax/linux-insides/details) by [0xAX](https://twitter.com/0xAX)
- [Learn Javascript](https://www.gitbook.com/book/gitbookio/javascript/details) by [GitBook](https://twitter.com/GitbookIO)
### Research Papers
- [TowCenter Collection](https://www.gitbook.com/@towcenter) by [Columbia Journalism School](http://www.journalism.columbia.edu/)
- [Block Relaxation Algorithms in Statistics](https://www.gitbook.com/@jandeleeuw) by Jan de Leeuw
### Documentation
- [DuckDuckHack Documentation](http://docs.duckduckhack.com) by [DuckDuckGo](https://duckduckgo.com/about)
- [Loomio Handbook](http://loomio.coop/) by [Loomio](https://www.loomio.org/)
- [Enspiral Handbook](http://handbook.enspiral.com/) by [Enspiral](http://enspiral.com/)
- This documentation
+55
View File
@@ -0,0 +1,55 @@
# GitBook FAQ
This page gathers common questions and answers concerning the GitBook format and toolchain.
Questions about GitBook.com and the Editor are gather into the [help.gitbook.com's FAQ](http://help.gitbook.com/faq.html).
#### How can I host/publish my book?
Books can easily be published and hosted on [GitBook.com](https://www.gitbook.com). But GitBook output can be hosted on any static file hosting solution.
#### What can I use to edit my content?
Any text editor should work! But we advise using the [GitBook Editor](https://www.gitbook.com/editor). [GitBook.com](https://www.gitbook.com) also provides a web version of this editor.
---
#### Does GitBook supports RTL/bi-directional text ?
The GitBook format supports right to left, and bi-directional writing. To enable it, you either need to specify a language (ex: `ar`), or force GitBook to use RTL in your `book.json`:
``` json
{
"language": "ar",
"direction": "rtl"
}
```
With version 3.0 of GitBook, it's automatically detected according to the content.
_Note that, while the output book will indeed respect RTL, the Editor doesn't support RTL writing yet_.
#### Should I use an `.html` or `.md` extensions in my links?
You should always use paths and the `.md` extensions when linking to your files, GitBook will automatically replace these paths by the appropriate link when the pointing file is referenced in the Table of Contents.
#### Can I create a GitBook in a sub-directory of my repository?
Yes, GitBooks can be created in [sub-directories](structure.md#subdirectory). GitBook.com and the CLI also looks by default in a serie of [folders](structure.md).
#### Does GitBook supports RTL languages?
Yes, GitBook automatically detect the direction in your pages (`rtl` or `ltr`) and adjust the layout accordingly. The direction can also be specified globally in the [book.json](config.md).
---
#### Does GitBook support Math equations?
GitBook supports math equations and TeX thanks to plugins. There are currently 2 official plugins to display math: [mathjax](https://plugins.gitbook.com/plugin/mathjax) and [katex](https://plugins.gitbook.com/plugin/katex).
#### Can I customize/theme the output?
Yes, both the website and ebook outputs can be customized using [themes](themes/README.md).
#### Can I add interactive content (videos, etc)?
GitBook is very [extensible](plugins/README.md). You can use [existing plugins](https://plugins.gitbook.com) or create your own!
+17
View File
@@ -0,0 +1,17 @@
# Multi-Languages
GitBook supports building books written in multiple languages. Each language should be a sub-directory following the normal GitBook format, and a file named `LANGS.md` should be present at the root of the repository with the following format:
```markdown
# Languages
* [English](en/)
* [French](fr/)
* [Español](es/)
```
### Configuration for each language
When a language book (ex: `en`) has a `book.json`, its configuration will extend the main configuration.
The only exception is plugins, plugins are specified globally, and language specific plugins cannot be specified.
+14
View File
@@ -0,0 +1,14 @@
# Glossary
Allows you to specify terms and their respective definitions to be displayed as annotations. Based on those terms, GitBook will automatically build an index and highlight those terms in pages.
The `GLOSSARY.md` format is a list of `h2` headings, along with a description paragraph:
```markdown
## Term
Definition for this term
## Another term
With it's definition, this can contain bold text
and all other kinds of inline markup ...
```
+104
View File
@@ -0,0 +1,104 @@
# Pages and Summary
### Summary
GitBook uses a `SUMMARY.md` file to define the structure of chapters and subchapters of the book. The `SUMMARY.md` file is used to generate the book's table of contents.
The format of `SUMMARY.md` is just a list of links. The link's title is used as the chapter's title, and the link's target is a path to that chapter's file.
Adding a nested list to a parent chapter will create subchapters.
##### Simple example
```markdown
# Summary
* [Part I](part1/README.md)
* [Writing is nice](part1/writing.md)
* [GitBook is nice](part1/gitbook.md)
* [Part II](part2/README.md)
* [We love feedback](part2/feedback_please.md)
* [Better tools for authors](part2/better_tools.md)
```
Each chapter has a dedicated page (`part#/README.md`) and is split into subchapters.
##### Anchors
Chapters in the Table of Contents can be pointing to specific part of a file using anchor.
```markdown
# Summary
### Part I
* [Part I](part1/README.md)
* [Writing is nice](part1/README.md#writing)
* [GitBook is nice](part1/README.md#gitbook)
* [Part II](part2/README.md)
* [We love feedback](part2/README.md#feedback)
* [Better tools for authors](part2/README.md#tools)
```
##### Parts
The Table of Contents can be divided into parts separated by headings or horizontal lines:
```markdown
# Summary
### Part I
* [Writing is nice](part1/writing.md)
* [GitBook is nice](part1/gitbook.md)
### Part II
* [We love feedback](part2/feedback_please.md)
* [Better tools for authors](part2/better_tools.md)
----
* [Last part without title](part3/title.md)
```
Parts are just groups of chapters and do not have dedicated pages, but according to the theme, it will show in the navigation.
### Pages
#### Markdown syntax
Most of the files for GitBook use the Markdown syntax by default. GitBook infers your pages's structure from it. The syntax used is similar to the [GitHub Flavored Markdown syntax](https://guides.github.com/features/mastering-markdown/). One can also opt for the [AsciiDoc syntax](asciidoc.md).
##### Example of a chapter file
``` markdown
# Title of the chapter
This is a great introduction.
## Section 1
Markdown will dictates _most_ of your **book's structure**
## Section 2
...
```
#### Front Matter
Pages can contain an optional front matter. It can be used to define the page's description. The front matter must be the first thing in the file and must take the form of valid YAML set between triple-dashed lines. Here is a basic example:
```yaml
---
description: This is a short description of my page
---
# The content of my page
...
```
The front matter can define variables of your own, they will be added to the [page variable](templating/variables.md) so you can use them in your templating.
+28
View File
@@ -0,0 +1,28 @@
# Plugins
Plugins are the best way to extend GitBook functionalities (ebook and website). There exist plugins to do a lot of things: bring math formulas display support, track visits using Google Analytic, etc.
### How to find plugins?
Plugins can be easily searched on [plugins.gitbook.com](https://plugins.gitbook.com).
### How to install a plugin?
Once you find a plugin that you want to install, you need to add it to your `book.json`:
```
{
"plugins": ["myPlugin", "anotherPlugin"]
}
```
You can also specify a specific version using: `"myPlugin@0.3.1"`. By default GitBook will resolve the latest version of the plugin compatbile with the current GitBook version.
### GitBook.com
Plugins are automatically installed on [GitBook.com](https://www.gitbook.com). Locally, run `gitbook install` to install and prepare all plugins for your books.
### Configuring plugins
Plugins specific configurations are stored in `pluginsConfig`. You have to refer to the documentation of the plugin itself for details about the available options.
+97
View File
@@ -0,0 +1,97 @@
# Context and APIs
GitBooks provides different APIs and contexts to plugins. These APIs can vary according to the GitBook version being used, your plugin should specify the `engines.gitbook` field in `package.json` accordingly.
#### Book instance
The `Book` class is the central point of GitBook, it centralize all access read methods. This class is defined in [book.js](https://github.com/GitbookIO/gitbook/blob/master/lib/book.js).
```js
// Read configuration from book.json
var value = book.config.get('title', 'Default Value');
// Resolve a filename to an absolute path
var filepath = book.resolve('README.md');
// Render an inline markup string
book.renderInline('markdown', 'This is **Markdown**')
.then(function(str) { ... })
// Render a markup string (block mode)
book.renderBlock('markdown', '* This is **Markdown**')
.then(function(str) { ... })
```
#### Output instance
The `Output` class represent the output/write process.
```js
// Return root folder for the output
var root = output.root();
// Resolve a file in the output folder
var filepath = output.resolve('myimage.png');
// Convert a filename to an URL (returns a path to an html file)
var fileurl = output.toURL('mychapter/README.md');
// Write a file in the output folder
output.writeFile('hello.txt', 'Hello World')
.then(function() { ... });
// Copy a file to the output folder
output.copyFile('./myfile.jpg', 'cover.jpg')
.then(function() { ... });
// Verify that a file exists
output.hasFile('hello.txt')
.then(function(exists) { ... });
```
#### Page instance
A page instance represent the current parsed page.
```js
// Title of the page (from SUMMARY)
page.title
// Content of the page (Markdown/Asciidoc/HTML according to the stage)
page.content
// Relative path in the book
page.path
// Absolute path to the file
page.rawPath
// Type of parser used for this file
page.type ('markdown' or 'asciidoc')
```
#### Context for Blocks and Filters
Blocks and filters have access to the same context, this context is bind to the template engine execution:
```js
{
// Current templating syntax
"ctx": {
// For example, after a {% set message = "hello" %}
"message": "hello"
},
// Book instance
"book" <Book>,
// Output instance
"output": <Output>
}
```
For example a filter or block function can access the current book using: `this.book`.
#### Context for Hooks
Hooks only have access to the `<Book>` instance using `this.book`.
+62
View File
@@ -0,0 +1,62 @@
# Extend Blocks
Extending templating blocks is the best way to provide extra functionalities to authors.
The most common usage is to process the content within some tags at runtime. It's like [filters](./filters.md), but on steroids because you aren't confined to a single expression.
### Defining a new block
Blocks are defined by the plugin, blocks is a map of name associated with a block descriptor. The block descriptor needs to contain at least a `process` method.
```js
module.exports = {
blocks: {
tag1: {
process: function(block) {
return "Hello "+block.body+", How are you?";
}
}
}
};
```
The `process` should return the html content that will replace the tag. Refer to [Context and APIs](./api.md) to learn more about `this` and GitBook API.
### Handling block arguments
Arguments can be passed to blocks:
```
{% tag1 "argument 1", "argument 2", name="Test" %}
This is the body of the block.
{% endtag1 %}
```
And arguments are easily accessible in the `process` method:
```js
module.exports = {
blocks: {
tag1: {
process: function(block) {
// block.args equals ["argument 1", "argument 2"]
// block.kwargs equals { "name": "Test" }
}
}
}
};
```
### Handling sub-blocks
A defined block can be parsed into different sub-blocks, for example let's consider the source:
```
{% myTag %}
Main body
{% subblock1 %}
Body of sub-block 1
{% subblock 2 %}
Body of sub-block 1
{% endmyTag %}
```
+74
View File
@@ -0,0 +1,74 @@
# Create and publish a plugin
A GitBook plugin is a node package published on NPM that follow a defined convention.
## Structure
#### package.json
The `package.json` is a manifest format for describing **Node.js modules**. GitBook plugins are built on top of Node modules. It declares dependencies, version, ownership, and other information required to run a plugin in GitBook. This document describes the schema in detail.
A plugin manifest `package.json` can also contain details about the required configuration. The configuration schema is defined in the `gitbook` field of the `package.json` (This field follow the [JSON-Schema](http://json-schema.org) guidelines):
```js
{
"name": "gitbook-plugin-mytest",
"version": "0.0.1",
"description": "This is my first GitBook plugin",
"engines": {
"gitbook": ">1.x.x"
},
"gitbook": {
"properties": {
"myConfigKey": {
"type": "string",
"default": "it's the default value",
"description": "It defines my awesome config!"
}
}
}
}
```
You can learn more about `package.json` from the [NPM documentation](https://docs.npmjs.com/files/package.json).
The **package name** must begin with `gitbook-plugin-` and the **package engines** should contains `gitbook`.
#### index.js
The `index.js` is main entry point of your plugin runtime:
```js
module.exports = {
// Map of hooks
hooks: {},
// Map of new blocks
blocks: {},
// Map of new filters
filters: {}
};
```
## Publish your plugin
GitBook plugins can be published on [NPM](https://www.npmjs.com).
To publish a new plugin, you need to create an account on [npmjs.com](https://www.npmjs.com) then publish it from the command line:
```
$ npm publish
```
## Private plugins
Private plugins can be hosted on GitHub and included using `git` urls:
```
{
"plugins": [
"myplugin@git+https://github.com/MyCompany/mygitbookplugin.git#1.0.0"
]
}
```
+57
View File
@@ -0,0 +1,57 @@
# Extend Filters
Filters are essentially functions that can be applied to variables. They are called with a pipe operator (`|`) and can take arguments.
```
{{ foo | title }}
{{ foo | join(",") }}
{{ foo | replace("foo", "bar") | capitalize }}
```
### Defining a new filter
Plugins can extend filters by defining custom functions in their entry point under the `filters` scope.
A filter function takes as first argument the content to filter, and should return the new content.
Refer to [Context and APIs](./api.md) to learn more about `this` and GitBook API.
```js
module.exports = {
filters: {
hello: function(name) {
return 'Hello '+name;
}
}
};
```
The filter `hello` can then be used in the book:
```
{{ "Aaron"|hello }}, how are you?
```
### Handling block arguments
Arguments can be passed to filters:
```
Hello {{ "Samy"|fullName("Pesse", man=true}} }}
```
Arguments are passed to the function, named-arguments are passed as a last argument (object).
```js
module.exports = {
filters: {
fullName: function(firstName, lastName, kwargs) {
var name = firstName + ' ' + lastName;
if (kwargs.man) name = "Mr" + name;
else name = "Mrs" + name;
return name;
}
}
};
```
+90
View File
@@ -0,0 +1,90 @@
# Hooks
Hooks is a method of augmenting or altering the behavior of the process, with custom callbacks.
### List of hooks
### Relative to the global pipeline
| Name | Description | Arguments |
| ---- | ----------- | --------- |
| `init` | Called after parsing the book, before generating output and pages. | None |
| `finish:before` | Called after generating the pages, before copying assets, cover, ... | None |
| `finish` | Called after everything else. | None |
### Relative to the page pipeline
> It is recommended using [templating](./templating.md) to extend page parsing.
| Name | Description | Arguments |
| ---- | ----------- | --------- |
| `page:before` | Called before running the templating engine on the page | Page Object |
| `page` | Called before outputting and indexing the page. | Page Object |
##### Page Object
```js
{
// Parser named
"type": "markdown",
// File Path relative to book root
"path": "page.md",
// Absolute file path
"rawpath": "/usr/...",
// Title of the page in the SUMMARY
"title": "",
// Content of the page
// Markdown/Asciidoc in "page:before"
// HTML in "page"
"content": "# Hello"
}
```
##### Example to add a title
In the `page:before` hook, `page.content` is the markdown/asciidoc content.
```js
{
"page:before": function(page) {
page.content = "# Title\n" +page.content;
return page;
}
}
```
##### Example to replace some html
In the `page` hook, `page.content` is the HTML generated from the markdown/asciidoc conversion.
```js
{
"page": function(page) {
page.content = page.content.replace("<b>", "<strong>")
.replace("</b>", "</strong>");
return page;
}
}
```
### Asynchronous Operations
Hooks callbacks can be asynchronous and return promises.
Example:
```js
{
"init": function() {
return writeSomeFile()
.then(function() {
return writeAnotherFile();
});
}
}
```
+22
View File
@@ -0,0 +1,22 @@
# Testing your plugin
### Testing your plugin locally
Testing your plugin on your book before publishing it is possible using [npm link](https://docs.npmjs.com/cli/link).
In the plugin's folder, run:
```
$ npm link
```
Then in your book's folder:
```
$ npm link gitbook-plugin-<plugin's name>
```
### Unit testing on Travis
[gitbook-tester](https://github.com/todvora/gitbook-tester) makes it easy to write **Node.js/Mocha** unit tests for your plugins. Using [Travis.org](https://travis.org), tests can be run on each commits/tags.
+69
View File
@@ -0,0 +1,69 @@
# Setup and Installation of GitBook
Getting GitBook installed and ready-to-go should only take a few minutes.
### GitBook.com
[GitBook.com](https://www.gitbook.com) is an easy to use solution to write, publish and host books. It is the easiest solution for publishing your content and collaborating on it.
It integrates well with the [GitBook Editor](https://www.gitbook.com/editor).
### Local Installation
##### Requirements
Installing GitBook is easy and straightforward. Your system just needs to meet these two requirements:
* NodeJS (v4.0.0 and above is recommended)
* Windows, Linux, Unix, or Mac OS X
##### Install with NPM
The best way to install GitBook is via **NPM**. At the terminal prompt, simply run the following command to install GitBook:
```
$ npm install gitbook-cli -g
```
`gitbook-cli` is an utility to install and use multiple versions of GitBook on the same system. It will automatically install the required version of GitBook to build a book.
##### Create a book
GitBook can setup a boilerplate book:
```
$ gitbook init
```
If you wish to create the book into a new directory, you can do so by running `gitbook init ./directory`
Preview and serve your book using:
```
$ gitbook serve
```
Or build the static website using:
```
$ gitbook build
```
##### Install pre-releases
`gitbook-cli` makes it easy to download and install other versions of GitBook to test with your book:
```
$ gitbook fetch beta
```
Use `gitbook ls-remote` to list remote versions available for install.
##### Debugging
You can use the options `--log=debug` and `--debug` to get better error messages (with stack trace). For example:
```
$ gitbook build ./ --log=debug --debug
```
+66
View File
@@ -0,0 +1,66 @@
# Directory Structure
GitBook uses a simple directory structure. All Markdown/Asciidoc files listed in the [SUMMARY](pages.md) will be transformed as HTML. Multi-Lingual books have a slightly [different structure](languages.md).
A basic GitBook usually looks something like this:
```
.
├── book.json
├── README.md
├── SUMMARY.md
├── chapter-1/
| ├── README.md
| └── something.md
└── chapter-2/
├── README.md
└── something.md
```
An overview of what each of these does:
| File | Description |
| -------- | ----------- |
| `book.json` | Stores [configuration](config.md) data (__optional__) |
| `README.md` | Preface / Introduction for your book (**required**) |
| `SUMMARY.md` | Table of Contents (See [Pages](pages.md)) (__optional__) |
| `GLOSSARY.md` | Lexicon / List of terms to annotate (See [Glossary](lexicon.md)) (__optional__) |
### Static files and Images
A static file is a file that is not listed in the `SUMMARY.md`. All static files, unless [ignored](#ignore), are copied to the output.
### Ignoring files & folders {#ignore}
GitBook will read the `.gitignore`, `.bookignore` and `.ignore` files to get a list of files and folders to skip.
The format inside those files, follows the same convention as `.gitignore`:
```
# This is a comment
# Ignore the file test.md
test.md
# Ignore everything in the directory "bin"
bin/*
```
### Project integration with subdirectory {#subdirectory}
For software projects, you can use a subdirectory (like `docs/`) to store the book for the project's documentation. You can configure the [`root` option](config.md) to indicate the folder where GitBook can find the book's files:
```
.
├── book.json
└── docs/
├── README.md
└── SUMMARY.md
```
With `book.json` containing:
```
{
"root": "./docs"
}
```
+4
View File
@@ -0,0 +1,4 @@
/* Reduce size of logo to allow long versions like 3.0.0-pre.1 */
.gb-page-header .container .logo h1 {
font-size: 24px ;
}
+65
View File
@@ -0,0 +1,65 @@
# AsciiDoc
Since version `2.0.0`, GitBook can also accept AsciiDoc as an input format.
Please refer to the [AsciiDoc Syntax Quick Reference](http://asciidoctor.org/docs/asciidoc-syntax-quick-reference/) for more informations about the format.
Just like for markdown, GitBook is using some special files to extract structures: `README.adoc`, `SUMMARY.adoc`, `LANGS.adoc` and `GLOSSARY.adoc`.
### README.adoc
This is the main entry of your book: the introduction. This file is **required**.
### SUMMARY.adoc
This file defines the list of chapters and subchapters. Just like in Markdown, the `SUMMARY.adoc`'s format is simply a list of links, the name of the link is used as the chapter's name, and the target is a path to that chapter's file.
Subchapters are defined simply by adding a nested list to a parent chapter.
```asciidoc
= Summary
. link:chapter-1/README.adoc[Chapter 1]
.. link:chapter-1/ARTICLE1.adoc[Article 1]
.. link:chapter-1/ARTICLE2.adoc[Article 2]
... link:chapter-1/ARTICLE-1-2-1.adoc[Article 1.2.1]
. link:chapter-2/README.adoc[Chapter 2]
. link:chapter-3/README.adoc[Chapter 3]
. link:chapter-4/README.adoc[Chapter 4]
.. Unfinished article
. Unfinished Chapter
```
### LANGS.adoc
For [Multi-Languages](./languages.md) books, this file is used to define the different supported languages and translations.
This file is following the same syntax as the `SUMMARY.adoc`:
```asciidoc
= Languages
. link:en/[English]
. link:fr/[French]
```
### GLOSSARY.adoc
This file is used to define terms. [See the glossary section](./lexicon.md).
```asciidoc
= Glossary
== Magic
Sufficiently advanced technology, beyond the understanding of the
observer producing a sense of wonder.
== PHP
A popular web programming language, used by many large websites such
as Facebook. Rasmus Lerdorf originally created PHP in 1994 to power
his personal homepage (PHP originally stood for "Personal Home Page"
but now stands for "PHP: Hypertext Preprocessor"). ```
+223
View File
@@ -0,0 +1,223 @@
# Markdown
Most of the examples from this documentation are in Markdown. Markdown is default parser for GitBook, but one can also opt for the [AsciiDoc syntax](asciidoc.md).
Heres an overview of Markdown syntax that you can use with GitBook (same as GitHub with some additions).
### Headings
To create a heading, add one to six `#` symbols before your heading text. The number of # you use will determine the size of the heading.
```markdown
# This is an <h1> tag
## This is an <h2> tag
###### This is an <h6> tag
```
GitBook supports a nice way for explicitly setting the header ID. If you follow the header text with an opening curly bracket (separated from the text with a least one space), a hash, the ID and a closing curly bracket, the ID is set on the header. If you use the trailing hash feature of atx style headers, the header ID has to go after the trailing hashes. For example:
```markdown
Hello {#id}
-----
# Hello {#id}
# Hello # {#id}
```
### Paragraphs and Line Breaks {#paragraphs}
A paragraph is simply one or more consecutive lines of text, separated by one or more blank lines. (A blank line is any line that looks like a blank line — a line containing nothing but spaces or tabs is considered blank.) Normal paragraphs should not be indented with spaces or tabs.
```
Here's a line for us to start with.
This line is separated from the one above by two newlines, so it will be a *separate paragraph*.
```
### Emphasis {#emphasis}
```markdown
*This text will be italic*
_This will also be italic_
**This text will be bold**
__This will also be bold__
~~This text will be crossed out.~~
_You **can** combine them_
```
### Lists {#lists}
Markdown supports ordered (numbered) and unordered (bulleted) lists.
##### Unordered
Unordered lists use asterisks, pluses, and hyphens — interchangably — as list markers:
```markdown
* Item 1
* Item 2
* Item 2a
* Item 2b
```
##### Ordered
Ordered lists use numbers followed by periods:
```markdown
1. Item 1
2. Item 2
3. Item 3
* Item 3a
* Item 3b
```
### Links {#links}
Markdown supports two style of links: inline and reference.
A simple link can be created by surrounding the text with square brackets and the link URL with parentheses:
```markdown
This is [an example](http://example.com/ "Title") inline link with a title.
[This link](http://example.net/) has no title attribute.
```
Links can point to relative paths, anchors or absolute urls.
### References
There is another way to create links which does not interrupt the text flow. The URL and title are defined using a reference name and this reference name is then used in square brackets instead of the link URL:
```markdown
This is [an example][id] reference-style link.
```
Then, anywhere in the document, you define your link label like this, on a line by itself:
```markdown
[id]: http://example.com/ "Optional Title Here"
```
### Images {#images}
Images can be created in a similar way than links: just use an exclamation mark before the square brackets. The link text will become the alternative text of the image and the link URL specifies the image source:
```markdown
An image: ![gras](img/image.jpg)
```
### Blockquotes {#blockquotes}
A blockquote is started using the `>` marker followed by an optional space; all following lines that are also started with the blockquote marker belong to the blockquote. You can use any block-level elements inside a blockquote:
```markdown
As Kanye West said:
> We're living the future so
> the present is our past.
```
### Tables {#tables}
You can create tables by assembling a list of words and dividing them with hyphens `-` (for the first row), and then separating each column with a pipe `|`:
```markdown
| First Header | Second Header |
| ------------- | ------------- |
| Content Cell | Content Cell |
| Content Cell | Content Cell |
```
The pipes on either end of the table are optional. Cells can vary in width and do not need to be perfectly aligned within columns. There must be at least three hyphens in each column of the header row.
### Code {#code}
Markdown supports two different code block styles. One uses lines indented with either four spaces or one tab whereas the other uses lines with tilde characters as delimiters therefore the content does not need to be indented:
```markdown
This is a sample code block.
Continued here.
```
##### Fenced code blocks
You can create fenced code blocks by placing triple backticks ` ``` ` before and after the code block. We recommend placing a blank line before and after code blocks to make the raw formatting easier to read.
```
function test() {
console.log("notice the blank line before this function?");
}
```
##### Syntax highlighting
You can add an optional language identifier to enable syntax highlighting in your fenced code block.
For example, to syntax highlight Ruby code:
```ruby
require 'redcarpet'
markdown = Redcarpet.new("Hello World!")
puts markdown.to_html
```
##### Inline code
Text phrases can be marked up as code by surrounding them with backticks:
Use `gitbook` to convert the `text` in markdown
syntax to HTML.
### Footnotes
GitBook supports a simple syntax for such footnotes. Footnotes are relative to each pages.
```markdown
Text prior to footnote reference.[^2]
[^2]: Comment to include in footnote.
```
### HTML
GitBook supports use of raw HTML in your text, Markdown syntax in HTML is not processed:
```
<div>
Markdown here will not be **parsed**
</div>
```
### Horizontal Rule
Horizontal Rules can be inserted using three or more asterisks, dashes or underscores, optionally separated by spaces or tabs, on an otherwise blank line:
```markdown
Three or more...
---
Hyphens
***
Asterisks
```
### Ignoring Markdown formatting
You can tell GitBook to ignore (or escape) Markdown formatting by using `\` before the Markdown character.
```
Let's rename \*our-new-project\* to \*our-old-project\*.
```
+99
View File
@@ -0,0 +1,99 @@
# Templating
GitBook uses the [Nunjucks templating language](https://mozilla.github.io/nunjucks/) to process pages and theme's templates.
The Nunjucks syntax is very similar to **Jinja2** or **Liquid**. Its syntax uses surrounding braces `{ }` to mark content that needs to be processed.
### Variables
A variable looks up a value from the template context. If you wanted to simply display a variable, you would use the `{{ variable }}` syntax. For example :
```twig
My name is {{ name }}, nice to meet you
```
This looks up username from the context and displays it. Variable names can have dots in them which lookup properties, just like JavaScript. You can also use the square bracket syntax.
```twig
{{ foo.bar }}
{{ foo["bar"] }}
```
If a value is undefined, nothing is displayed. The following all output nothing if foo is undefined: `{{ foo }}`, `{{ foo.bar }}`, `{{ foo.bar.baz }}`.
GitBook provides a set of [predefined variables](variables.md) from the context.
### Filters
Filters are essentially functions that can be applied to variables. They are called with a pipe operator (`|`) and can take arguments.
```twig
{{ foo | title }}
{{ foo | join(",") }}
{{ foo | replace("foo", "bar") | capitalize }}
```
The third example shows how you can chain filters. It would display "Bar", by first replacing "foo" with "bar" and then capitalizing it.
### Tags
##### if
`if` tests a condition and lets you selectively display content. It behaves exactly as JavaScript's `if` behaves.
```twig
{% if variable %}
It is true
{% endif %}
```
If variable is defined and evaluates to true, "It is true" will be displayed. Otherwise, nothing will be.
You can specify alternate conditions with `elif` and `else`:
```twig
{% if hungry %}
I am hungry
{% elif tired %}
I am tired
{% else %}
I am good!
{% endif %}
```
##### for
`for` iterates over arrays and dictionaries.
```twig
# Chapters about GitBook
{% for article in glossary.terms['gitbook'].articles %}
* [{{ article.title }}]({{ article.path }})
{% endfor %}
```
##### set
`set` lets you create/modify a variable.
```twig
{% set softwareVersion = "1.0.0" %}
Current version is {{ softwareVersion }}.
[Download it](website.com/download/{{ softwareVersion }})
```
##### include and block
Inclusion and inheritance is detailled in the [Content References](conrefs.md) section.
### Escaping
If you want GitBook to ignore any of the special templating tags, you can use raw and anything inside of it will be output as plain text.
``` twig
{% raw %}
this will {{ not be processed }}
{% endraw %}
```
+18
View File
@@ -0,0 +1,18 @@
# Builtin Templating Helpers
GitBook provides a serie of builtin filters and blocks to help you write templates.
### Filters
`value|default(default, [boolean])`If value is strictly undefined, return default, otherwise value. If boolean is true, any JavaScript falsy value will return default (false, "", etc)
`arr|sort(reverse, caseSens, attr)`
Sort arr with JavaScript's arr.sort function. If reverse is true, result will be reversed. Sort is case-insensitive by default, but setting caseSens to true makes it case-sensitive. If attr is passed, will compare attr from each item.
### Blocks
`{% markdown %}Markdown string{% endmarkdown %}`
Render inline markdown
`{% asciidoc %}AsciiDoc string{% endasciidoc %}`
Render inline asciidoc
+55
View File
@@ -0,0 +1,55 @@
# Content References
Content referencing (conref) is a convenient mechanism to reuse content from other files or books.
### Importing local files
Importing an other file's content is easy using the `include` tag:
```
{% include "./test.md" %}
```
### Importing file from another book
GitBook can also resolve the include path by using git:
```
{% include "git+https://github.com/GitbookIO/documentation.git/README.md#0.0.1" %}
```
The format of git url is:
```
git+https://user@hostname/owner/project.git/file#commit-ish
```
The real git url part should finish with `.git`, the filename to import is extracted after the `.git` till the fragment of the url.
The `commit-ish` can be any tag, sha, or branch which can be supplied as an argument to `git checkout`. The default is `master`.
### Inheritance
Template inheritance is a way to make it easy to reuse templates. When writing a template, you can define "blocks" that child templates can override. The inheritance chain can be as long as you like.
`block` defines a section on the template and identifies it with a name. Base templates can specify blocks and child templates can override them with new content.
```
{% extends "./mypage.md" %}
{% block pageContent %}
# This is my page content
{% endblock %}
```
In the file `mypage.md`, you should specify the blocks that can be extended:
```
{% block pageContent %}
This is the default content
{% endblock %}
# License
{% include "./LICENSE" %}
```
+86
View File
@@ -0,0 +1,86 @@
# Variables
The following is a reference of the available data during book's parsing and theme generation.
### Global Variables
| Variable | Description |
| -------- | ----------- |
| `book` | Book-wide information + configuration settings from `book.json`. See below for details. |
| `gitbook` | GitBook specific information |
| `page` | Current page specific information |
| `file` | File associated with the current page specific information |
| `readme` | Information about the Readme |
| `glossary` | Information about the Glossary |
| `summary` | Information about the table of contents |
| `languages` | List of languages for multi-lingual books |
| `output` | Information about the output generator |
| `config` | Dump of the `book.json` |
### Book Variables
| Variable | Description |
| -------- | ----------- |
| `book.[CONFIGURATION_DATA]` | All the `variables` set via the `book.json` are available through the book variable. |
| `book.language` | Current language for a multilingual book |
### GitBook Variables
| Variable | Description |
| -------- | ----------- |
| `gitbook.time` | The current time (when you run the `gitbook` command) . |
| `gitbook.version` | Version of GitBook used to generate the book |
### File Variables
| Variable | Description |
| -------- | ----------- |
| `file.path` | The path to the raw page |
| `file.mtime` | Modified Time. Last time the file was modified |
| `file.type` | The name of the parser used to compile this file (ex: `markdown`, `asciidoc`, etc) |
#### Page Variables
| Variable | Description |
| -------- | ----------- |
| `page.title` | Title of the page |
| `page.previous` | Previous page in the Table of Contents (can be `null`) |
| `page.next` | Next page in the Table of Contents (can be `null`) |
| `page.dir` | Text direction, based on configuration or detected from content (`rtl` or `ltr`) |
#### Table of Contents Variables
| Variable | Description |
| -------- | ----------- |
| `summary.parts` | List of sections in the Table of Contents |
The whole table of contents (`SUMMARY.md`) can be accessed:
`summary.parts[0].articles[0].title` will return the title of the first article.
#### Multi-lingual book Variable
| Variable | Description |
| -------- | ----------- |
| `languages.list` | List of languages for this book |
Languages are defined by `{ id: 'en', title: 'English' }`.
### Output Variables
| Variable | Description |
| -------- | ----------- |
| `output.name` | Name of the output generator, possible values are `website`, `json`, `ebook` |
| `output.format` | When `output.name == "ebook"`, `format` defines the ebook format that will be generated, possible values are `pdf`, `epub` or `mobi` |
### Readme Variables
| Variable | Description |
| -------- | ----------- |
| `readme.path` | Path to the Readme in the book |
### Glossary Variables
| Variable | Description |
| -------- | ----------- |
| `glossary.path` | Path to the Glossary in the book |
+39
View File
@@ -0,0 +1,39 @@
# Theming
Since version 3.0.0, GitBook can be easily themed. Books use the [theme-default](https://github.com/GitbookIO/theme-default) theme by default.
> **Caution**: Custom theming can block some plugins from working correctly.
### Structure of a theme
A theme is a plugin containing templates and assets. Overriding any individual template is optional, since themes always extend the default theme.
| Folder | Description |
| -------- | ----------- |
| `_layouts` | Main folder containing all the templates |
| `_layouts/website/page.html` | Template for a normal page |
| `_layouts/ebook/page.html` | Template for a normal page during ebook generation (PDF< ePub, Mobi) |
### Extend/Customize theme in a book
Authors can extend the templates of a theme directly from their book's source (without creating an external theme). Templates will be resolved in the `_layouts` folder of the book first, then in the installed plugins/themes.
### Extend instead of Forking
When you want to make your theme changes available to multiple books, instead of forking the default theme, you can extend it using the [templating syntax](../templating/README.md):
```html
{% extends template.self %}
{% block body %}
{{ super() }}
... This will be added to the "body" block
{% endblock %}
```
Take a look at the [API](https://github.com/GitbookIO/theme-api) theme for a more complete example.
### Publish a theme
Themes are published as plugins ([see related docs](../plugins/README.md)) with a `theme-` prefix. For example the theme `awesome` will be loaded from the `theme-awesome` plugin, and then from the `gitbook-plugin-theme-awesome` NPM package.
+9
View File
@@ -0,0 +1,9 @@
var gitbook = require('../gitbook');
describe('satisfies', function() {
it('should return true for *', function() {
expect(gitbook.satisfies('*')).toBe(true);
});
});
+16
View File
@@ -0,0 +1,16 @@
var tmp = require('tmp');
var initBook = require('../init');
describe('initBook', function() {
it('should create a README and SUMMARY for empty book', function() {
var dir = tmp.dirSync();
return initBook(dir.name)
.then(function() {
expect(dir.name).toHaveFile('README.md');
expect(dir.name).toHaveFile('SUMMARY.md');
});
});
});
+6
View File
@@ -0,0 +1,6 @@
describe('GitBook', function() {
it('should correctly export', function() {
require('../');
});
});
+17
View File
@@ -0,0 +1,17 @@
/**
Decode changes from a JS API to a config object
@param {Config} config
@param {Object} result: result from API
@return {Config}
*/
function decodeGlobal(config, result) {
var values = result.values;
delete values.generator;
delete values.output;
return config.updateValues(values);
}
module.exports = decodeGlobal;
+22
View File
@@ -0,0 +1,22 @@
var decodeConfig = require('./decodeConfig');
/**
Decode changes from a JS API to a output object.
Only the configuration can be edited by plugin's hooks
@param {Output} output
@param {Object} result: result from API
@return {Output}
*/
function decodeGlobal(output, result) {
var book = output.getBook();
var config = book.getConfig();
// Update config
config = decodeConfig(config, result.config);
book = book.set('config', config);
return output.set('book', book);
}
module.exports = decodeGlobal;
+44
View File
@@ -0,0 +1,44 @@
var deprecate = require('./deprecate');
/**
Decode changes from a JS API to a page object.
Only the content can be edited by plugin's hooks.
@param {Output} output
@param {Page} page: page instance to edit
@param {Object} result: result from API
@return {Page}
*/
function decodePage(output, page, result) {
var originalContent = page.getContent();
// No returned value
// Existing content will be used
if (!result) {
return page;
}
deprecate.disable('page.sections');
// GitBook 3
// Use returned page.content if different from original content
if (result.content != originalContent) {
page = page.set('content', result.content);
}
// GitBook 2 compatibility
// Finally, use page.sections
else if (result.sections) {
page = page.set('content',
result.sections.map(function(section) {
return section.content;
}).join('\n')
);
}
deprecate.enable('page.sections');
return page;
}
module.exports = decodePage;
+122
View File
@@ -0,0 +1,122 @@
var is = require('is');
var objectPath = require('object-path');
var logged = {};
var disabled = {};
/**
Log a deprecated notice
@param {Book|Output} book
@param {String} key
@param {String} message
*/
function logNotice(book, key, message) {
if (logged[key] || disabled[key]) return;
logged[key] = true;
var logger = book.getLogger();
logger.warn.ln(message);
}
/**
Deprecate a function
@param {Book|Output} book
@param {String} key: unique identitifer for the deprecated
@param {Function} fn
@param {String} msg: message to print when called
@return {Function}
*/
function deprecateMethod(book, key, fn, msg) {
return function() {
logNotice(book, key, msg);
return fn.apply(this, arguments);
};
}
/**
Deprecate a property of an object
@param {Book|Output} book
@param {String} key: unique identitifer for the deprecated
@param {Object} instance
@param {String|Function} property
@param {String} msg: message to print when called
@return {Function}
*/
function deprecateField(book, key, instance, property, value, msg) {
var store = undefined;
var prepare = function() {
if (!is.undefined(store)) return;
if (is.fn(value)) store = value();
else store = value;
};
var getter = function(){
prepare();
logNotice(book, key, msg);
return store;
};
var setter = function(v) {
prepare();
logNotice(book, key, msg);
store = v;
return store;
};
Object.defineProperty(instance, property, {
get: getter,
set: setter,
enumerable: true,
configurable: true
});
}
/**
Enable a deprecation
@param {String} key: unique identitifer
*/
function enableDeprecation(key) {
disabled[key] = false;
}
/**
Disable a deprecation
@param {String} key: unique identitifer
*/
function disableDeprecation(key) {
disabled[key] = true;
}
/**
Deprecate a method in favor of another one
@param {Book} book
@param {String} key
@param {Object} instance
@param {String} oldName
@param {String} newName
*/
function deprecateRenamedMethod(book, key, instance, oldName, newName, msg) {
msg = msg || ('"' + oldName + '" is deprecated, use "' + newName + '()" instead');
var fn = objectPath.get(instance, newName);
instance[oldName] = deprecateMethod(book, key, fn, msg);
}
module.exports = {
method: deprecateMethod,
renamedMethod: deprecateRenamedMethod,
field: deprecateField,
enable: enableDeprecation,
disable: disableDeprecation
};
+36
View File
@@ -0,0 +1,36 @@
var objectPath = require('object-path');
var deprecate = require('./deprecate');
/**
Encode a config object into a JS config api
@param {Output} output
@param {Config} config
@return {Object}
*/
function encodeConfig(output, config) {
var result = {
values: config.getValues().toJS(),
get: function(key, defaultValue) {
return objectPath.get(result.values, key, defaultValue);
},
set: function(key, value) {
return objectPath.set(result.values, key, value);
}
};
deprecate.field(output, 'config.options', result, 'options',
result.values, '"config.options" property is deprecated, use "config.get(key)" instead');
deprecate.field(output, 'config.options.generator', result.values, 'generator',
output.getGenerator(), '"options.generator" property is deprecated, use "output.name" instead');
deprecate.field(output, 'config.options.generator', result.values, 'output',
output.getRoot(), '"options.output" property is deprecated, use "output.root()" instead');
return result;
}
module.exports = encodeConfig;
+257
View File
@@ -0,0 +1,257 @@
var path = require('path');
var Promise = require('../utils/promise');
var PathUtils = require('../utils/path');
var fs = require('../utils/fs');
var Plugins = require('../plugins');
var deprecate = require('./deprecate');
var fileToURL = require('../output/helper/fileToURL');
var defaultBlocks = require('../constants/defaultBlocks');
var gitbook = require('../gitbook');
var parsers = require('../parsers');
var encodeConfig = require('./encodeConfig');
var encodeSummary = require('./encodeSummary');
var encodeNavigation = require('./encodeNavigation');
var encodePage = require('./encodePage');
/**
Encode a global context into a JS object
It's the context for page's hook, etc
@param {Output} output
@return {Object}
*/
function encodeGlobal(output) {
var book = output.getBook();
var bookFS = book.getContentFS();
var logger = output.getLogger();
var outputFolder = output.getRoot();
var plugins = output.getPlugins();
var blocks = Plugins.listBlocks(plugins);
var result = {
log: logger,
config: encodeConfig(output, book.getConfig()),
summary: encodeSummary(output, book.getSummary()),
/**
Check if the book is a multilingual book
@return {Boolean}
*/
isMultilingual: function() {
return book.isMultilingual();
},
/**
Check if the book is a language book for a multilingual book
@return {Boolean}
*/
isLanguageBook: function() {
return book.isLanguageBook();
},
/**
Read a file from the book
@param {String} fileName
@return {Promise<Buffer>}
*/
readFile: function(fileName) {
return bookFS.read(fileName);
},
/**
Read a file from the book as a string
@param {String} fileName
@return {Promise<String>}
*/
readFileAsString: function(fileName) {
return bookFS.readAsString(fileName);
},
/**
Resolve a file from the book root
@param {String} fileName
@return {String}
*/
resolve: function(fileName) {
return path.resolve(book.getContentRoot(), fileName);
},
/**
Resolve a page by it path
@param {String} filePath
@return {String}
*/
getPageByPath: function(filePath) {
var page = output.getPage(filePath);
if (!page) return undefined;
return encodePage(output, page);
},
/**
Render a block of text (markdown/asciidoc)
@param {String} type
@param {String} text
@return {Promise<String>}
*/
renderBlock: function(type, text) {
var parser = parsers.get(type);
return parser.parsePage(text)
.get('content');
},
/**
Render an inline text (markdown/asciidoc)
@param {String} type
@param {String} text
@return {Promise<String>}
*/
renderInline: function(type, text) {
var parser = parsers.get(type);
return parser.parseInline(text)
.get('content');
},
template: {
/**
Apply a templating block and returns its result
@param {String} name
@param {Object} blockData
@return {Promise|Object}
*/
applyBlock: function(name, blockData) {
var block = blocks.get(name) || defaultBlocks.get(name);
return Promise(block.applyBlock(blockData, result));
}
},
output: {
/**
Name of the generator being used
{String}
*/
name: output.getGenerator(),
/**
Return absolute path to the root folder of output
@return {String}
*/
root: function() {
return outputFolder;
},
/**
Resolve a file from the output root
@param {String} fileName
@return {String}
*/
resolve: function(fileName) {
return path.resolve(outputFolder, fileName);
},
/**
Convert a filepath into an url
@return {String}
*/
toURL: function(filePath) {
return fileToURL(output, filePath);
},
/**
Check that a file exists.
@param {String} fileName
@return {Promise}
*/
hasFile: function(fileName, content) {
return Promise()
.then(function() {
var filePath = PathUtils.resolveInRoot(outputFolder, fileName);
return fs.exists(filePath);
});
},
/**
Write a file to the output folder,
It creates the required folder
@param {String} fileName
@param {Buffer} content
@return {Promise}
*/
writeFile: function(fileName, content) {
return Promise()
.then(function() {
var filePath = PathUtils.resolveInRoot(outputFolder, fileName);
return fs.ensureFile(filePath)
.then(function() {
return fs.writeFile(filePath, content);
});
});
},
/**
Copy a file to the output folder
It creates the required folder.
@param {String} inputFile
@param {String} outputFile
@param {Buffer} content
@return {Promise}
*/
copyFile: function(inputFile, outputFile, content) {
return Promise()
.then(function() {
var outputFilePath = PathUtils.resolveInRoot(outputFolder, outputFile);
return fs.ensureFile(outputFilePath)
.then(function() {
return fs.copy(inputFile, outputFilePath);
});
});
}
},
gitbook: {
version: gitbook.version
}
};
// Deprecated properties
deprecate.renamedMethod(output, 'this.isSubBook', result, 'isSubBook', 'isLanguageBook');
deprecate.renamedMethod(output, 'this.contentLink', result, 'contentLink', 'output.toURL');
deprecate.field(output, 'this.generator', result, 'generator',
output.getGenerator(), '"this.generator" property is deprecated, use "this.output.name" instead');
deprecate.field(output, 'this.navigation', result, 'navigation', function() {
return encodeNavigation(output);
}, '"navigation" property is deprecated');
deprecate.field(output, 'this.book', result, 'book',
result, '"book" property is deprecated, use "this" directly instead');
deprecate.field(output, 'this.options', result, 'options',
result.config.values, '"options" property is deprecated, use config.get(key) instead');
return result;
}
module.exports = encodeGlobal;
+64
View File
@@ -0,0 +1,64 @@
var Immutable = require('immutable');
/**
Encode an article for next/prev
@param {Map<String:Page>}
@param {Article}
@return {Object}
*/
function encodeArticle(pages, article) {
var articlePath = article.getPath();
return {
path: articlePath,
title: article.getTitle(),
level: article.getLevel(),
exists: (articlePath && pages.has(articlePath)),
external: article.isExternal()
};
}
/**
this.navigation is a deprecated property from GitBook v2
@param {Output}
@return {Object}
*/
function encodeNavigation(output) {
var book = output.getBook();
var pages = output.getPages();
var summary = book.getSummary();
var articles = summary.getArticlesAsList();
var navigation = articles
.map(function(article, i) {
var ref = article.getRef();
if (!ref) {
return undefined;
}
var prev = articles.get(i - 1);
var next = articles.get(i + 1);
return [
ref,
{
index: i,
title: article.getTitle(),
introduction: (i === 0),
prev: prev? encodeArticle(pages, prev) : undefined,
next: next? encodeArticle(pages, next) : undefined,
level: article.getLevel()
}
];
})
.filter(function(e) {
return Boolean(e);
});
return Immutable.Map(navigation).toJS();
}
module.exports = encodeNavigation;
+39
View File
@@ -0,0 +1,39 @@
var JSONUtils = require('../json');
var deprecate = require('./deprecate');
var encodeProgress = require('./encodeProgress');
/**
Encode a page in a context to a JS API
@param {Output} output
@param {Page} page
@return {Object}
*/
function encodePage(output, page) {
var book = output.getBook();
var summary = book.getSummary();
var fs = book.getContentFS();
var file = page.getFile();
// JS Page is based on the JSON output
var result = JSONUtils.encodePage(page, summary);
result.type = file.getType();
result.path = file.getPath();
result.rawPath = fs.resolve(result.path);
deprecate.field(output, 'page.progress', result, 'progress', function() {
return encodeProgress(output, page);
}, '"page.progress" property is deprecated');
deprecate.field(output, 'page.sections', result, 'sections', [
{
content: result.content,
type: 'normal'
}
], '"sections" property is deprecated, use page.content instead');
return result;
}
module.exports = encodePage;
+63
View File
@@ -0,0 +1,63 @@
var Immutable = require('immutable');
var encodeNavigation = require('./encodeNavigation');
/**
page.progress is a deprecated property from GitBook v2
@param {Output}
@param {Page}
@return {Object}
*/
function encodeProgress(output, page) {
var current = page.getPath();
var navigation = encodeNavigation(output);
navigation = Immutable.Map(navigation);
var n = navigation.size;
var percent = 0, prevPercent = 0, currentChapter = null;
var done = true;
var chapters = navigation
.map(function(nav, chapterPath) {
nav.path = chapterPath;
return nav;
})
.valueSeq()
.sortBy(function(nav) {
return nav.index;
})
.map(function(nav, i) {
// Calcul percent
nav.percent = (i * 100) / Math.max((n - 1), 1);
// Is it done
nav.done = done;
if (nav.path == current) {
currentChapter = nav;
percent = nav.percent;
done = false;
} else if (done) {
prevPercent = nav.percent;
}
return nav;
})
.toJS();
return {
// Previous percent
prevPercent: prevPercent,
// Current percent
percent: percent,
// List of chapter with progress
chapters: chapters,
// Current chapter
current: currentChapter
};
}
module.exports = encodeProgress;
+51
View File
@@ -0,0 +1,51 @@
var encodeSummaryArticle = require('../json/encodeSummaryArticle');
/**
Encode summary to provide an API to plugin
@param {Output} output
@param {Config} config
@return {Object}
*/
function encodeSummary(output, summary) {
var result = {
/**
Iterate over the summary, it stops when the "iter" returns false
@param {Function} iter
*/
walk: function (iter) {
summary.getArticle(function(article) {
var jsonArticle = encodeSummaryArticle(article, false);
return iter(jsonArticle);
});
},
/**
Get an article by its level
@param {String} level
@return {Object}
*/
getArticleByLevel: function(level) {
var article = summary.getByLevel(level);
return (article? encodeSummaryArticle(article) : undefined);
},
/**
Get an article by its path
@param {String} level
@return {Object}
*/
getArticleByPath: function(level) {
var article = summary.getByPath(level);
return (article? encodeSummaryArticle(article) : undefined);
}
};
return result;
}
module.exports = encodeSummary;
+8
View File
@@ -0,0 +1,8 @@
module.exports = {
encodePage: require('./encodePage'),
decodePage: require('./decodePage'),
encodeGlobal: require('./encodeGlobal'),
decodeGlobal: require('./decodeGlobal')
};
-865
View File
@@ -1,865 +0,0 @@
var Q = require("q");
var _ = require("lodash");
var path = require("path");
var util = require("util");
var lunr = require("lunr");
var parsers = require("gitbook-parsers");
var color = require("bash-color");
var fs = require("./utils/fs");
var parseNavigation = require("./utils/navigation");
var parseProgress = require("./utils/progress");
var pageUtil = require("./utils/page");
var batch = require("./utils/batch");
var links = require("./utils/links");
var i18n = require("./utils/i18n");
var logger = require("./utils/logger");
var Configuration = require("./configuration");
var TemplateEngine = require("./template");
var Plugin = require("./plugin");
var PluginsList = require("./pluginslist");
var generators = require("./generators");
var Book = function(root, context, parent) {
var that = this;
this.context = _.defaults(context || {}, {
// Extend book configuration
config: {},
// Log function
log: function(msg) {
process.stdout.write(msg);
},
// Log level
logLevel: "info"
});
// Log
this.log = logger(this.context.log, this.context.logLevel);
// Root folder of the book
this.root = path.resolve(root);
// Parent book
this.parent = parent;
// Configuration
this.config = new Configuration(this, this.context.config);
Object.defineProperty(this, "options", {
get: function () {
return this.config.options;
}
});
// Template
this.template = new TemplateEngine(this);
// Summary
this.summary = {};
this.navigation = [];
// Glossary
this.glossary = [];
// Langs
this.langs = [];
// Sub-books
this.books = [];
// Files in the book
this.files = [];
// List of plugins
this.plugins = new PluginsList(this);
// Structure files
this.summaryFile = null;
this.glossaryFile = null;
this.readmeFile = null;
this.langsFile = null;
// Search Index
this.searchIndex = lunr(function () {
this.ref('url');
this.field('title', { boost: 10 });
this.field('body');
});
// Bind methods
_.bindAll(this);
};
// Return string representation
Book.prototype.toString = function() {
return "[Book "+this.root+"]";
};
// Initialize and parse the book: config, summary, glossary
Book.prototype.parse = function() {
var that = this;
var multilingual = false;
return this.parseConfig()
.then(function() {
return that.parsePlugins();
})
.then(function() {
return that.parseLangs()
.then(function() {
multilingual = that.langs.length > 0;
if (multilingual) that.log.info.ln("Parsing multilingual book, with", that.langs.length, "languages");
// Sub-books that inherit from the current book configuration
that.books = _.map(that.langs, function(lang) {
that.log.info.ln("Preparing language book", lang.lang);
return new Book(
path.join(that.root, lang.path),
_.merge({}, that.context, {
config: _.extend({}, that.options, {
'output': path.join(that.options.output, lang.lang),
'language': lang.lang
})
}),
that
)
});
});
})
.then(function() {
if (multilingual) return;
return that.listAllFiles();
})
.then(function() {
if (multilingual) return;
return that.parseReadme();
})
.then(function() {
if (multilingual) return;
return that.parseSummary();
})
.then(function() {
if (multilingual) return;
return that.parseGlossary();
})
.then(function() {
// Init sub-books
return _.reduce(that.books, function(prev, book) {
return prev.then(function() {
return book.parse();
});
}, Q());
})
.thenResolve(this);
};
// Generate the output
Book.prototype.generate = function(generator) {
var that = this;
that.options.generator = generator || that.options.generator;
that.log.info.ln("start generation with", that.options.generator, "generator");
return Q()
// Clean output folder
.then(function() {
that.log.info("clean", that.options.generator, "generator");
return fs.clean(that.options.output)
.progress(function(p) {
that.log.debug.ln("remove", p.file, "("+p.i+"/"+p.count+")");
})
.then(function() {
that.log.info.ok();
});
})
// Create generator
.then(function() {
var Generator = generators[generator];
if (!Generator) throw "Generator '"+that.options.generator+"' doesn't exist";
generator = new Generator(that);
return generator.prepare();
})
// Generate content
.then(function() {
if (that.isMultilingual()) {
return that.generateMultiLingual(generator);
} else {
// Separate list of files into the different operations needed
var ops = _.groupBy(that.files, function(file) {
if (file[file.length -1] == "/") {
return "directories";
} else if (_.contains(parsers.extensions, path.extname(file)) && that.navigation[file]) {
return "content";
} else {
return "files";
}
});
return Q()
// First, let's create folder
.then(function() {
return _.reduce(ops["directories"] || [], function(prev, folder) {
return prev.then(function() {
that.log.debug.ln("transferring folder", folder);
return Q(generator.transferFolder(folder));
});
}, Q());
})
// Then, let's copy other files
.then(function() {
return Q.all(_.map(ops["files"] || [], function(file) {
that.log.debug.ln("transferring file", file);
return Q(generator.transferFile(file));
}));
})
// Finally let's generate content
.then(function() {
var nFiles = (ops["content"] || []).length;
return _.reduce(ops["content"] || [], function(prev, file, i) {
return prev.then(function() {
var p = ((i*100)/nFiles).toFixed(0)+"%";
that.log.debug.ln("processing", file, p);
return Q(generator.convertFile(file))
.fail(function(err) {
// Transform error message to signal file
throw that.normError(err, {
fileName: file
});
});
});
}, Q());
});
}
})
// Finish generation
.then(function() {
return generator.callHook("finish:before");
})
.then(function() {
return generator.finish();
})
.then(function() {
return generator.callHook("finish");
})
.then(function() {
that.log.info.ln("generation is finished");
});
};
// Generate the output for a multilingual book
Book.prototype.generateMultiLingual = function(generator) {
var that = this;
return Q()
.then(function() {
// Generate sub-books
return _.reduce(that.books, function(prev, book) {
return prev.then(function() {
return book.generate(that.options.generator);
});
}, Q());
});
};
// Extract files from ebook generated
Book.prototype.generateFile = function(output, options) {
var book = this;
options = _.defaults(options || {}, {
ebookFormat: path.extname(output).slice(1)
});
output = output || path.resolve(book.root, "book."+options.ebookFormat);
return fs.tmp.dir()
.then(function(tmpDir) {
book.setOutput(tmpDir);
return book.generate(options.ebookFormat)
.then(function(_options) {
var copyFile = function(lang) {
var _outputFile = output;
var _tmpDir = tmpDir;
if (lang) {
_outputFile = _outputFile.slice(0, -path.extname(_outputFile).length)+"_"+lang+path.extname(_outputFile);
_tmpDir = path.join(_tmpDir, lang);
}
book.log.debug.ln("copy ebook to", _outputFile);
return fs.copy(
path.join(_tmpDir, "index."+options.ebookFormat),
_outputFile
);
};
// Multi-langs book
return Q()
.then(function() {
if (book.isMultilingual()) {
return Q.all(
_.map(book.langs, function(lang) {
return copyFile(lang.lang);
})
)
.thenResolve(book.langs.length);
} else {
return copyFile().thenResolve(1);
}
})
.then(function(n) {
book.log.info.ok(n+" file(s) generated");
return fs.remove(tmpDir);
});
});
});
};
// Parse configuration
Book.prototype.parseConfig = function() {
var that = this;
that.log.info("loading book configuration....")
return that.config.load()
.then(function() {
that.log.info.ok();
});
};
// Parse list of plugins
Book.prototype.parsePlugins = function() {
var that = this;
var failed = [];
// Load plugins
return that.plugins.load(that.options.plugins)
.then(function() {
if (_.size(that.plugins.failed) > 0) return Q.reject(new Error("Error loading plugins: "+that.plugins.failed.join(",")+". Run 'gitbook install' to install plugins from NPM."));
that.log.info.ok(that.plugins.count()+" plugins loaded");
that.log.debug.ln("normalize plugins list");
});
};
// Parse readme to extract defaults title and description
Book.prototype.parseReadme = function() {
var that = this;
var structure = that.config.getStructure("readme");
that.log.debug.ln("start parsing readme:", structure);
return that.findFile(structure)
.then(function(readme) {
if (!readme) throw "No README file";
if (!_.contains(that.files, readme.path)) throw "README file is ignored";
that.readmeFile = readme.path;
that._defaultsStructure(that.readmeFile);
that.log.debug.ln("readme located at", that.readmeFile);
return that.template.renderFile(that.readmeFile)
.then(function(content) {
return readme.parser.readme(content)
.fail(function(err) {
throw that.normError(err, {
name: err.name || "Readme Parse Error",
fileName: that.readmeFile
});
});
});
})
.then(function(readme) {
that.options.title = that.options.title || readme.title;
that.options.description = that.options.description || readme.description;
});
};
// Parse langs to extract list of sub-books
Book.prototype.parseLangs = function() {
var that = this;
var structure = that.config.getStructure("langs");
that.log.debug.ln("start parsing languages index:", structure);
return that.findFile(structure)
.then(function(langs) {
if (!langs) return [];
that.langsFile = langs.path;
that._defaultsStructure(that.langsFile);
that.log.debug.ln("languages index located at", that.langsFile);
return that.template.renderFile(that.langsFile)
.then(function(content) {
return langs.parser.langs(content)
.fail(function(err) {
throw that.normError(err, {
name: err.name || "Langs Parse Error",
fileName: that.langsFile
});
});
});
})
.then(function(langs) {
that.langs = langs;
});
};
// Parse summary to extract list of chapters
Book.prototype.parseSummary = function() {
var that = this;
var structure = that.config.getStructure("summary");
that.log.debug.ln("start parsing summary:", structure);
return that.findFile(structure)
.then(function(summary) {
if (!summary) throw "No SUMMARY file";
// Remove the summary from the list of files to parse
that.summaryFile = summary.path;
that._defaultsStructure(that.summaryFile);
that.files = _.without(that.files, that.summaryFile);
that.log.debug.ln("summary located at", that.summaryFile);
return that.template.renderFile(that.summaryFile)
.then(function(content) {
return summary.parser.summary(content, {
entryPoint: that.readmeFile,
entryPointTitle: that.i18n('SUMMARY_INTRODUCTION'),
files: that.files
})
.fail(function(err) {
throw that.normError(err, {
name: err.name || "Summary Parse Error",
fileName: that.summaryFile
});
});
});
})
.then(function(summary) {
that.summary = summary;
that.navigation = parseNavigation(that.summary, that.files);
});
};
// Parse glossary to extract terms
Book.prototype.parseGlossary = function() {
var that = this;
var structure = that.config.getStructure("glossary");
that.log.debug.ln("start parsing glossary: ", structure);
return that.findFile(structure)
.then(function(glossary) {
if (!glossary) return [];
// Remove the glossary from the list of files to parse
that.glossaryFile = glossary.path;
that._defaultsStructure(that.glossaryFile);
that.files = _.without(that.files, that.glossaryFile);
that.log.debug.ln("glossary located at", that.glossaryFile);
return that.template.renderFile(that.glossaryFile)
.then(function(content) {
return glossary.parser.glossary(content)
.fail(function(err) {
throw that.normError(err, {
name: err.name || "Glossary Parse Error",
fileName: that.glossaryFile
});
});
});
})
.then(function(glossary) {
that.glossary = glossary;
});
};
// Parse a page
Book.prototype.parsePage = function(filename, options) {
var that = this, page = {};
options = _.defaults(options || {}, {
// Transform svg images
convertImages: false,
// Interpolate before templating
interpolateTemplate: _.identity,
// Interpolate after templating
interpolateContent: _.identity
});
var interpolate = function(fn) {
return Q(fn(page))
.then(function(_page) {
page = _page || page;
});
};
that.log.debug.ln("start parsing file", filename);
var extension = path.extname(filename);
var filetype = parsers.get(extension);
if (!filetype) return Q.reject(new Error("Can't parse file: "+filename));
// Type of parser used
page.type = filetype.name;
// Path relative to book
page.path = filename;
// Path absolute in the system
page.rawPath = path.resolve(that.root, filename);
// Progress in the book
page.progress = parseProgress(that.navigation, filename);
that.log.debug.ln("render template", filename);
// Read file content
return that.readFile(page.path)
.then(function(content) {
page.content = content;
return interpolate(options.interpolateTemplate);
})
// Prepare page markup
.then(function() {
return filetype.page.prepare(page.content)
.then(function(content) {
page.content = content;
});
})
// Generate template
.then(function() {
return that.template.renderPage(page);
})
// Prepare and Parse markup
.then(function(content) {
page.content = content;
that.log.debug.ln("use file parser", filetype.name, "for", filename);
return filetype.page(page.content);
})
// Post process sections
.then(function(_page) {
return _.reduce(_page.sections, function(prev, section) {
return prev.then(function(_sections) {
return that.template.postProcess(section.content || "")
.then(function(content) {
section.content = content;
return _sections.concat([section]);
})
});
}, Q([]));
})
// Prepare html
.then(function(_sections) {
return pageUtil.normalize(_sections, {
book: that,
convertImages: options.convertImages,
input: filename,
navigation: that.navigation,
base: path.dirname(filename) || './',
output: path.dirname(filename) || './',
glossary: that.glossary
});
})
// Interpolate output
.then(function(_sections) {
page.sections = _sections;
return interpolate(options.interpolateContent);
})
.then(function() {
that.indexPage(page);
return page;
});
};
// Find file that can be parsed with a specific filename
Book.prototype.findFile = function(filename) {
var that = this;
return _.reduce(parsers.extensions, function(prev, ext) {
return prev.then(function(output) {
// Stop if already find a parser
if (output) return output;
var filepath = filename+ext;
return that.fileExists(filepath)
.then(function(exists) {
if (!exists) return null;
return {
parser: parsers.get(ext),
path: filepath
};
})
});
}, Q(null));
};
// Check if a file exists in the book
Book.prototype.fileExists = function(filename) {
return fs.exists(
path.join(this.root, filename)
);
};
// Read a file
Book.prototype.readFile = function(filename) {
return fs.readFile(
path.join(this.root, filename),
{ encoding: "utf8" }
);
};
// Return stat for a file
Book.prototype.statFile = function(filename) {
return fs.stat(path.join(this.root, filename));
};
// List all files in the book
Book.prototype.listAllFiles = function() {
var that = this;
return fs.list(this.root, {
ignoreFiles: ['.ignore', '.gitignore', '.bookignore'],
ignoreRules: [
// Skip Git stuff
'.git/',
'.gitignore',
// Skip OS X meta data
'.DS_Store',
// Skip stuff installed by plugins
'node_modules',
// Skip book outputs
'_book',
'*.pdf',
'*.epub',
'*.mobi',
// Skip config files
'.ignore',
'.bookignore',
'book.json',
]
})
.then(function(_files) {
that.files = _files;
});
};
// Return true if the book is a multilingual book
Book.prototype.isMultilingual = function(filename) {
return this.books.length > 0;
};
// Return root of the parent
Book.prototype.parentRoot = function() {
if (this.parent) return this.parent.parentRoot();
return this.root;
};
// Return true if it's a sub-book
Book.prototype.isSubBook = function() {
return !!this.parent;
};
// Test if the file is the entry point
Book.prototype.isEntryPoint = function(fp) {
return fp == this.readmeFile;
};
// Resolve a path in book
Book.prototype.resolve = function(p) {
return path.resolve(this.root, p);
};
// Normalize a path to .html and convert README -> index
Book.prototype.contentPath = function(link) {
if (
path.basename(link, path.extname(link)) == "README"
|| link == this.readmeFile
) {
link = path.join(path.dirname(link), "index"+path.extname(link));
}
link = links.changeExtension(link, ".html");
return link;
}
// Normalize a link to .html and convert README -> index
Book.prototype.contentLink = function(link) {
return links.normalize(this.contentPath(link));
}
// Index a page into the search index
Book.prototype.indexPage = function(page) {
var nav = this.navigation[page.path];
if (!nav) return;
this.log.debug.ln("index page", page.path);
this.searchIndex.add({
url: this.contentLink(page.path),
title: nav.title,
body: pageUtil.extractText(page.sections),
});
};
// Default structure paths to an extension
Book.prototype._defaultsStructure = function(filename) {
var that = this;
var extension = path.extname(filename);
that.readmeFile = that.readmeFile || that.config.getStructure("readme")+extension;
that.summaryFile = that.summaryFile || that.config.getStructure("summary")+extension;
that.glossaryFile = that.glossaryFile || that.config.getStructure("glossary")+extension;
that.langsFile = that.langsFile || that.config.getStructure("langs")+extension;
}
// Change output path
Book.prototype.setOutput = function(p) {
var that = this;
this.options.output = path.resolve(p);
_.each(this.books, function(book) {
book.setOutput(path.join(that.options.output, book.options.language));
});
};
// Translate a strign according to the book language
Book.prototype.i18n = function(phrase) {
var args = Array.prototype.slice.call(arguments);
return i18n.__.apply({}, [this.config.normalizeLanguage()].concat(args));
};
// Normalize error
Book.prototype.normError = function(err, opts, defs) {
if (_.isString(err)) err = new Error(err);
// Extend err
_.extend(err, opts || {});
_.defaults(err, defs || {});
err.lineNumber = err.lineNumber || err.lineno;
err.columnNumber = err.columnNumber || err.colno;
err.toString = function() {
var attributes = [];
if (this.fileName) attributes.push("In file '"+this.fileName+"'");
if (this.lineNumber) attributes.push("Line "+this.lineNumber);
if (this.columnNumber) attributes.push("Column "+this.columnNumber);
return (this.name || "Error")+": "+this.message+((attributes.length > 0)? " ("+attributes.join(", ")+")" : "")
};
return err;
};
// Init and return a book
Book.init = function(root, opts) {
var book = new Book(root, opts);
var extensionToUse = ".md";
var chaptersPaths = function(chapters) {
return _.reduce(chapters || [], function(accu, chapter) {
var o = {
title: chapter.title
};
if (chapter.path) o.path = chapter.path;
return accu.concat(
[o].concat(chaptersPaths(chapter.articles))
);
}, []);
};
book.log.info.ln("init book at", root);
return fs.mkdirp(root)
.then(function() {
book.log.info.ln("detect structure from SUMMARY (if it exists)");
return book.parseSummary();
})
.fail(function() {
return Q();
})
.then(function() {
var summary = book.summaryFile || "SUMMARY.md";
var chapters = book.summary.chapters || [];
extensionToUse = path.extname(summary);
if (chapters.length == 0) {
chapters = [
{
title: "Summary",
path: "SUMMARY"+extensionToUse
},
{
title: "Introduction",
path: "README"+extensionToUse
}
];
}
return Q(chaptersPaths(chapters));
})
.then(function(chapters) {
// Create files that don't exist
return Q.all(_.map(chapters, function(chapter) {
if (!chapter.path) return Q();
var absolutePath = path.resolve(book.root, chapter.path);
return fs.exists(absolutePath)
.then(function(exists) {
if(exists) {
book.log.info.ln("found", chapter.path);
return;
} else {
book.log.info.ln("create", chapter.path);
}
return fs.mkdirp(path.dirname(absolutePath))
.then(function() {
return fs.writeFile(absolutePath, '# '+chapter.title+'\n');
});
});
}));
})
.then(function() {
book.log.info.ln("initialization is finished");
});
};
module.exports= Book;
+26
View File
@@ -0,0 +1,26 @@
var Modifiers = require('./modifiers');
module.exports = {
Parse: require('./parse'),
// Models
Book: require('./models/book'),
FS: require('./models/fs'),
File: require('./models/file'),
Summary: require('./models/summary'),
Glossary: require('./models/glossary'),
Config: require('./models/config'),
Page: require('./models/page'),
PluginDependency: require('./models/pluginDependency'),
// Modifiers
SummaryModifier: Modifiers.Summary,
ConfigModifier: Modifiers.Config,
// Constants
CONFIG_FILES: require('./constants/configFiles.js'),
IGNORE_FILES: require('./constants/ignoreFiles.js'),
DEFAULT_PLUGINS: require('./constants/defaultPlugins'),
EXTENSIONS_MARKDOWN: require('./constants/extsMarkdown'),
EXTENSIONS_ASCIIDOC: require('./constants/extsAsciidoc')
};
+34
View File
@@ -0,0 +1,34 @@
var Parse = require('../parse');
var Output = require('../output');
var timing = require('../utils/timing');
var options = require('./options');
var getBook = require('./getBook');
var getOutputFolder = require('./getOutputFolder');
module.exports = {
name: 'build [book] [output]',
description: 'build a book',
options: [
options.log,
options.format,
options.timing
],
exec: function(args, kwargs) {
var book = getBook(args, kwargs);
var outputFolder = getOutputFolder(args);
var Generator = Output.getGenerator(kwargs.format);
return Parse.parseBook(book)
.then(function(resultBook) {
return Output.generate(Generator, resultBook, {
root: outputFolder
});
})
.fin(function() {
if (kwargs.timing) timing.dump(book.getLogger());
});
}
};
+78
View File
@@ -0,0 +1,78 @@
var path = require('path');
var tmp = require('tmp');
var Promise = require('../utils/promise');
var fs = require('../utils/fs');
var Parse = require('../parse');
var Output = require('../output');
var options = require('./options');
var getBook = require('./getBook');
module.exports = function(format) {
return {
name: (format + ' [book] [output]'),
description: 'build a book into an ebook file',
options: [
options.log
],
exec: function(args, kwargs) {
var extension = '.' + format;
// Output file will be stored in
var outputFile = args[1] || ('book' + extension);
// Create temporary directory
var outputFolder = tmp.dirSync().name;
var book = getBook(args, kwargs);
var logger = book.getLogger();
var Generator = Output.getGenerator('ebook');
return Parse.parseBook(book)
.then(function(resultBook) {
return Output.generate(Generator, resultBook, {
root: outputFolder,
format: format
});
})
// Extract ebook file
.then(function(output) {
var book = output.getBook();
var languages = book.getLanguages();
if (book.isMultilingual()) {
return Promise.forEach(languages.getList(), function(lang) {
var langID = lang.getID();
var langOutputFile = path.join(
path.dirname(outputFile),
path.basename(outputFile, extension) + '_' + langID + extension
);
return fs.copy(
path.resolve(outputFolder, langID, 'index' + extension),
langOutputFile
);
})
.thenResolve(languages.getCount());
} else {
return fs.copy(
path.resolve(outputFolder, 'index' + extension),
outputFile
).thenResolve(1);
}
})
// Log end
.then(function(count) {
logger.info.ok(count + ' file(s) generated');
logger.debug('cleaning up... ');
return logger.debug.promise(fs.rmDir(outputFolder));
});
}
};
};
+23
View File
@@ -0,0 +1,23 @@
var path = require('path');
var Book = require('../models/book');
var createNodeFS = require('../fs/node');
/**
Return a book instance to work on from
command line args/kwargs
@param {Array} args
@param {Object} kwargs
@return {Book}
*/
function getBook(args, kwargs) {
var input = path.resolve(args[0] || process.cwd());
var logLevel = kwargs.log;
var fs = createNodeFS(input);
var book = Book.createForFS(fs);
return book.setLogLevel(logLevel);
}
module.exports = getBook;
+17
View File
@@ -0,0 +1,17 @@
var path = require('path');
/**
Return path to output folder
@param {Array} args
@return {String}
*/
function getOutputFolder(args) {
var bookRoot = path.resolve(args[0] || process.cwd());
var defaultOutputRoot = path.join(bookRoot, '_book');
var outputFolder = args[1]? path.resolve(process.cwd(), args[1]) : defaultOutputRoot;
return outputFolder;
}
module.exports = getOutputFolder;
+12
View File
@@ -0,0 +1,12 @@
var buildEbook = require('./buildEbook');
module.exports = [
require('./build'),
require('./serve'),
require('./install'),
require('./parse'),
require('./init'),
buildEbook('pdf'),
buildEbook('epub'),
buildEbook('mobi')
];
+17
View File
@@ -0,0 +1,17 @@
var path = require('path');
var options = require('./options');
var initBook = require('../init');
module.exports = {
name: 'init [book]',
description: 'setup and create files for chapters',
options: [
options.log
],
exec: function(args, kwargs) {
var bookRoot = path.resolve(process.cwd(), args[0] || './');
return initBook(bookRoot);
}
};
+21
View File
@@ -0,0 +1,21 @@
var options = require('./options');
var getBook = require('./getBook');
var Parse = require('../parse');
var Plugins = require('../plugins');
module.exports = {
name: 'install [book]',
description: 'install all plugins dependencies',
options: [
options.log
],
exec: function(args, kwargs) {
var book = getBook(args, kwargs);
return Parse.parseConfig(book)
.then(function(resultBook) {
return Plugins.installPlugins(resultBook);
});
}
};
+31
View File
@@ -0,0 +1,31 @@
var Logger = require('../utils/logger');
var logOptions = {
name: 'log',
description: 'Minimum log level to display',
values: Logger.LEVELS
.keySeq()
.map(function(s) {
return s.toLowerCase();
}).toJS(),
defaults: 'info'
};
var formatOption = {
name: 'format',
description: 'Format to build to',
values: ['website', 'json', 'ebook'],
defaults: 'website'
};
var timingOption = {
name: 'timing',
description: 'Print timing debug information',
defaults: false
};
module.exports = {
log: logOptions,
format: formatOption,
timing: timingOption
};
+79
View File
@@ -0,0 +1,79 @@
var options = require('./options');
var getBook = require('./getBook');
var Parse = require('../parse');
function printBook(book) {
var logger = book.getLogger();
var config = book.getConfig();
var configFile = config.getFile();
var summary = book.getSummary();
var summaryFile = summary.getFile();
var readme = book.getReadme();
var readmeFile = readme.getFile();
var glossary = book.getGlossary();
var glossaryFile = glossary.getFile();
if (configFile.exists()) {
logger.info.ln('Configuration file is', configFile.getPath());
}
if (readmeFile.exists()) {
logger.info.ln('Introduction file is', readmeFile.getPath());
}
if (glossaryFile.exists()) {
logger.info.ln('Glossary file is', glossaryFile.getPath());
}
if (summaryFile.exists()) {
logger.info.ln('Table of Contents file is', summaryFile.getPath());
}
}
function printMultingualBook(book) {
var logger = book.getLogger();
var languages = book.getLanguages();
var books = book.getBooks();
logger.info.ln(languages.size + ' languages');
languages.forEach(function(lang) {
logger.info.ln('Language:', lang.getTitle());
printBook(books.get(lang.getID()));
logger.info.ln('');
});
}
module.exports = {
name: 'parse [book]',
description: 'parse and print debug information about a book',
options: [
options.log
],
exec: function(args, kwargs) {
var book = getBook(args, kwargs);
var logger = book.getLogger();
return Parse.parseBook(book)
.then(function(resultBook) {
var rootFolder = book.getRoot();
var contentFolder = book.getContentRoot();
logger.info.ln('Book located in:', rootFolder);
if (contentFolder != rootFolder) {
logger.info.ln('Content located in:', contentFolder);
}
if (resultBook.isMultilingual()) {
printMultingualBook(resultBook);
} else {
printBook(resultBook);
}
});
}
};
+159
View File
@@ -0,0 +1,159 @@
/* eslint-disable no-console */
var tinylr = require('tiny-lr');
var open = require('open');
var Parse = require('../parse');
var Output = require('../output');
var ConfigModifier = require('../modifiers').Config;
var Promise = require('../utils/promise');
var options = require('./options');
var getBook = require('./getBook');
var getOutputFolder = require('./getOutputFolder');
var Server = require('./server');
var watch = require('./watch');
var server, lrServer, lrPath;
function waitForCtrlC() {
var d = Promise.defer();
process.on('SIGINT', function() {
d.resolve();
});
return d.promise;
}
function generateBook(args, kwargs) {
var port = kwargs.port;
var outputFolder = getOutputFolder(args);
var book = getBook(args, kwargs);
var Generator = Output.getGenerator(kwargs.format);
var browser = kwargs['browser'];
var hasWatch = kwargs['watch'];
var hasLiveReloading = kwargs['live'];
var hasOpen = kwargs['open'];
// Stop server if running
if (server.isRunning()) console.log('Stopping server');
return server.stop()
.then(function() {
return Parse.parseBook(book)
.then(function(resultBook) {
if (hasLiveReloading) {
// Enable livereload plugin
var config = resultBook.getConfig();
config = ConfigModifier.addPlugin(config, 'livereload');
resultBook = resultBook.set('config', config);
}
return Output.generate(Generator, resultBook, {
root: outputFolder
});
});
})
.then(function() {
console.log();
console.log('Starting server ...');
return server.start(outputFolder, port);
})
.then(function() {
console.log('Serving book on http://localhost:'+port);
if (lrPath && hasLiveReloading) {
// trigger livereload
lrServer.changed({
body: {
files: [lrPath]
}
});
}
if (hasOpen) {
open('http://localhost:'+port, browser);
}
})
.then(function() {
if (!hasWatch) {
return waitForCtrlC();
}
return watch(book.getRoot())
.then(function(filepath) {
// set livereload path
lrPath = filepath;
console.log('Restart after change in file', filepath);
console.log('');
return generateBook(args, kwargs);
});
});
}
module.exports = {
name: 'serve [book] [output]',
description: 'serve the book as a website for testing',
options: [
{
name: 'port',
description: 'Port for server to listen on',
defaults: 4000
},
{
name: 'lrport',
description: 'Port for livereload server to listen on',
defaults: 35729
},
{
name: 'watch',
description: 'Enable file watcher and live reloading',
defaults: true
},
{
name: 'live',
description: 'Enable live reloading',
defaults: true
},
{
name: 'open',
description: 'Enable opening book in browser',
defaults: false
},
{
name: 'browser',
description: 'Specify browser for opening book',
defaults: ''
},
options.log,
options.format
],
exec: function(args, kwargs) {
server = new Server();
var hasWatch = kwargs['watch'];
var hasLiveReloading = kwargs['live'];
return Promise()
.then(function() {
if (!hasWatch || !hasLiveReloading) {
return;
}
lrServer = tinylr({});
return Promise.nfcall(lrServer.listen.bind(lrServer), kwargs.lrport)
.then(function() {
console.log('Live reload server started on port:', kwargs.lrport);
console.log('Press CTRL+C to quit ...');
console.log('');
});
})
.then(function() {
return generateBook(args, kwargs);
});
}
};
+50 -18
View File
@@ -1,34 +1,41 @@
var Q = require('q');
var _ = require('lodash');
var events = require('events');
var http = require('http');
var send = require('send');
var util = require('util');
var url = require('url');
var Server = function() {
var Promise = require('../utils/promise');
function Server() {
this.running = null;
this.dir = null;
this.port = 0;
this.sockets = [];
};
}
util.inherits(Server, events.EventEmitter);
// Return true if the server is running
/**
Return true if the server is running
@return {Boolean}
*/
Server.prototype.isRunning = function() {
return this.running != null;
return !!this.running;
};
// Stop the server
/**
Stop the server
@return {Promise}
*/
Server.prototype.stop = function() {
var that = this;
if (!this.isRunning()) return Q();
if (!this.isRunning()) return Promise();
var d = Q.defer();
var d = Promise.defer();
this.running.close(function(err) {
that.running = null;
that.emit("state", false);
that.emit('state', false);
if (err) d.reject(err);
else d.resolve();
@@ -41,14 +48,19 @@ Server.prototype.stop = function() {
return d.promise;
};
/**
Start the server
@return {Promise}
*/
Server.prototype.start = function(dir, port) {
var that = this, pre = Q();
var that = this, pre = Promise();
port = port || 8004;
if (that.isRunning()) pre = this.stop();
return pre
.then(function() {
var d = Q.defer();
var d = Promise.defer();
that.running = http.createServer(function(req, res){
// Render error
@@ -59,14 +71,22 @@ Server.prototype.start = function(dir, port) {
// Redirect to directory's index.html
function redirect() {
var resultURL = urlTransform(req.url, function(parsed) {
parsed.pathname += '/';
return parsed;
});
res.statusCode = 301;
res.setHeader('Location', req.url + '/');
res.end('Redirecting to ' + req.url + '/');
res.setHeader('Location', resultURL);
res.end('Redirecting to ' + resultURL);
}
res.setHeader('X-Current-Location', req.url);
// Send file
send(req, url.parse(req.url).pathname)
.root(dir)
send(req, url.parse(req.url).pathname, {
root: dir
})
.on('error', error)
.on('directory', redirect)
.pipe(res);
@@ -85,12 +105,24 @@ Server.prototype.start = function(dir, port) {
that.port = port;
that.dir = dir;
that.emit("state", true);
that.emit('state', true);
d.resolve();
});
return d.promise;
});
};
/**
urlTransform is a helper function that allows a function to transform
a url string in it's parsed form and returns the new url as a string
@param {String} uri
@param {Function} fn
@return {String}
*/
function urlTransform(uri, fn) {
return url.format(fn(url.parse(uri)));
}
module.exports = Server;
+46
View File
@@ -0,0 +1,46 @@
var path = require('path');
var chokidar = require('chokidar');
var Promise = require('../utils/promise');
var parsers = require('../parsers');
/**
Watch a folder and resolve promise once a file is modified
@param {String} dir
@return {Promise}
*/
function watch(dir) {
var d = Promise.defer();
dir = path.resolve(dir);
var toWatch = [
'book.json', 'book.js', '_layouts/**'
];
// Watch all parsable files
parsers.extensions.forEach(function(ext) {
toWatch.push('**/*'+ext);
});
var watcher = chokidar.watch(toWatch, {
cwd: dir,
ignored: '_book/**',
ignoreInitial: true
});
watcher.once('all', function(e, filepath) {
watcher.close();
d.resolve(filepath);
});
watcher.once('error', function(err) {
watcher.close();
d.reject(err);
});
return d.promise;
}
module.exports = watch;
-278
View File
@@ -1,278 +0,0 @@
var _ = require("lodash");
var Q = require("q");
var path = require("path");
var semver = require('semver');
var pkg = require('../package.json');
var fs = require("./utils/fs");
var i18n = require("./utils/i18n");
// Default plugins added to each books
var defaultsPlugins = [];
// Normalize a list of plugins to use
function normalizePluginsList(plugins) {
// Normalize list to an array
plugins = _.isString(plugins) ? plugins.split(",") : (plugins || []);
// Remove empty parts
plugins = _.compact(plugins);
// Divide as {name, version} to handle format like "myplugin@1.0.0"
plugins = _.map(plugins, function(plugin) {
if (plugin.name) return plugin;
var parts = plugin.split("@");
return {
'name': parts[0],
'version': parts[1] // optional
}
});
// List plugins to remove
var toremove = _.chain(plugins)
.filter(function(plugin) {
return plugin.name.length > 0 && plugin.name[0] == "-";
})
.map(function(plugin) {
return plugin.name.slice(1);
})
.value();
// Merge with defaults
plugins = _.chain(plugins)
.concat(_.map(defaultsPlugins, function(plugin) {
return { 'name': plugin }
}))
.uniq()
.value();
// Build final list
plugins = _.filter(plugins, function(plugin) {
return !_.contains(toremove, plugin.name) && !(plugin.name.length > 0 && plugin.name[0] == "-");
});
return plugins;
}
// Normalize a list of plugin name to use
function normalizePluginsNames(plugins) {
return _.pluck(normalizePluginsList(plugins), "name");
};
var Configuration = function(book, options) {
var that = this;
this.book = book;
this.options = _.cloneDeep(Configuration.DEFAULT);
this.options = _.merge(this.options, options || {});
// options.input == book.root
Object.defineProperty(this.options, "input", {
get: function () {
return that.book.root;
}
});
// options.originalInput == book.parent.root
Object.defineProperty(this.options, "originalInput", {
get: function () {
return that.book.parent? that.book.parent.root : undefined;
}
});
// options.originalOutput == book.parent.options.output
Object.defineProperty(this.options, "originalOutput", {
get: function () {
return that.book.parent? that.book.parent.options.output : undefined;
}
});
};
// Read and parse the configuration
Configuration.prototype.load = function() {
var that = this;
return Q()
.then(function() {
var configPath, config;
try {
configPath = require.resolve(
path.resolve(that.book.root, that.options.configFile)
);
// Invalidate node.js cache for livreloading
delete require.cache[configPath];
_config = require(configPath);
that.options = _.merge(
that.options,
_.omit(_config, 'configFile', 'defaultsPlugins', 'generator', 'extension')
);
}
catch(err) {
if (err instanceof SyntaxError) return Q.reject(err);
return Q();
}
})
.then(function() {
if (!semver.satisfies(pkg.version, that.options.gitbook)) {
throw "GitBook version doesn't satisfy version required by the book: "+that.options.gitbook;
}
if (that.options.gitbook != '*' && !semver.satisfies(semver.inc(pkg.version, 'patch'), that.options.gitbook)) {
that.book.log.warn.ln("gitbook version specified in your book.json might be too strict for future patches, \""+(_.first(pkg.version.split("."))+".x.x")+"\" is more adequate");
}
that.options.output = path.resolve(that.options.output || path.join(that.book.root, "_book"));
that.options.plugins = normalizePluginsList(that.options.plugins);
that.options.defaultsPlugins = normalizePluginsList(that.options.defaultsPlugins || "");
that.options.plugins = _.union(that.options.plugins, that.options.defaultsPlugins);
that.options.plugins = _.uniq(that.options.plugins, "name");
// Default value for text direction (from language)
if (!that.options.direction) {
var lang = i18n.getCatalog(that.options.language);
if (lang) that.options.direction = lang.direction;
}
that.options.gitbook = pkg.version;
});
};
// Extend the configuration
Configuration.prototype.extend = function(options) {
_.extend(this.options, options);
};
// Get structure file
Configuration.prototype.getStructure = function(name) {
return this.options.structure[name].split(".").slice(0, -1).join(".");
};
// Return normalized language
Configuration.prototype.normalizeLanguage = function() {
return i18n.normalizeLanguage(this.options.language);
};
// Return a configuration
Configuration.prototype.get = function(key, def) {
return _.get(this.options, key, def);
};
// Default configuration
Configuration.DEFAULT = {
// Options that can't be extend
"configFile": "book",
"generator": "website",
"extension": null,
// Book metadats (somes are extracted from the README by default)
"title": null,
"description": null,
"isbn": null,
"language": "en",
"direction": null,
"author": null,
// version of gitbook to use
"gitbook": "*",
// Structure
"structure": {
"langs": "LANGS.md",
"readme": "README.md",
"glossary": "GLOSSARY.md",
"summary": "SUMMARY.md"
},
// CSS Styles
"styles": {
"website": "styles/website.css",
"print": "styles/print.css",
"ebook": "styles/ebook.css",
"pdf": "styles/pdf.css",
"mobi": "styles/mobi.css",
"epub": "styles/epub.css"
},
// Plugins list, can contain "-name" for removing default plugins
"plugins": [],
// Global configuration for plugins
"pluginsConfig": {
"fontSettings": {
"theme": null, //"sepia", "night" or "white",
"family": "sans",// "serif" or "sans",
"size": 2 // 1 - 4
}
},
// Variables for templating
"variables": {},
// Set another theme with your own layout
// It's recommended to use plugins or add more options for default theme, though
// See https://github.com/GitbookIO/gitbook/issues/209
"theme": path.resolve(__dirname, '../theme'),
// Links in template (null: default, false: remove, string: new value)
"links": {
// Custom links at top of sidebar
"sidebar": {
//"Custom link name": "https://customlink.com"
},
// Sharing links
"sharing": {
"google": null,
"facebook": null,
"twitter": null,
"weibo": null,
"all": null
}
},
// Options for PDF generation
"pdf": {
// Add toc at the end of the file
"toc": true,
// Add page numbers to the bottom of every page
"pageNumbers": false,
// Font size for the file content
"fontSize": 12,
// Paper size for the pdf
// Choices are [ua0, ua1, ua2, ua3, ua4, ua5, ua6, ub0, ub1, ub2, ub3, ub4, ub5, ub6, ulegal, uletter]
"paperSize": "a4",
// How to mark detected chapters.
// Choices are “pagebreak”, “rule”, "both" or “none”.
"chapterMark" : "pagebreak",
// An XPath expression. Page breaks are inserted before the specified elements.
// To disable use the expression: "/"
"pageBreaksBefore": "/",
// Margin (in pts)
// Note: 72 pts equals 1 inch
"margin": {
"right": 62,
"left": 62,
"top": 56,
"bottom": 56
},
//Header HTML template. Available variables: _PAGENUM_, _TITLE_, _AUTHOR_ and _SECTION_.
"headerTemplate": "",
//Footer HTML template. Available variables: _PAGENUM_, _TITLE_, _AUTHOR_ and _SECTION_.
"footerTemplate": ""
}
};
module.exports= Configuration;
+46
View File
@@ -0,0 +1,46 @@
var jsonschema = require('jsonschema');
var schema = require('../configSchema');
describe('configSchema', function() {
function validate(cfg) {
var v = new jsonschema.Validator();
return v.validate(cfg, schema, {
propertyName: 'config'
});
}
describe('structure', function() {
it('should accept dot in filename', function() {
var result = validate({
structure: {
readme: 'book-intro.adoc'
}
});
expect(result.errors.length).toBe(0);
});
it('should accept uppercase in filename', function() {
var result = validate({
structure: {
readme: 'BOOK.adoc'
}
});
expect(result.errors.length).toBe(0);
});
it('should not accept filepath', function() {
var result = validate({
structure: {
readme: 'folder/myFile.md'
}
});
expect(result.errors.length).toBe(1);
});
});
});
+6
View File
@@ -0,0 +1,6 @@
var Immutable = require('immutable');
var jsonSchemaDefaults = require('json-schema-defaults');
var schema = require('./configSchema');
module.exports = Immutable.fromJS(jsonSchemaDefaults(schema));
+5
View File
@@ -0,0 +1,5 @@
// Configuration files to test (sorted)
module.exports = [
'book.js',
'book.json'
];
+194
View File
@@ -0,0 +1,194 @@
var FILENAME_REGEX = '^[a-zA-Z-._\d,\s]+$';
module.exports = {
'$schema': 'http://json-schema.org/schema#',
'id': 'https://gitbook.com/schemas/book.json',
'title': 'GitBook Configuration',
'type': 'object',
'properties': {
'root': {
'type': 'string',
'title': 'Path fro the root folder containing the book\'s content'
},
'title': {
'type': 'string',
'title': 'Title of the book, default is extracted from README'
},
'isbn': {
'type': 'string',
'title': 'ISBN for published book'
},
'language': {
'type': 'string',
'title': 'Language of the book'
},
'author': {
'type': 'string',
'title': 'Name of the author'
},
'gitbook': {
'type': 'string',
'default': '*',
'title': 'GitBook version to match'
},
'direction': {
'type': 'string',
'enum': ['ltr', 'rtl'],
'title': 'Direction of texts, default is detected in the pages'
},
'theme': {
'type': 'string',
'default': 'default',
'title': 'Name of the theme plugin to use'
},
'variables': {
'type': 'object',
'title': 'Templating context variables'
},
'plugins': {
'oneOf': [
{ '$ref': '#/definitions/pluginsArray' },
{ '$ref': '#/definitions/pluginsString' }
],
'default': []
},
'pluginsConfig': {
'type': 'object',
'title': 'Configuration for plugins'
},
'structure': {
'type': 'object',
'properties': {
'langs': {
'default': 'LANGS.md',
'type': 'string',
'title': 'File to use as languages index',
'pattern': FILENAME_REGEX
},
'readme': {
'default': 'README.md',
'type': 'string',
'title': 'File to use as preface',
'pattern': FILENAME_REGEX
},
'glossary': {
'default': 'GLOSSARY.md',
'type': 'string',
'title': 'File to use as glossary index',
'pattern': FILENAME_REGEX
},
'summary': {
'default': 'SUMMARY.md',
'type': 'string',
'title': 'File to use as table of contents',
'pattern': FILENAME_REGEX
}
},
'additionalProperties': false
},
'pdf': {
'type': 'object',
'title': 'PDF specific configurations',
'properties': {
'pageNumbers': {
'type': 'boolean',
'default': true,
'title': 'Add page numbers to the bottom of every page'
},
'fontSize': {
'type': 'integer',
'minimum': 8,
'maximum': 30,
'default': 12,
'title': 'Font size for the PDF output'
},
'fontFamily': {
'type': 'string',
'default': 'Arial',
'title': 'Font family for the PDF output'
},
'paperSize': {
'type': 'string',
'enum': ['a0', 'a1', 'a2', 'a3', 'a4', 'a5', 'a6', 'b0', 'b1', 'b2', 'b3', 'b4', 'b5', 'b6', 'legal', 'letter'],
'default': 'a4',
'title': 'Paper size for the PDF'
},
'chapterMark': {
'type': 'string',
'enum': ['pagebreak', 'rule', 'both', 'none'],
'default': 'pagebreak',
'title': 'How to mark detected chapters'
},
'pageBreaksBefore': {
'type': 'string',
'default': '/',
'title': 'An XPath expression. Page breaks are inserted before the specified elements. To disable use the expression: "/"'
},
'margin': {
'type': 'object',
'properties': {
'right': {
'type': 'integer',
'title': 'Right Margin',
'minimum': 0,
'maximum': 100,
'default': 62
},
'left': {
'type': 'integer',
'title': 'Left Margin',
'minimum': 0,
'maximum': 100,
'default': 62
},
'top': {
'type': 'integer',
'title': 'Top Margin',
'minimum': 0,
'maximum': 100,
'default': 56
},
'bottom': {
'type': 'integer',
'title': 'Bottom Margin',
'minimum': 0,
'maximum': 100,
'default': 56
}
}
}
}
}
},
'required': [],
'definitions': {
'pluginsArray': {
'type': 'array',
'items': {
'oneOf': [
{ '$ref': '#/definitions/pluginObject' },
{ '$ref': '#/definitions/pluginString' }
]
}
},
'pluginsString': {
'type': 'string'
},
'pluginString': {
'type': 'string'
},
'pluginObject': {
'type': 'object',
'properties': {
'name': {
'type': 'string'
},
'version': {
'type': 'string'
}
},
'additionalProperties': false,
'required': ['name']
}
}
};
+51
View File
@@ -0,0 +1,51 @@
var Immutable = require('immutable');
var TemplateBlock = require('../models/templateBlock');
module.exports = Immutable.Map({
html: TemplateBlock({
name: 'html',
process: function(blk) {
return blk;
}
}),
code: TemplateBlock({
name: 'code',
process: function(blk) {
return {
html: false,
body: blk.body
};
}
}),
markdown: TemplateBlock({
name: 'markdown',
process: function(blk) {
return this.book.renderInline('markdown', blk.body)
.then(function(out) {
return { body: out };
});
}
}),
asciidoc: TemplateBlock({
name: 'asciidoc',
process: function(blk) {
return this.book.renderInline('asciidoc', blk.body)
.then(function(out) {
return { body: out };
});
}
}),
markup: TemplateBlock({
name: 'markup',
process: function(blk) {
return this.book.renderInline(this.ctx.file.type, blk.body)
.then(function(out) {
return { body: out };
});
}
})
});
+15
View File
@@ -0,0 +1,15 @@
var Immutable = require('immutable');
var moment = require('moment');
module.exports = Immutable.Map({
// Format a date
// ex: 'MMMM Do YYYY, h:mm:ss a
date: function(time, format) {
return moment(time).format(format);
},
// Relative Time
dateFromNow: function(time) {
return moment(time).fromNow();
}
});
+29
View File
@@ -0,0 +1,29 @@
var Immutable = require('immutable');
var PluginDependency = require('../models/pluginDependency');
var pkg = require('../../package.json');
/**
* Create a PluginDependency from a dependency of gitbook
* @param {String} pluginName
* @return {PluginDependency}
*/
function createFromDependency(pluginName) {
var npmID = PluginDependency.nameToNpmID(pluginName);
var version = pkg.dependencies[npmID];
return PluginDependency.create(pluginName, version);
}
/*
* List of default plugins for all books,
* default plugins should be installed in node dependencies of GitBook
*/
module.exports = Immutable.List([
'highlight',
'search',
'lunr',
'sharing',
'fontsettings',
'theme-default'
]).map(createFromDependency);
+4
View File
@@ -0,0 +1,4 @@
module.exports = [
'.adoc',
'.asciidoc'
];
+5
View File
@@ -0,0 +1,5 @@
module.exports = [
'.md',
'.markdown',
'.mdown'
];
+6
View File
@@ -0,0 +1,6 @@
// Files containing ignore pattner (sorted by priority)
module.exports = [
'.ignore',
'.gitignore',
'.bookignore'
];
+2
View File
@@ -0,0 +1,2 @@
module.exports = '_assets';
+8
View File
@@ -0,0 +1,8 @@
module.exports = [
'init',
'finish',
'finish:before',
'config',
'page',
'page:before'
];
+5
View File
@@ -0,0 +1,5 @@
/*
All GitBook plugins are NPM packages starting with this prefix.
*/
module.exports = 'gitbook-plugin-';
+6
View File
@@ -0,0 +1,6 @@
var Immutable = require('immutable');
module.exports = Immutable.List([
'js',
'css'
]);
+2
View File
@@ -0,0 +1,2 @@
module.exports = '_layouts';
+4
View File
@@ -0,0 +1,4 @@
/*
All GitBook themes plugins name start with this prefix once shorted.
*/
module.exports = 'theme-';
+82
View File
@@ -0,0 +1,82 @@
var createMockFS = require('../mock');
describe('MockFS', function() {
var fs = createMockFS({
'README.md': 'Hello World',
'SUMMARY.md': '# Summary',
'folder': {
'test.md': 'Cool',
'folder2': {
'hello.md': 'Hello',
'world.md': 'World'
}
}
});
describe('exists', function() {
it('must return true for a file', function() {
return fs.exists('README.md')
.then(function(result) {
expect(result).toBeTruthy();
});
});
it('must return false for a non existing file', function() {
return fs.exists('README_NOTEXISTS.md')
.then(function(result) {
expect(result).toBeFalsy();
});
});
it('must return true for a directory', function() {
return fs.exists('folder')
.then(function(result) {
expect(result).toBeTruthy();
});
});
it('must return true for a deep file', function() {
return fs.exists('folder/test.md')
.then(function(result) {
expect(result).toBeTruthy();
});
});
it('must return true for a deep file (2)', function() {
return fs.exists('folder/folder2/hello.md')
.then(function(result) {
expect(result).toBeTruthy();
});
});
});
describe('readAsString', function() {
it('must return content for a file', function() {
return fs.readAsString('README.md')
.then(function(result) {
expect(result).toBe('Hello World');
});
});
it('must return content for a deep file', function() {
return fs.readAsString('folder/test.md')
.then(function(result) {
expect(result).toBe('Cool');
});
});
});
describe('readDir', function() {
it('must return content for a directory', function() {
return fs.readDir('./')
.then(function(files) {
expect(files.size).toBe(3);
expect(files.includes('README.md')).toBeTruthy();
expect(files.includes('SUMMARY.md')).toBeTruthy();
expect(files.includes('folder/')).toBeTruthy();
});
});
});
});
+95
View File
@@ -0,0 +1,95 @@
var path = require('path');
var is = require('is');
var Buffer = require('buffer').Buffer;
var Immutable = require('immutable');
var FS = require('../models/fs');
var error = require('../utils/error');
/**
Create a fake filesystem for unit testing GitBook.
@param {Map<String:String|Map>}
*/
function createMockFS(files) {
files = Immutable.fromJS(files);
var mtime = new Date();
function getFile(filePath) {
var parts = path.normalize(filePath).split(path.sep);
return parts.reduce(function(list, part, i) {
if (!list) return null;
var file;
if (!part || part === '.') file = list;
else file = list.get(part);
if (!file) return null;
if (is.string(file)) {
if (i === (parts.length - 1)) return file;
else return null;
}
return file;
}, files);
}
function fsExists(filePath) {
return Boolean(getFile(filePath) !== null);
}
function fsReadFile(filePath) {
var file = getFile(filePath);
if (!is.string(file)) {
throw error.FileNotFoundError({
filename: filePath
});
}
return new Buffer(file, 'utf8');
}
function fsStatFile(filePath) {
var file = getFile(filePath);
if (!file) {
throw error.FileNotFoundError({
filename: filePath
});
}
return {
mtime: mtime
};
}
function fsReadDir(filePath) {
var dir = getFile(filePath);
if (!dir || is.string(dir)) {
throw error.FileNotFoundError({
filename: filePath
});
}
return dir
.map(function(content, name) {
if (!is.string(content)) {
name = name + '/';
}
return name;
})
.valueSeq();
}
return FS.create({
root: '',
fsExists: fsExists,
fsReadFile: fsReadFile,
fsStatFile: fsStatFile,
fsReadDir: fsReadDir
});
}
module.exports = createMockFS;
+42
View File
@@ -0,0 +1,42 @@
var path = require('path');
var Immutable = require('immutable');
var fresh = require('fresh-require');
var fs = require('../utils/fs');
var FS = require('../models/fs');
function fsReadDir(folder) {
return fs.readdir(folder)
.then(function(files) {
files = Immutable.List(files);
return files
.map(function(file) {
if (file == '.' || file == '..') return;
var stat = fs.statSync(path.join(folder, file));
if (stat.isDirectory()) file = file + path.sep;
return file;
})
.filter(function(file) {
return Boolean(file);
});
});
}
function fsLoadObject(filename) {
return fresh(filename, require);
}
module.exports = function createNodeFS(root) {
return FS.create({
root: root,
fsExists: fs.exists,
fsReadFile: fs.readFile,
fsStatFile: fs.stat,
fsReadDir: fsReadDir,
fsLoadObject: fsLoadObject,
fsReadAsStream: fs.readStream
});
};
-78
View File
@@ -1,78 +0,0 @@
var _ = require("lodash");
var path = require("path");
var Q = require("q");
var fs = require("./utils/fs");
var Plugin = require("./plugin");
var BaseGenerator = function(book) {
this.book = book;
Object.defineProperty(this, "options", {
get: function () {
return this.book.options;
}
});
_.bindAll(this);
};
BaseGenerator.prototype.callHook = function(name, data) {
return this.book.plugins.hook(name, data);
};
// Prepare the genertor
BaseGenerator.prototype.prepare = function() {
var that = this;
return that.callHook("init");
};
// Write a parsed file to the output
BaseGenerator.prototype.convertFile = function(input) {
return Q.reject(new Error("Could not convert "+input));
};
// Copy file to the output (non parsable)
BaseGenerator.prototype.transferFile = function(input) {
return fs.copy(
path.join(this.book.root, input),
path.join(this.options.output, input)
);
};
// Copy a folder to the output
BaseGenerator.prototype.transferFolder = function(input) {
return fs.mkdirp(
path.join(this.book.options.output, input)
);
};
// Copy the cover picture
BaseGenerator.prototype.copyCover = function() {
var that = this;
return Q.all([
fs.copy(path.join(that.book.root, "cover.jpg"), path.join(that.options.output, "cover.jpg")),
fs.copy(path.join(that.book.root, "cover_small.jpg"), path.join(that.options.output, "cover_small.jpg"))
])
.fail(function() {
// If orignaly from multi-lang, try copy from parent
if (!that.book.isSubBook()) return;
return Q.all([
fs.copy(path.join(that.book.parentRoot(), "cover.jpg"), path.join(that.options.output, "cover.jpg")),
fs.copy(path.join(that.book.parentRoot(), "cover_small.jpg"), path.join(that.options.output, "cover_small.jpg"))
]);
})
.fail(function(err) {
return Q();
});
};
// At teh end of the generation
BaseGenerator.prototype.finish = function() {
return Q.reject(new Error("Could not finish generation"));
};
module.exports = BaseGenerator;
-139
View File
@@ -1,139 +0,0 @@
var util = require("util");
var path = require("path");
var Q = require("q");
var _ = require("lodash");
var exec = require('child_process').exec;
var fs = require("../utils/fs");
var stringUtils = require("../utils/string");
var BaseGenerator = require("./website");
var Generator = function(book, format) {
BaseGenerator.apply(this, arguments);
// eBook format
this.ebookFormat = format;
// Resources namespace
this.namespace = "ebook";
// Styles to use
this.styles = _.compact(["print", "ebook", this.ebookFormat]);
// Convert images (svg -> png)
this.convertImages = true;
};
util.inherits(Generator, BaseGenerator);
Generator.prototype.prepareTemplates = function() {
this.templates["page"] = this.book.plugins.template("ebook:page") || path.resolve(this.options.theme, 'templates/ebook/page.html');
this.templates["summary"] = this.book.plugins.template("ebook:summary") || path.resolve(this.options.theme, 'templates/ebook/summary.html');
this.templates["glossary"] = this.book.plugins.template("ebook:glossary") || path.resolve(this.options.theme, 'templates/ebook/glossary.html');
return Q();
};
// Generate table of contents
Generator.prototype.writeSummary = function() {
var that = this;
that.book.log.info.ln("write SUMMARY.html");
return this._writeTemplate(this.templates["summary"], {}, path.join(this.options.output, "SUMMARY.html"));
};
Generator.prototype.finish = function() {
var that = this;
return Q()
.then(this.copyAssets)
.then(this.copyCover)
.then(this.writeGlossary)
.then(this.writeSummary)
.then(function() {
if (!that.ebookFormat) return Q();
var d = Q.defer();
if (!that.options.cover && fs.existsSync(path.join(that.options.output, "cover.jpg"))) {
that.options.cover = path.join(that.options.output, "cover.jpg");
}
var _options = {
"--cover": that.options.cover,
"--title": that.options.title,
"--comments": that.options.description,
"--isbn": that.options.isbn,
"--authors": that.options.author,
"--language": that.options.language,
"--book-producer": "GitBook",
"--publisher": "GitBook",
"--chapter": "descendant-or-self::*[contains(concat(' ', normalize-space(@class), ' '), ' book-chapter ')]",
"--level1-toc": "descendant-or-self::*[contains(concat(' ', normalize-space(@class), ' '), ' book-chapter-1 ')]",
"--level2-toc": "descendant-or-self::*[contains(concat(' ', normalize-space(@class), ' '), ' book-chapter-2 ')]",
"--level3-toc": "descendant-or-self::*[contains(concat(' ', normalize-space(@class), ' '), ' book-chapter-3 ')]",
"--no-chapters-in-toc": true,
"--max-levels": "1",
"--breadth-first": true
};
if (that.ebookFormat == "pdf") {
var pdfOptions = that.options.pdf;
_.extend(_options, {
"--chapter-mark": String(pdfOptions.chapterMark),
"--page-breaks-before": String(pdfOptions.pageBreaksBefore),
"--margin-left": String(pdfOptions.margin.left),
"--margin-right": String(pdfOptions.margin.right),
"--margin-top": String(pdfOptions.margin.top),
"--margin-bottom": String(pdfOptions.margin.bottom),
"--pdf-default-font-size": String(pdfOptions.fontSize),
"--pdf-mono-font-size": String(pdfOptions.fontSize),
"--paper-size": String(pdfOptions.paperSize),
"--pdf-page-numbers": Boolean(pdfOptions.pageNumbers),
"--pdf-header-template": String(pdfOptions.headerTemplate) || "<p class='header'><span>"+that.options.title+"</span></p>",
"--pdf-footer-template": String(pdfOptions.footerTemplate) || "<p class='footer'><span>_SECTION_</span> <span style='float:right;'>_PAGENUM_</span></p>"
});
} else if (that.ebookFormat == "epub") {
_.extend(_options, {
"--dont-split-on-page-breaks": true
});
}
var command = [
"ebook-convert",
path.join(that.options.output, "SUMMARY.html"),
path.join(that.options.output, "index."+that.ebookFormat),
stringUtils.optionsToShellArgs(_options)
].join(" ");
that.book.log.info("start conversion to", that.ebookFormat, "....");
var child = exec(command, function (error, stdout, stderr) {
if (error) {
that.book.log.info.fail();
if (error.code == 127) {
error.message = "Need to install ebook-convert from Calibre";
} else {
error.message = error.message + " "+stdout;
}
return d.reject(error);
}
that.book.log.info.ok();
d.resolve();
});
child.stdout.on('data', function (data) {
that.book.log.debug(data);
});
child.stderr.on('data', function (data) {
that.book.log.debug(data);
});
return d.promise;
});
};
module.exports = Generator;
-11
View File
@@ -1,11 +0,0 @@
var _ = require("lodash");
var EbookGenerator = require("./ebook");
module.exports = {
json: require("./json"),
website: require("./website"),
ebook: EbookGenerator,
pdf: _.partialRight(EbookGenerator, "pdf"),
mobi: _.partialRight(EbookGenerator, "mobi"),
epub: _.partialRight(EbookGenerator, "epub")
};
-76
View File
@@ -1,76 +0,0 @@
var util = require("util");
var path = require("path");
var Q = require("q");
var _ = require("lodash");
var fs = require("../utils/fs");
var BaseGenerator = require("../generator");
var links = require("../utils/links");
var Generator = function() {
BaseGenerator.apply(this, arguments);
};
util.inherits(Generator, BaseGenerator);
// Ignore some methods
Generator.prototype.transferFile = function(input) { };
// Convert an input file
Generator.prototype.convertFile = function(input) {
var that = this;
return that.book.parsePage(input)
.then(function(page) {
var json = {
progress: page.progress,
sections: page.sections
};
var output = links.changeExtension(page.path, ".json");
output = path.join(that.options.output, output);
return fs.writeFile(
output,
JSON.stringify(json, null, 4)
);
});
};
// Finish generation
Generator.prototype.finish = function() {
return this.writeReadme();
};
// Write README.json
Generator.prototype.writeReadme = function() {
var that = this;
var mainlang, langs;
return Q()
.then(function() {
langs = that.book.langs;
mainLang = langs.length > 0? _.first(langs).lang : null;
readme = links.changeExtension(that.book.readmeFile, ".json");
// Read readme from main language
return fs.readFile(
mainLang? path.join(that.options.output, mainLang, readme) : path.join(that.options.output, readme)
);
})
.then(function(content) {
// Extend it with infos about the languages
var json = JSON.parse(content);
_.extend(json, {
langs: langs
});
// Write it as README.json
return fs.writeFile(
path.join(that.options.output, "README.json"),
JSON.stringify(json, null, 4)
);
});
};
module.exports = Generator;
-276
View File
@@ -1,276 +0,0 @@
var util = require("util");
var path = require("path");
var Q = require("q");
var _ = require("lodash");
var nunjucks = require("nunjucks");
var AutoEscapeExtension = require("nunjucks-autoescape")(nunjucks);
var FilterExtension = require("nunjucks-filter")(nunjucks);
var fs = require("../utils/fs");
var BaseGenerator = require("../generator");
var links = require("../utils/links");
var pageUtil = require("../utils/page");
var i18n = require("../utils/i18n");
var pkg = require("../../package.json");
var Generator = function() {
BaseGenerator.apply(this, arguments);
// Revision
this.revision = new Date();
// Resources namespace
this.namespace = "website";
// Style to integrates in the output
this.styles = ["website"];
// Convert images (svg -> png)
this.convertImages = false;
// Templates
this.templates = {};
};
util.inherits(Generator, BaseGenerator);
// Prepare the genertor
Generator.prototype.prepare = function() {
return BaseGenerator.prototype.prepare.apply(this)
.then(this.prepareStyles)
.then(this.prepareTemplates)
.then(this.prepareTemplateEngine);
};
// Prepare all styles
Generator.prototype.prepareStyles = function() {
var that = this;
this.styles = _.chain(this.styles)
.map(function(style) {
var stylePath = that.options.styles[style];
if (stylePath && fs.existsSync(path.resolve(that.book.root, stylePath))) {
return [style, stylePath];
}
return null;
})
.compact()
.object()
.value();
return Q();
};
// Prepare templates
Generator.prototype.prepareTemplates = function() {
this.templates["page"] = this.book.plugins.template("site:page") || path.resolve(this.options.theme, 'templates/website/page.html');
this.templates["langs"] = this.book.plugins.template("site:langs") || path.resolve(this.options.theme, 'templates/website/langs.html');
this.templates["glossary"] = this.book.plugins.template("site:glossary") || path.resolve(this.options.theme, 'templates/website/glossary.html');
return Q();
};
// Prepare template engine
Generator.prototype.prepareTemplateEngine = function() {
var that = this;
return Q()
.then(function() {
var language = that.book.config.normalizeLanguage();
if (!i18n.hasLocale(language)) {
that.book.log.warn.ln("Language '"+language+"' is not available as a layout locales (en, "+i18n.getLocales().join(", ")+")");
}
var folders = _.chain(that.templates)
.values()
.map(path.dirname)
.uniq()
.value();
that.env = new nunjucks.Environment(
new nunjucks.FileSystemLoader(folders),
{
autoescape: true
}
);
// Add filter
that.env.addFilter("contentLink", that.book.contentLink.bind(that.book));
that.env.addFilter('lvl', function(lvl) {
return lvl.split(".").length;
});
// Add extension
that.env.addExtension('AutoEscapeExtension', new AutoEscapeExtension(that.env));
that.env.addExtension('FilterExtension', new FilterExtension(that.env));
});
};
// Finis generation
Generator.prototype.finish = function() {
return this.copyAssets()
.then(this.copyCover)
.then(this.writeGlossary)
.then(this.writeSearchIndex)
.then(this.writeLangsIndex)
};
// Convert an input file
Generator.prototype.convertFile = function(input) {
var that = this;
return that.book.parsePage(input, {
convertImages: that.convertImages,
interpolateTemplate: function(page) {
return that.callHook("page:before", page);
},
interpolateContent: function(page) {
return that.callHook("page", page);
}
})
.then(function(page) {
var relativeOutput = that.book.contentPath(page.path);
var output = path.join(that.options.output, relativeOutput);
var basePath = path.relative(path.dirname(output), that.options.output) || ".";
if (process.platform === 'win32') basePath = basePath.replace(/\\/g, '/');
that.book.log.debug.ln("write parsed file", page.path, "to", relativeOutput);
return that._writeTemplate(that.templates["page"], {
progress: page.progress,
_input: page.path,
content: page.sections,
basePath: basePath,
staticBase: links.join(basePath, "gitbook")
}, output);
});
};
// Write the index for langs
Generator.prototype.writeLangsIndex = function() {
var that = this;
if (!this.book.langs.length) return Q();
return this._writeTemplate(this.templates["langs"], {
langs: this.book.langs
}, path.join(this.options.output, "index.html"));
};
// Write glossary
Generator.prototype.writeGlossary = function() {
var that = this;
// No glossary
if (this.book.glossary.length == 0) return Q();
return this._writeTemplate(this.templates["glossary"], {}, path.join(this.options.output, "GLOSSARY.html"));
};
// Write the search index
Generator.prototype.writeSearchIndex = function() {
var that = this;
return fs.writeFile(
path.join(this.options.output, "search_index.json"),
JSON.stringify(this.book.searchIndex)
);
};
// Convert a page into a normalized data set
Generator.prototype.normalizePage = function(page) {
var that = this;
var _callHook = function(name) {
return that.callHook(name, page)
.then(function(_page) {
page = _page;
return page;
});
};
return Q()
.then(function() {
return _callHook("page");
})
.then(function() {
return page;
});
};
// Generate a template
Generator.prototype._writeTemplate = function(tpl, options, output, interpolate) {
var that = this;
interpolate = interpolate || _.identity;
return Q()
.then(function(sections) {
return that.env.render(
tpl,
_.extend({
gitbook: {
version: pkg.version
},
styles: that.styles,
revision: that.revision,
title: that.options.title,
description: that.options.description,
language: that.book.config.normalizeLanguage(),
glossary: that.book.glossary,
summary: that.book.summary,
allNavigation: that.book.navigation,
plugins: {
resources: that.book.plugins.resources(that.namespace)
},
pluginsConfig: JSON.stringify(that.options.pluginsConfig),
htmlSnippet: _.partial(_.partialRight(that.book.plugins.html, that, options), that.namespace),
options: that.options,
basePath: ".",
staticBase: path.join(".", "gitbook"),
'__': that.book.i18n.bind(that.book)
}, options)
);
})
.then(interpolate)
.then(function(html) {
return fs.writeFile(
output,
html
);
});
};
// Copy assets
Generator.prototype.copyAssets = function() {
var that = this;
// Copy gitbook assets
return fs.copy(
path.join(that.options.theme, "assets"),
path.join(that.options.output, "gitbook")
)
// Copy plugins assets
.then(function() {
return Q.all(
_.map(that.book.plugins.list, function(plugin) {
var pluginAssets = path.join(that.options.output, "gitbook/plugins/", plugin.name);
return plugin.copyAssets(pluginAssets, that.namespace);
})
);
});
};
module.exports = Generator;
+28
View File
@@ -0,0 +1,28 @@
var semver = require('semver');
var pkg = require('../package.json');
var VERSION = pkg.version;
var VERSION_STABLE = VERSION.replace(/\-(\S+)/g, '');
var START_TIME = new Date();
/**
Verify that this gitbook version satisfies a requirement
We can't directly use samver.satisfies since it will break all plugins when gitbook version is a prerelease (beta, alpha)
@param {String} condition
@return {Boolean}
*/
function satisfies(condition) {
// Test with real version
if (semver.satisfies(VERSION, condition)) return true;
// Test with future stable release
return semver.satisfies(VERSION_STABLE, condition);
}
module.exports = {
version: pkg.version,
satisfies: satisfies,
START_TIME: START_TIME
};
+8 -208
View File
@@ -1,210 +1,10 @@
var Q = require("q");
var _ = require("lodash");
var path = require("path");
var tinylr = require('tiny-lr');
var color = require('bash-color');
var extend = require('extend');
var Book = require("./book");
var Plugin = require("./plugin");
var Server = require("./utils/server");
var stringUtils = require("./utils/string");
var watch = require("./utils/watch");
var logger = require("./utils/logger");
var common = require('./browser');
var LOG_OPTION = {
name: "log",
description: "Minimum log level to display",
values: _.chain(logger.LEVELS).keys().map(stringUtils.toLowerCase).value(),
defaults: "info"
};
var FORMAT_OPTION = {
name: "format",
description: "Format to build to",
values: ["website", "json", "ebook"],
defaults: "website"
};
module.exports = {
Book: Book,
LOG_LEVELS: logger.LEVELS,
commands: _.flatten([
{
name: "build [book] [output]",
description: "build a book",
options: [
FORMAT_OPTION,
LOG_OPTION
],
exec: function(args, kwargs) {
var input = args[0] || process.cwd();
var output = args[1] || path.join(input, "_book");
var book = new Book(input, _.extend({}, {
'config': {
'output': output
},
'logLevel': kwargs.log
}));
return book.parse()
.then(function() {
return book.generate(kwargs.format);
})
.then(function(){
console.log("");
console.log(color.green("Done, without error"));
});
}
},
_.map(["pdf", "epub", "mobi"], function(ebookType) {
return {
name: ebookType+" [book] [output]",
description: "build a book to "+ebookType,
options: [
LOG_OPTION
],
exec: function(args, kwargs) {
var input = args[0] || process.cwd();
var output = args[1];
var book = new Book(input, _.extend({}, {
'logLevel': kwargs.log
}));
return book.parse()
.then(function() {
return book.generateFile(output, {
ebookFormat: ebookType
});
})
.then(function(){
console.log("");
console.log(color.green("Done, without error"));
});
}
};
}),
{
name: "serve [book]",
description: "Build then serve a gitbook from a directory",
options: [
{
name: "port",
description: "Port for server to listen on",
defaults: 4000
},
{
name: "lrport",
description: "Port for livereload server to listen on",
defaults: 35729
},
{
name: "watch",
description: "Enable/disable file watcher",
defaults: true
},
FORMAT_OPTION,
LOG_OPTION
],
exec: function(args, kwargs) {
var input = args[0] || process.cwd();
var server = new Server();
// Init livereload server
var lrServer = tinylr({});
var lrPath = undefined;
var generate = function() {
if (server.isRunning()) console.log("Stopping server");
return server.stop()
.then(function() {
var book = new Book(input, _.extend({}, {
'config': {
'defaultsPlugins': ["livereload"]
},
'logLevel': kwargs.log
}));
return book.parse()
.then(function() {
return book.generate(kwargs.format);
})
.thenResolve(book);
})
.then(function(book) {
console.log();
console.log('Starting server ...');
return server.start(book.options.output, kwargs.port)
.then(function() {
console.log('Serving book on http://localhost:'+kwargs.port);
if (lrPath) {
// trigger livereload
lrServer.changed({
body: {
files: [lrPath]
}
});
}
if (!kwargs.watch) return;
return watch(book.root)
.then(function(filepath) {
// set livereload path
lrPath = filepath;
console.log("Restart after change in file", filepath);
console.log('');
return generate();
})
})
});
};
return Q.nfcall(lrServer.listen.bind(lrServer), kwargs.lrport)
.then(function() {
console.log('Live reload server started on port:', kwargs.lrport);
console.log('Press CTRL+C to quit ...');
console.log('')
return generate();
});
}
},
{
name: "install [book]",
description: "install plugins dependencies",
exec: function(args, kwargs) {
var input = args[0] || process.cwd();
var book = new Book(input);
return book.config.load()
.then(function() {
return book.plugins.install();
})
.then(function(){
console.log("");
console.log(color.green("Done, without error"));
});
}
},
{
name: "init [directory]",
description: "create files and folders based on contents of SUMMARY.md",
exec: function(args, kwargs) {
return Book.init(args[0] || process.cwd())
.then(function(){
console.log("");
console.log(color.green("Done, without error"));
});
}
}
])
};
module.exports = extend({
initBook: require('./init'),
createNodeFS: require('./fs/node'),
Output: require('./output'),
commands: require('./cli')
}, common);
+83
View File
@@ -0,0 +1,83 @@
var path = require('path');
var createNodeFS = require('./fs/node');
var fs = require('./utils/fs');
var Promise = require('./utils/promise');
var File = require('./models/file');
var Readme = require('./models/readme');
var Book = require('./models/book');
var Parse = require('./parse');
/**
Initialize folder structure for a book
Read SUMMARY to created the right chapter
@param {Book}
@param {String}
@return {Promise}
*/
function initBook(rootFolder) {
var extension = '.md';
return fs.mkdirp(rootFolder)
// Parse the summary and readme
.then(function() {
var fs = createNodeFS(rootFolder);
var book = Book.createForFS(fs);
return Parse.parseReadme(book)
// Setup default readme if doesn't found one
.fail(function() {
var readmeFile = File.createWithFilepath('README' + extension);
var readme = Readme.create(readmeFile);
return book.setReadme(readme);
});
})
.then(Parse.parseSummary)
.then(function(book) {
var logger = book.getLogger();
var summary = book.getSummary();
var summaryFile = summary.getFile();
var summaryFilename = summaryFile.getPath() || ('SUMMARY' + extension);
var articles = summary.getArticlesAsList();
// Write pages
return Promise.forEach(articles, function(article) {
var articlePath = article.getPath();
var filePath = articlePath? path.join(rootFolder, articlePath) : null;
if (!filePath) {
return;
}
return fs.assertFile(filePath, function() {
return fs.ensureFile(filePath)
.then(function() {
logger.info.ln('create', article.getPath());
return fs.writeFile(filePath, '# ' + article.getTitle() + '\n\n');
});
});
})
// Write summary
.then(function() {
var filePath = path.join(rootFolder, summaryFilename);
return fs.ensureFile(filePath)
.then(function() {
logger.info.ln('create ' + path.basename(filePath));
return fs.writeFile(filePath, summary.toText(extension));
});
})
// Log end
.then(function() {
logger.info.ln('initialization is finished');
});
});
}
module.exports = initBook;
+39
View File
@@ -0,0 +1,39 @@
var extend = require('extend');
var gitbook = require('../gitbook');
var encodeSummary = require('./encodeSummary');
var encodeGlossary = require('./encodeGlossary');
var encodeReadme = require('./encodeReadme');
var encodeLanguages = require('./encodeLanguages');
/**
Encode a book to JSON
@param {Book}
@return {Object}
*/
function encodeBookToJson(book) {
var config = book.getConfig();
var language = book.getLanguage();
var variables = config.getValue('variables', {});
return {
summary: encodeSummary(book.getSummary()),
glossary: encodeGlossary(book.getGlossary()),
readme: encodeReadme(book.getReadme()),
config: book.getConfig().getValues().toJS(),
languages: book.isMultilingual()? encodeLanguages(book.getLanguages()) : undefined,
gitbook: {
version: gitbook.version,
time: gitbook.START_TIME
},
book: extend({
language: language? language : undefined
}, variables.toJS())
};
}
module.exports = encodeBookToJson;
+22
View File
@@ -0,0 +1,22 @@
var encodeBook = require('./encodeBook');
var encodePage = require('./encodePage');
var encodeFile = require('./encodeFile');
/**
* Return a JSON representation of a book with a specific file
*
* @param {Book} output
* @param {Page} page
* @return {Object}
*/
function encodeBookWithPage(book, page) {
var file = page.getFile();
var result = encodeBook(book);
result.page = encodePage(page, book.getSummary());
result.file = encodeFile(file);
return result;
}
module.exports = encodeBookWithPage;
+21
View File
@@ -0,0 +1,21 @@
/**
Return a JSON representation of a file
@param {File} file
@return {Object}
*/
function encodeFileToJson(file) {
var filePath = file.getPath();
if (!filePath) {
return undefined;
}
return {
path: filePath,
mtime: file.getMTime(),
type: file.getType()
};
}
module.exports = encodeFileToJson;
+21
View File
@@ -0,0 +1,21 @@
var encodeFile = require('./encodeFile');
var encodeGlossaryEntry = require('./encodeGlossaryEntry');
/**
Encode a glossary to JSON
@param {Glossary}
@return {Object}
*/
function encodeGlossary(glossary) {
var file = glossary.getFile();
var entries = glossary.getEntries();
return {
file: encodeFile(file),
entries: entries
.map(encodeGlossaryEntry).toJS()
};
}
module.exports = encodeGlossary;

Some files were not shown because too many files have changed in this diff Show More