Skip to content

Commit

Permalink
Merge pull request #19 from Clonkk/main
Browse files Browse the repository at this point in the history
nimibook Cli to init, build, clean, update and general refactoring on repo structure
  • Loading branch information
pietroppeter authored Jun 4, 2021
2 parents 4c8b542 + 9acda49 commit 2e2d2ec
Show file tree
Hide file tree
Showing 55 changed files with 322 additions and 101 deletions.
27 changes: 27 additions & 0 deletions .github/workflows/valid.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
on:
pull_request:
branches:
- main
push:
branches:
- main

jobs:
tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: "install_nim"
id: install_nim
uses: iffy/install-nim@v3
- run: cat nimibook.nimble
- run: nimble install -y
- name: Gen Book
run: nimble genbook
- name: Gen Book outside repo
run: nim r examplebook.nim build
working-directory: examples
- name: Check book outside repo
run: nim r examplebook.nim clean
working-directory: examples

10 changes: 4 additions & 6 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
!docs/.gitignore
!docs/css
!docs/FontAwesome
!docs/fonts
!docs/js
bin/
docs/
book/book.json
book/book.json
nbook

44 changes: 35 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,48 @@ provided by [nim-markdown]. For a quick reference of supported syntax see the [c

### Status

nimibook currently provides minimal functionality to create a book, notably missing is
a command line interface to automate common task (e.g. initialization of a new nimibook).
nimibook currently provides minimal functionality to create a book and support a local CLI mode.

## Installation

To be able to use nimibook, currently the only way is to recreate the same content of the repository
and adjust it to your content. You can do that using the template feature from github
or with a checkout of the repo and copying and pasting.

Discussion of further options is ongoing in [issue #12](https://github.com/pietroppeter/nimibook/issues/12).
To install Nimibook simply use : ``nimble install nimibook``

## Usage

1. Write your content using [nimib] or simple markdown files in the ``book`` folder.
2. Use the Toc DSL to link chapters to content in ``genbook.nim``.
3. Generate your books in the ``docs`` folder using ``nimble genbook``.

2. Use the Table of Content (ToC) DSL to link chapters to content in ``nbook.nim``.
Example :
```nim
import nimibook
var book = newBookFromToc("Dummy Book", "book"): # Create a new book called "Dummy", whose content is in the folder "book"
section("Dummy", "index"): # Create a new section called "Dummy", its content is the file "index.nim". Notice how the .nim extensions is optionnal
entry("Simple example", "page_1.nim") # Create a new entry called "Simple example", its content is the file "page_1.nim"
nimibookCli(book)
```
See [nimibook] or [Nimibook repo](https://github.com/pietroppeter/nimibook
) for more documentations and examples.

3. Generate your very own CLI tools or use Nimble tasks with ``nim c -d:release nbook.nim``.
* ``./nbook init`` to init your book structure. **This command must be ran at least once**.
* ``./nbook build`` to build your book.

4. Whenever your Table of Content changes (add/remove files, changes sections organization), recompile your ``nbook`` and run the ``build`` command : ``nim c -d:release nbook.nim && ./nbook build``
* It is also doable in one command : ``nim r -d:release nbook.nim build``
* You don't need to call the ``init`` command again.
* Rinse and repeat until your ToC is done ! Then you can just edit files and call ``build`` without recompiling.

## Tips and Tricks

* Each book requires its own ToC and thus will be its own CLI Apps
* ``nbook.nim`` is the default name used - it is possible to use another name.
* Multiple books ``nbook.nim`` cannot share the same folder. Instead, either split them into two separate books, or merge them into one.
* Some commands :
* ``./nbook clean`` will remove generated files and restart from a clean state.
* ``./nbook update`` will update assets and mustache template.
* These two commands will modify installed files, use them with cuation if you customized files locally.

<!--refs-->
[mdbook]: https://rust-lang.github.io/mdBook/index.html
Expand Down
1 change: 1 addition & 0 deletions book/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
*.html
*.mustache
#toc.mustache
2 changes: 1 addition & 1 deletion book/index.nim
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ proc readFileUntil(filename: string, text: string): string =
result &= line & '\n'

nbText: "../README.md".readFileUntil("<!--SKIP")
nbSave
nbSave
1 change: 1 addition & 0 deletions examples/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
examplebook
3 changes: 3 additions & 0 deletions examples/book/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
*.mustache
*.html
*.json
11 changes: 11 additions & 0 deletions examples/book/book_1.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import nimib, nimibook

nbInit

nbUseNimibook # overrides nimib defaults with nimibooks and loads book configuration

nbText: """ ## This is a title
This is a sentence in a page
"""

nbSave
12 changes: 12 additions & 0 deletions examples/book/index.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import nimib, nimibook

nbInit

nbUseNimibook # overrides nimib defaults with nimibooks and loads book configuration

nbText: "Hello world"

nbCode:
doAssert 1+2 == 3

nbSave
8 changes: 8 additions & 0 deletions examples/examplebook.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import nimibook

var book = newBookFromToc("Dummy Book", "book"):
section("Dummy", "index"):
entry("Simple example", "book_1")

nimibookCli(book)

4 changes: 2 additions & 2 deletions genbook.nim → nbook.nim
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import nimibook, os # os is used inside Toc DSL
import nimibook

var book = newBookFromToc("nimibook", "book"):
section("Introduction", "index"): # .nim extension is optional
Expand All @@ -13,4 +13,4 @@ var book = newBookFromToc("nimibook", "book"):
draft("Draft chapter", "draft.md")

book.git_repository_url = "https://github.com/pietroppeter/nimibook"
nbBookTasks
nimibookCli(book)
24 changes: 6 additions & 18 deletions nimibook.nimble
Original file line number Diff line number Diff line change
Expand Up @@ -10,32 +10,20 @@ srcDir = "src"
# Dependencies

requires "nim >= 1.4.0"
requires "nimib >= 0.1.2"
requires "nimib >= 0.1.3"
requires "jsony >= 1.0.1"

import os

task genbook, "build book":
selfExec(" r -d:release genbook.nim")
selfExec(" r -d:release nbook.nim init")
selfExec(" r -d:release nbook.nim build")

task dumpbook, "dump book.json":
selfExec(" r -d:release -d:dumpBook genbook.nim")
selfExec(" r -d:release nbook.nim dump")

task cleanbook, "remove all files created during build":
# todo: it should remove all files and directories not tracked in git from docs
for file in walkDirRec("docs"):
if file.endsWith(".html"):
rmFile(file)
echo "removed ", file
for file in ["book/book.json"]: # hardcoded files to remove (one for now)
if fileExists(file):
rmFile(file)
echo "removed ", file
# if by mistake I create html in book folder, remove them
for file in walkDirRec("book"):
if file.endsWith(".html"):
rmFile(file)
echo "removed ", file

selfExec(" r -d:release nbook.nim clean ")

task srcpretty, "run nimpretty on nim files in src folder":
for file in walkDirRec("src"):
Expand Down
51 changes: 41 additions & 10 deletions src/nimibook.nim
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,44 @@ export types, render, tocs, publishers, defaults, docs, books
template nbUseNimibook* =
nbDoc.useNimibook

template nbBookTasks* =
when defined(printBook):
import print
print book
elif defined(dumpBook):
dump book
elif defined(cleanBook):
clean book
else:
publish book
proc printHelp() =
echo """
Choose one of the following options : init, clean, check, build, update
init : Initialize book structure.
clean : Delete generated files and files that are not supposed to be here (use this with caution).
check : Check generated book is correct.
build : Build your book !
update : Update assets and mustache template.
"""

import std/[os, parseopt]
export os, parseopt
template nimibookCli*(book: Book) =
var p = initOptParser()
var hasArgs = false
while true:
p.next()
case p.kind
of cmdEnd:
if not hasArgs:
printHelp()
break
of cmdShortOption, cmdLongOption:
discard
of cmdArgument:
hasArgs = true
if p.key == "init":
init book
elif p.key == "clean":
clean book
elif p.key == "check":
check book
elif p.key == "build":
# TODO specify folder in options
publish book
elif p.key == "update":
update book
elif p.key == "dump":
dump book
else:
printHelp()
78 changes: 74 additions & 4 deletions src/nimibook/books.nim
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import std / os
import nimibook / [types, entries]
import std / [os, strutils, sequtils, sugar]
import nimibook / [types, entries, tocs]
import jsony

# fix for jsony: quote in string. https://github.com/treeform/jsony/issues/14
Expand Down Expand Up @@ -51,18 +51,88 @@ proc dumpHook*(s: var string, v: string) =
s.setLen(at)

proc dump*(book: Book) =
var book = book
let uri = normalizedPath(book.toc.path / "book.json")
writeFile(uri, book.toJson)

proc clean*(book: Book) =
proc cleanjson*(book: Book) =
let uri = normalizedPath(book.toc.path / "book.json")
removeFile(uri)

proc files(book: Book): seq[string] =
result = collect(newSeq):
for p in book.toc.entries: p.path

proc htmlFiles(book: Book): seq[string] =
result = book.toc.entries.map(x => "docs" / url(x))

proc cleanRootFolder(book: Book) =
# All source files
let srcurls: seq[string] = book.files
# debugEcho("walkDirRec ", book.toc.path)
for f in walkDirRec(book.toc.path):
let ext = f.splitFile().ext
if f notin srcurls and ext != ".mustache" and ext != ".nims" and ext != ".cfg" and not f.contains(".git"):
# debugEcho(" >> removeFile ", f)
removeFile(f)

proc shouldDelete(book: Book, dir, f: string): bool =
# Remove anything that's not in "docs/assets" or "docs/statis" (for image and shit like that).
if isRelativeTo(f, dir / "assets"):
return false

if f in book.keep:
return false

if f.contains(".git"):
return false

for keep in book.keep:
if isRelativeTo(f, dir / keep):
return false

return true

proc cleanDocFolder(book: Book) =
# Since getCurrentDir() is used it assumes that the binary is called from the rootfolder
let docDir = "docs"
# debugEcho("walkDirRec ", docDir)
for f in walkDirRec(docDir):
if shouldDelete(book, docDir, f):
# debugEcho(" >> removeFile ", f)
removeFile(f)

for f in walkDirRec(docDir, yieldFilter = {pcDir}):
# Remove leftover folders
if shouldDelete(book, docDir, f):
# debugEcho(" >> removeDir", f)
removeDir(f)

proc clean*(book: Book) =
cleanjson(book)
cleanRootFolder(book)
cleanDocFolder(book)

proc load*(path: string): Book =
let uri = normalizedPath(path)
readFile(uri).fromJson(Book)

proc check*(book: Book) =
for entry in book.toc.entries:
entry.check()
echo "Check toc => OK"
echo "Check Book: OK"

proc initBookFile(book: Book) =
let srcurls = book.files
for f in srcurls:
if not fileExists(f):
let file = open(f, fmWrite)
file.close()

proc init*(book: Book) =
populateAssets(book.toc.path, false)
initBookFile(book)

proc update*(book: Book) =
populateAssets(book.toc.path, true)
initBookFile(book)
2 changes: 1 addition & 1 deletion src/nimibook/defaults.nim
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ proc setDefaults*(book: var Book) =
book.preferred_dark_theme = "navy"
book.theme_option = {"light": "Light (default)", "rust": "Rust", "coal": "Coal", "navy": "Navy", "ayu": "Ayu"}.toTable
book.favicon_escaped = """<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2280%22>🐳</text></svg>">"""
book.git_repository_icon = "fa-github"
book.git_repository_icon = "fa-github"
Loading

0 comments on commit 2e2d2ec

Please sign in to comment.