├── .gitignore
├── README.md
├── assets
├── codetabs.css
└── codetabs.js
├── index.js
├── package.json
└── preview.png
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 |
5 | # Runtime data
6 | pids
7 | *.pid
8 | *.seed
9 |
10 | # Directory for instrumented libs generated by jscoverage/JSCover
11 | lib-cov
12 |
13 | # Coverage directory used by tools like istanbul
14 | coverage
15 |
16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
17 | .grunt
18 |
19 | # Compiled binary addons (http://nodejs.org/api/addons.html)
20 | build/Release
21 |
22 | # Dependency directory
23 | # Deployed apps should consider commenting this line out:
24 | # see https://npmjs.org/doc/faq.html#Should-I-check-my-node_modules-folder-into-git
25 | node_modules
26 |
27 | # vim swapfile
28 | *.swp
29 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # codetabs
2 |
3 | Include multiple languages code block to your GitBook (for example when documenting an API).
4 |
5 | 
6 |
7 | ### Installation
8 |
9 | Adds the plugin to your `book.json`, then run `gitbook install` if you are building your book locally.
10 |
11 | ```js
12 | {
13 | "plugins": ["codetabs"]
14 | }
15 | ```
16 |
17 | ### Usage
18 |
19 | ```md
20 |
21 | This is a code block with tabs for each languages:
22 |
23 | {% codetabs name="Python", type="py" -%}
24 | msg = "Hello World"
25 | print msg
26 | {%- language name="JavaScript", type="js" -%}
27 | var msg = "Hello World";
28 | console.log(msg);
29 | {%- language name="HTML", type="html" -%}
30 | Hello World
31 | {%- endcodetabs %}
32 | ```
33 |
34 | ### Escaping templating syntax
35 |
36 | For languages using syntax like `{{`, `{%`; we have to escape these content:
37 |
38 |
39 | ```md
40 | Here is some angular and react code
41 |
42 | {% codetabs name="Python", type="py" -%}
43 | {% raw %}
44 |
Hello {{yourName}}!
45 | {% endraw %}
46 | {%- language name="React", type="js" -%}
47 | var React = require('react')
48 | {%- endcodetabs %}
49 | ```
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/assets/codetabs.css:
--------------------------------------------------------------------------------
1 | .codetabs {
2 |
3 | }
4 |
5 | .codetabs .codetabs-header .tab {
6 | display: inline-block;
7 | padding: 3px 6px;
8 | border-bottom: 2px solid transparent;
9 | cursor: pointer;
10 | opacity: 0.7;
11 | }
12 |
13 | .codetabs .codetabs-header .tab.active {
14 | border-bottom-color: #428bca;
15 | cursor: default;
16 | opacity: 1;
17 | }
18 |
19 | .codetabs .codetabs-body .tab {
20 | display: none;
21 | }
22 |
23 | .codetabs .codetabs-body .tab.active {
24 | display: block;
25 | }
26 |
27 |
--------------------------------------------------------------------------------
/assets/codetabs.js:
--------------------------------------------------------------------------------
1 | require([
2 | 'jquery'
3 | ], function($) {
4 | $(document).on('click.plugin.codetabs', '.codetabs .codetabs-header .tab', function(e) {
5 | var $btn = $(e.target);
6 | var $tabs = $btn.parents('.codetabs');
7 | var tabId = $btn.data('codetab');
8 |
9 | $tabs.find('.tab').removeClass('active');
10 | $tabs.find('.tab[data-codetab="' + tabId + '"]').addClass('active');
11 | });
12 | });
13 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | var escape = require('escape-html');
2 |
3 | /*
4 | Generate HTML for the tab in the header
5 |
6 | @param {Block}
7 | @param {Boolean}
8 | @return {String}
9 | */
10 | function createTab(block, i, isActive) {
11 | return '' + block.kwargs.name + '
';
12 | }
13 |
14 | /*
15 | Generate HTML for the tab's content
16 |
17 | @param {Block}
18 | @param {Boolean}
19 | @return {String}
20 | */
21 | function createTabBody(block, i, isActive) {
22 | return ''
23 | + escape(block.body) +
24 | '
';
25 | }
26 |
27 | module.exports = {
28 | book: {
29 | assets: './assets',
30 | css: [
31 | 'codetabs.css'
32 | ],
33 | js: [
34 | 'codetabs.js'
35 | ]
36 | },
37 |
38 | blocks: {
39 | codetabs: {
40 | blocks: ['language'],
41 | process: function(parentBlock) {
42 | var blocks = [parentBlock].concat(parentBlock.blocks);
43 | var tabsContent = '';
44 | var tabsHeader = '';
45 |
46 | blocks.forEach(function(block, i) {
47 | var isActive = (i == 0);
48 |
49 | if (!block.kwargs.name) {
50 | throw new Error('Code tab requires a "name" property');
51 | }
52 |
53 | tabsHeader += createTab(block, i, isActive);
54 | tabsContent += createTabBody(block, i, isActive);
55 | });
56 |
57 |
58 | return '' +
59 | '' +
60 | '
' + tabsContent + '
' +
61 | '
';
62 | }
63 | }
64 | }
65 | };
66 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "gitbook-plugin-codetabs",
3 | "version": "1.0.0",
4 | "description": "Multiple languages code blocks for GitBook",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "repository": {
10 | "type": "git",
11 | "url": "git+https://github.com/GitbookIO/plugin-codetabs.git"
12 | },
13 | "keywords": [
14 | "gitbook",
15 | "code"
16 | ],
17 | "engines": {
18 | "gitbook": ">=3.0.0-pre.8"
19 | },
20 | "author": "Samy Pesse ",
21 | "license": "Apache-2.0",
22 | "bugs": {
23 | "url": "https://github.com/GitbookIO/plugin-codetabs/issues"
24 | },
25 | "homepage": "https://github.com/GitbookIO/plugin-codetabs#readme",
26 | "dependencies": {
27 | "escape-html": "^1.0.3"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GitbookIO/plugin-codetabs/26f344ca078093cca599a6e5271b99b82ddb6211/preview.png
--------------------------------------------------------------------------------