├── src ├── tags.md ├── images │ ├── basic-pdf.png │ ├── basic-mkdocs.png │ ├── basic-pdf-hello.png │ ├── basic-pdf-seqdiag.png │ ├── basic-mkdocs-hello.png │ ├── basic-mkdocs-seqdiag.png │ ├── architecture-detailed.png │ ├── architecture-overview.png │ ├── basic-pdf-seqdiag-comic.png │ └── basic-mkdocs-seqdiag-comic.png ├── tutorials │ ├── img │ │ ├── slate.png │ │ ├── aglio1.png │ │ ├── aglio2.png │ │ ├── slate_raml.png │ │ └── docker_mkdocs.jpg │ ├── db │ │ ├── img │ │ │ ├── dbml.png │ │ │ └── oracle.png │ │ ├── db.md │ │ ├── pgsql.md │ │ ├── dbml.md │ │ └── oracle.md │ ├── preprocessor │ │ ├── intro.md │ │ ├── generator.md │ │ ├── install.md │ │ └── preprocessor.md │ ├── docker.md │ ├── first_project.md │ └── api.md ├── preprocessors │ ├── testrail.md │ ├── bpmn.md │ ├── badges.md │ ├── dbdoc.md │ ├── flags.md │ ├── history.md │ ├── ramldoc.md │ ├── anchors.md │ ├── archeme.md │ ├── argdown.md │ ├── dbmldoc.md │ ├── flatten.md │ ├── includes.md │ ├── macros.md │ ├── mermaid.md │ ├── replace.md │ ├── blockdiag.md │ ├── csvtables.md │ ├── glossary.md │ ├── graphviz.md │ ├── metagraph.md │ ├── plantuml.md │ ├── reindexer.md │ ├── swaggerdoc.md │ ├── customids.md │ ├── epsconvert.md │ ├── imagemagick.md │ ├── imgcaptions.md │ ├── imgconvert.md │ ├── runcommands.md │ ├── showcommits.md │ ├── superlinks.md │ ├── admonitions.md │ ├── bindfigma.md │ ├── elasticsearch.md │ ├── imagineui.md │ ├── templateparser.md │ ├── apireferences.md │ ├── bindsympli.md │ ├── multilinetables.md │ ├── pgsqldoc.md │ ├── checksources.md │ ├── escapecode.md │ ├── removeexcess.md │ ├── confluence.md │ ├── repolink.md │ └── general_notes.md ├── backends │ ├── mdtopdf.md │ ├── aglio.md │ ├── slate.md │ ├── mkdocs.md │ ├── confluence.md │ └── pandoc.md ├── cli │ ├── bump.md │ ├── init │ │ ├── index.md │ │ └── templates │ │ │ └── preprocessor.md │ ├── subset.md │ ├── gupload.md │ ├── meta_generate.md │ └── src.md ├── config │ ├── downloadfile.md │ ├── slugs.md │ ├── yaml_include.md │ ├── alt_structure.md │ └── from.md ├── meta.md ├── releases.md ├── stylesheets │ └── extra.css ├── index.md ├── quickstart.md ├── installation.md ├── architecture.md ├── debugging_builds.md ├── dev_reference.md └── config.md ├── template ├── PTMono.zip ├── PTSans.zip ├── octopus-black-512.png └── docs.tex ├── theme ├── assets │ ├── foliant-docs.pdf │ └── images │ │ ├── octopus-black-32.ico │ │ └── octopus-white.svg ├── main.html └── partials │ └── source.html ├── Dockerfile-site ├── .gitignore ├── .travis.yml ├── requirements.txt ├── Dockerfile-pdf ├── README.md ├── docker-compose.yml ├── .github └── workflows │ └── deploy-site-to-pages.yml ├── mkdocs.yml ├── repos.yml └── foliant.yml /src/tags.md: -------------------------------------------------------------------------------- 1 | # Tags 2 | 3 | [TAGS] 4 | -------------------------------------------------------------------------------- /template/PTMono.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foliant-docs/docs/HEAD/template/PTMono.zip -------------------------------------------------------------------------------- /template/PTSans.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foliant-docs/docs/HEAD/template/PTSans.zip -------------------------------------------------------------------------------- /src/images/basic-pdf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foliant-docs/docs/HEAD/src/images/basic-pdf.png -------------------------------------------------------------------------------- /src/images/basic-mkdocs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foliant-docs/docs/HEAD/src/images/basic-mkdocs.png -------------------------------------------------------------------------------- /src/tutorials/img/slate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foliant-docs/docs/HEAD/src/tutorials/img/slate.png -------------------------------------------------------------------------------- /src/images/basic-pdf-hello.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foliant-docs/docs/HEAD/src/images/basic-pdf-hello.png -------------------------------------------------------------------------------- /src/tutorials/db/img/dbml.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foliant-docs/docs/HEAD/src/tutorials/db/img/dbml.png -------------------------------------------------------------------------------- /src/tutorials/img/aglio1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foliant-docs/docs/HEAD/src/tutorials/img/aglio1.png -------------------------------------------------------------------------------- /src/tutorials/img/aglio2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foliant-docs/docs/HEAD/src/tutorials/img/aglio2.png -------------------------------------------------------------------------------- /template/octopus-black-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foliant-docs/docs/HEAD/template/octopus-black-512.png -------------------------------------------------------------------------------- /theme/assets/foliant-docs.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foliant-docs/docs/HEAD/theme/assets/foliant-docs.pdf -------------------------------------------------------------------------------- /src/images/basic-pdf-seqdiag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foliant-docs/docs/HEAD/src/images/basic-pdf-seqdiag.png -------------------------------------------------------------------------------- /src/tutorials/db/img/oracle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foliant-docs/docs/HEAD/src/tutorials/db/img/oracle.png -------------------------------------------------------------------------------- /src/tutorials/img/slate_raml.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foliant-docs/docs/HEAD/src/tutorials/img/slate_raml.png -------------------------------------------------------------------------------- /src/images/basic-mkdocs-hello.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foliant-docs/docs/HEAD/src/images/basic-mkdocs-hello.png -------------------------------------------------------------------------------- /src/images/basic-mkdocs-seqdiag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foliant-docs/docs/HEAD/src/images/basic-mkdocs-seqdiag.png -------------------------------------------------------------------------------- /src/tutorials/img/docker_mkdocs.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foliant-docs/docs/HEAD/src/tutorials/img/docker_mkdocs.jpg -------------------------------------------------------------------------------- /Dockerfile-site: -------------------------------------------------------------------------------- 1 | FROM foliant/foliant 2 | 3 | COPY ./requirements.txt ./ 4 | 5 | RUN pip3 install -r ./requirements.txt 6 | -------------------------------------------------------------------------------- /src/images/architecture-detailed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foliant-docs/docs/HEAD/src/images/architecture-detailed.png -------------------------------------------------------------------------------- /src/images/architecture-overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foliant-docs/docs/HEAD/src/images/architecture-overview.png -------------------------------------------------------------------------------- /src/images/basic-pdf-seqdiag-comic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foliant-docs/docs/HEAD/src/images/basic-pdf-seqdiag-comic.png -------------------------------------------------------------------------------- /theme/assets/images/octopus-black-32.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foliant-docs/docs/HEAD/theme/assets/images/octopus-black-32.ico -------------------------------------------------------------------------------- /src/images/basic-mkdocs-seqdiag-comic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/foliant-docs/docs/HEAD/src/images/basic-mkdocs-seqdiag-comic.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /__folianttmp__/ 2 | /.*cache/ 3 | /*.pre/ 4 | /*.pdf 5 | /*.docx 6 | /*.mkdocs/ 7 | /*.mkdocs.src/ 8 | /*.log 9 | .DS_Store 10 | -------------------------------------------------------------------------------- /theme/main.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block extrahead %} 4 | 5 | {% endblock %} 6 | -------------------------------------------------------------------------------- /src/preprocessors/testrail.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - preprocessor 4 | --- 5 | 6 | # Testrail 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/backends/mdtopdf.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - backend 4 | - pdf 5 | --- 6 | 7 | # MdToPdf 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/cli/bump.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - cli extension 4 | - version 5 | --- 6 | 7 | # Bump 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/config/downloadfile.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - config extension 4 | --- 5 | 6 | # DownloadFile 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/cli/init/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - cli extension 4 | - template 5 | --- 6 | 7 | # Init 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/cli/subset.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - cli extension 4 | - config 5 | --- 6 | 7 | # Subset 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/preprocessors/bpmn.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - preprocessor 4 | - diagram 5 | --- 6 | 7 | # BPMN 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/cli/gupload.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - cli extension 4 | - google drive 5 | --- 6 | 7 | # Gupload 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/config/slugs.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - config extension 4 | - chapters 5 | --- 6 | 7 | # Slugs 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/preprocessors/badges.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - preprocessor 4 | - git 5 | --- 6 | 7 | # Badges 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/preprocessors/dbdoc.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - preprocessor 4 | - database 5 | --- 6 | 7 | # DBDoc 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/preprocessors/flags.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - preprocessor 4 | - markdown 5 | --- 6 | 7 | # Flags 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/preprocessors/history.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - preprocessor 4 | - git 5 | --- 6 | 7 | # History 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/preprocessors/ramldoc.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - preprocessor 4 | - API 5 | --- 6 | 7 | # RAMLDoc 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/preprocessors/anchors.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - preprocessor 4 | - markdown 5 | --- 6 | 7 | # Anchors 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/preprocessors/archeme.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - preprocessor 4 | - diagram 5 | --- 6 | 7 | # Archeme 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/preprocessors/argdown.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - preprocessor 4 | - diagram 5 | --- 6 | 7 | # Argdown 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/preprocessors/dbmldoc.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - preprocessor 4 | - database 5 | --- 6 | 7 | # DBMLDoc 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/preprocessors/flatten.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - preprocessor 4 | - pandoc 5 | --- 6 | 7 | # Flatten 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/preprocessors/includes.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - preprocessor 4 | - git 5 | --- 6 | 7 | # Includes 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/preprocessors/macros.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - preprocessor 4 | - markdown 5 | --- 6 | 7 | # Macros 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/preprocessors/mermaid.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - preprocessor 4 | - diagram 5 | --- 6 | 7 | # Mermaid 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/preprocessors/replace.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - preprocessor 4 | - markdown 5 | --- 6 | 7 | # Replace 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/preprocessors/blockdiag.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - preprocessor 4 | - diagram 5 | --- 6 | 7 | # Blockdiag 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/preprocessors/csvtables.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - preprocessor 4 | - table 5 | --- 6 | 7 | # CSVTables 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/preprocessors/glossary.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - preprocessor 4 | - pandoc 5 | --- 6 | 7 | # Glossary 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/preprocessors/graphviz.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - preprocessor 4 | - diagram 5 | --- 6 | 7 | # Graphviz 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/preprocessors/metagraph.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - preprocessor 4 | - diagram 5 | --- 6 | 7 | # MetaGraph 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/preprocessors/plantuml.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - preprocessor 4 | - diagram 5 | --- 6 | 7 | # Plantuml 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/preprocessors/reindexer.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - preprocessor 4 | - search 5 | --- 6 | 7 | # Reindexer 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/preprocessors/swaggerdoc.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - preprocessor 4 | - API 5 | --- 6 | 7 | # SwaggerDoc 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/backends/aglio.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - backend 4 | - site 5 | - API 6 | - SSG 7 | --- 8 | 9 | # Aglio 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/backends/slate.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - backend 4 | - site 5 | - API 6 | - SSG 7 | --- 8 | 9 | # Slate 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/config/yaml_include.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - config extension 4 | - include 5 | --- 6 | 7 | # YAMLInclude 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/meta.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - overview 4 | - config 5 | - yaml 6 | --- 7 | 8 | # Metadata 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/preprocessors/customids.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - preprocessor 4 | - markdown 5 | --- 6 | 7 | # CustomIDs 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/preprocessors/epsconvert.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - preprocessor 4 | - image 5 | --- 6 | 7 | # Epsconvert 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/preprocessors/imagemagick.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - preprocessor 4 | - image 5 | --- 6 | 7 | # ImageMagick 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/preprocessors/imgcaptions.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - preprocessor 4 | - image 5 | --- 6 | 7 | # ImgCaptions 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/preprocessors/imgconvert.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - preprocessor 4 | - image 5 | --- 6 | 7 | # ImgConvert 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/preprocessors/runcommands.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - preprocessor 4 | - shell 5 | --- 6 | 7 | # RunCommands 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/preprocessors/showcommits.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - preprocessor 4 | - git 5 | --- 6 | 7 | # ShowCommits 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/preprocessors/superlinks.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - preprocessor 4 | - markdown 5 | --- 6 | 7 | # SuperLinks 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/backends/mkdocs.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - backend 4 | - site 5 | - SSG 6 | - mkdocs 7 | --- 8 | 9 | # MkDocs 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/config/alt_structure.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - config extension 4 | - chapters 5 | --- 6 | 7 | # AltStructure 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/preprocessors/admonitions.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - preprocessor 4 | - markdown 5 | --- 6 | 7 | # Admonitions 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/preprocessors/bindfigma.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - preprocessor 4 | - image 5 | - design 6 | --- 7 | 8 | # BindFigma 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/preprocessors/elasticsearch.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - preprocessor 4 | - search 5 | --- 6 | 7 | # Elasticsearch 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/preprocessors/imagineui.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - preprocessor 4 | - image 5 | - design 6 | --- 7 | 8 | # ImagineUI 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/preprocessors/templateparser.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - preprocessor 4 | - jinja 5 | --- 6 | 7 | # TemplateParser 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/cli/meta_generate.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - cli extension 4 | - yaml 5 | --- 6 | 7 | # Meta Generate 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/preprocessors/apireferences.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - preprocessor 4 | - API 5 | - DB 6 | --- 7 | 8 | # APIReferences 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/preprocessors/bindsympli.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - preprocessor 4 | - image 5 | - design 6 | --- 7 | 8 | # BindSympli 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/preprocessors/multilinetables.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - preprocessor 4 | - table 5 | --- 6 | 7 | # MultilineTables 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/preprocessors/pgsqldoc.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - preprocessor 4 | - database 5 | - deprecated 6 | --- 7 | 8 | # Pgsqldoc 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/cli/init/templates/preprocessor.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - template 4 | - preprocessor 5 | --- 6 | 7 | # Preprocessor 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/preprocessors/checksources.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - preprocessor 4 | - yaml 5 | - config 6 | --- 7 | 8 | # CheckSources 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/preprocessors/escapecode.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - preprocessor 4 | - markdown 5 | --- 6 | 7 | # EscapeCode and UnescapeCode 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/preprocessors/removeexcess.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - preprocessor 4 | - yaml 5 | - config 6 | --- 7 | 8 | # RemoveExcess 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/releases.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - changelog 4 | --- 5 | 6 | # History of Releases 7 | 8 | Here is the single linear history of releases of Foliant and its extensions. It’s also available as an [RSS feed](https://foliant-docs.github.io/docs/rss.xml). 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/backends/confluence.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - backend 4 | - confluence 5 | --- 6 | 7 | # Confluence 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/backends/pandoc.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - backend 4 | - docx 5 | - pdf 6 | - odt 7 | - epub 8 | - tex 9 | - pandoc 10 | --- 11 | 12 | # Pandoc 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/preprocessors/confluence.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - preprocessor 4 | - confluence 5 | --- 6 | 7 | # Confluence 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/stylesheets/extra.css: -------------------------------------------------------------------------------- 1 | .md-header { 2 | background-color: rgba(0, 0, 0, 0.87); 3 | } 4 | 5 | [data-md-color-scheme="slate"] { 6 | --md-primary-fg-color: #0d0839; 7 | --md-typeset-a-color: #6bc7f3; 8 | --md-accent-fg-color: #ff6e42; 9 | --md-default-fg-color--light: hsla(var(--md-hue)); 10 | --md-typeset-mark-color: #069884; 11 | } -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: required 2 | 3 | services: 4 | - docker 5 | 6 | install: '' 7 | 8 | script: 9 | - docker-compose run site 10 | 11 | deploy: 12 | provider: pages 13 | local-dir: foliant-docs.mkdocs 14 | skip-cleanup: true 15 | github-token: $GITHUB_TOKEN 16 | keep-history: true 17 | verbose: true 18 | on: 19 | branch: master 20 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | foliantcontrib.anchors 2 | foliantcontrib.flags >= 1.0.2 3 | foliantcontrib.history >= 1.0.9 4 | foliantcontrib.includes >= 1.1.13 5 | foliantcontrib.macros >= 1.0.4 6 | foliantcontrib.mkdocs >= 1.0.13 7 | foliantcontrib.pandoc == 1.0.11 8 | foliantcontrib.superlinks >= 1.0.11 9 | foliantcontrib.yaml_include >= 1.0.0 10 | mkdocs-material == 8.2.14 11 | mkdocs-material-extensions == 1.0.3 12 | Jinja2 == 3.1.2 13 | -------------------------------------------------------------------------------- /Dockerfile-pdf: -------------------------------------------------------------------------------- 1 | FROM foliant/foliant:pandoc 2 | 3 | COPY ./requirements.txt ./ 4 | COPY ./template/ ./template/ 5 | 6 | RUN pip3 install -r ./requirements.txt 7 | 8 | RUN mkdir -p /usr/share/fonts/truetype/ptsans/ \ 9 | && mkdir -p /usr/share/fonts/truetype/ptmono/ \ 10 | && unzip ./template/PTSans.zip -d /usr/share/fonts/truetype/ptsans/ \ 11 | && unzip ./template/PTMono.zip -d /usr/share/fonts/truetype/ptmono/ \ 12 | && fc-cache -fv 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Foliant Documentation 2 | 3 | [![Build Status](https://api.travis-ci.com/foliant-docs/docs.svg?branch=master)](https://travis-ci.com/github/foliant-docs) 4 | 5 | ## Build Locally 6 | 7 | With Docker Compose: 8 | 9 | ```bash 10 | $ git clone git@github.com:foliant-docs/foliant.git 11 | $ cd foliant/docs 12 | # Site: 13 | $ docker compose run --rm site 14 | # PDF: 15 | $ docker compose run --rm pdf 16 | ``` 17 | 18 | With pip and stuff (requires Python 3.6+, Pandoc, and TeXLive): 19 | 20 | ```bash 21 | $ git clone git@github.com:foliant-docs/foliant.git 22 | $ cd foliant/docs 23 | $ pip install -r requirements 24 | # Site: 25 | $ foliant make site 26 | # PDF: 27 | $ foliant make pdf 28 | ``` 29 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | 3 | services: 4 | pre: 5 | build: 6 | context: ./ 7 | dockerfile: Dockerfile-site 8 | volumes: 9 | - ./:/usr/src/app/ 10 | working_dir: /usr/src/app/ 11 | command: make pre -dk 12 | site: 13 | build: 14 | context: ./ 15 | dockerfile: Dockerfile-site 16 | volumes: 17 | - ./:/usr/src/app/ 18 | working_dir: /usr/src/app/ 19 | command: make site 20 | pdf: 21 | build: 22 | context: ./ 23 | dockerfile: Dockerfile-pdf 24 | volumes: 25 | - ./:/usr/src/app/ 26 | working_dir: /usr/src/app/ 27 | command: make pdf 28 | -------------------------------------------------------------------------------- /src/config/from.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - config extension 4 | - multiproject 5 | --- 6 | 7 | # MultiProject 8 | 9 | 10 | 11 | ## Installation 12 | 13 | 14 | 15 | ## Usage 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/preprocessors/repolink.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - preprocessor 4 | - git 5 | - mkdocs 6 | --- 7 | 8 | # RepoLink 9 | 10 | 11 | 12 | ## Installation 13 | 14 | RepoLink preprocessor is a part of MultiProject extension: 15 | 16 | 17 | 18 | ## Usage 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/cli/src.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - cli extension 4 | - backup 5 | - multiproject 6 | --- 7 | 8 | # Src 9 | 10 | 11 | 12 | ## Installation 13 | 14 | To enable the `src` command, install MultiProject extension: 15 | 16 | 17 | 18 | ## Usage 19 | 20 | 21 | -------------------------------------------------------------------------------- /.github/workflows/deploy-site-to-pages.yml: -------------------------------------------------------------------------------- 1 | name: build and deploy docs-site to GitHub Pages 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | workflow_dispatch: 8 | 9 | permissions: 10 | contents: read 11 | pages: write 12 | id-token: write 13 | 14 | jobs: 15 | build-docs-site: 16 | runs-on: ubuntu-latest 17 | steps: 18 | - name: Checkout 19 | uses: actions/checkout@v3 20 | - name: Setup GH Pages 21 | uses: actions/configure-pages@v5 22 | - run: docker compose run --rm site 23 | - name: Upload artifact 24 | uses: actions/upload-pages-artifact@v3 25 | with: 26 | path: ./foliant-docs.mkdocs 27 | 28 | deploy-docs-site: 29 | environment: 30 | name: github-pages 31 | url: ${{ steps.deployment.outputs.page_url }} 32 | runs-on: ubuntu-latest 33 | needs: build-docs-site 34 | steps: 35 | - name: Deploy to GitHub Pages 36 | id: deployment 37 | uses: actions/deploy-pages@v4 38 | -------------------------------------------------------------------------------- /theme/partials/source.html: -------------------------------------------------------------------------------- 1 | 22 | 23 | 24 | 30 |
31 | {% set icon = config.theme.icon.repo or "fontawesome/brands/git-alt" %} 32 | {% include ".icons/" ~ icon ~ ".svg" %} 33 |
34 |
35 | {{ config.main_repo_name }} 36 |
37 |
-------------------------------------------------------------------------------- /mkdocs.yml: -------------------------------------------------------------------------------- 1 | # main repo will be displayed in the header 2 | main_repo_name: foliant-docs/foliant 3 | main_repo_url: https://github.com/foliant-docs/foliant 4 | 5 | repo_name: foliant-docs/docs 6 | repo_url: https://github.com/foliant-docs/docs 7 | edit_uri: edit/master/src/ 8 | theme: 9 | name: material 10 | custom_dir: !path ./theme/ 11 | palette: 12 | - scheme: default 13 | primary: "rgba(0, 0, 0, 0.87)" 14 | accent: light blue 15 | toggle: 16 | icon: material/weather-night 17 | name: Switch to dark mode 18 | - scheme: slate 19 | toggle: 20 | icon: material/weather-sunny 21 | name: Switch to light mode 22 | font: 23 | text: PT Sans 24 | code: PT Mono 25 | logo: assets/images/octopus-white.svg 26 | favicon: assets/images/octopus-black-32.ico 27 | features: 28 | - search.suggest 29 | - search.highlight 30 | - navigation.top 31 | icon: 32 | repo: fontawesome/brands/github-alt 33 | features: 34 | - search.suggest 35 | - search.highlight 36 | - navigation.instant 37 | - navigation.top 38 | 39 | 40 | extra: 41 | social: 42 | - icon: fontawesome/brands/github 43 | link: https://github.com/foliant-docs/foliant 44 | - icon: fontawesome/regular/file-pdf 45 | link: /docs/assets/foliant-docs.pdf 46 | analytics: 47 | provider: google 48 | property: UA-120535275-2 49 | plugins: 50 | - tags: 51 | tags_file: tags.md 52 | - search: 53 | lang: 54 | - en 55 | 56 | markdown_extensions: 57 | - def_list 58 | - pymdownx.highlight 59 | - toc: 60 | permalink: true 61 | - admonition 62 | - pymdownx.details 63 | - pymdownx.superfences 64 | extra_css: 65 | - 'stylesheets/extra.css' 66 | -------------------------------------------------------------------------------- /src/tutorials/preprocessor/intro.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - tutorial 4 | - preprocessor 5 | --- 6 | 7 | # Introduction 8 | 9 | Creating preprocessors for Foliant is quite straightforward because they are essentially just Python scripts wrapped in a `Preprocessor` class, which is provided by Foliant core. In this tutorial, we will go through all steps of creating a new preprocessor. 10 | 11 | The full source code of the preprocessor created in this tutorial can be found [here](https://github.com/foliant-docs/preprocessor_tutorial). 12 | 13 | --- 14 | 15 | First of all, we need to decide what our preprocessor will do. Let's say you need a preprocessor that will generate some placeholder gibberish text for your documentation, somewhat like [Lorem Ipsum](https://lipsum.com/). 16 | 17 | We need a way to tell Foliant to insert the placeholder into a specific part of our document. The Foliant way of doing that is using an XML-tag like the following. 18 | 19 | ```html 20 | 21 | ``` 22 | 23 | After the preprocessor is applied, this tag should be transformed into some placeholder text. 24 | 25 | ``` 26 | Hiteap zoiouxwaf jyrcaay yty xuzuapo eyuigouu. Ysseotaeq ytuiio qqyy yehiiy koyiyoky uul. Pan osfu zoiz oy ikcya tcsxecy qxiiyo. Gryxeye ogeelaee atprwm mjioy eigyyoov nx qe tayoiaud jodmaofue yvo ieyuunyrq eaowu. Jyqnr aej elqj wuytjcae oy igy ak. 27 | ``` 28 | 29 | We would also want to specify the size of the generated text, so our tag should accept the `size` parameter which will define the number of generated sentences: 30 | 31 | ```html 32 | 33 | ``` 34 | 35 | The tutorial is split into three stages: 36 | 37 | 1. Writing the gibberish generator, 38 | 1. Wrapping it in a `Preprocessor` class, 39 | 1. Installing and testing the preprocessor. 40 | 41 | So let's get started! 42 | 43 | Next: 44 | -------------------------------------------------------------------------------- /src/preprocessors/general_notes.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - preprocessor 4 | - yaml 5 | - config 6 | --- 7 | 8 | # General Notes on Usage 9 | 10 | Most simple preprocessors apply unconditionally to the whole content of each Markdown file in the Foliant project. But usually preprocessors look for some specific pseudo-XML tags in Markdown content. Each preprocessor registers its own set of tags. 11 | 12 | Tags can have attributes and a body. Attributes are usually used to specify some required or optional parameters. Body is the content that is enclosed between opening and closing tags; preprocessors usually do something with this content: 13 | 14 | ```xml 15 | body 16 | ``` 17 | 18 | Foliant under 1.0.8 tries to convert each attribute value into a boolean value, a number, or a string. Attribute values must be enclosed in double quotes (`"`). 19 | 20 | Since Foliant 1.0.9, attribute values are processed as YAML. Scalar values are also converted into boolean values, numbers and strings, but you may specify composite values that should be transformed into lists or dictionaries. You may also use modifiers (i.e. YAML tags) that are available in the Foliant project’s config. 21 | 22 | `!path` 23 | : The string preceded by this modifier should be converted into an existing path relative to the Foliant project’s top-level (“root”) directory. 24 | 25 | `!project_path` 26 | : The string preceded by this modifier should be converted into a path relative to the Foliant project’s top-level (“root”) directory. This path may be nonexistent. 27 | 28 | `!rel_path` 29 | : The string preceded by this modifier should be converted into a path relative to the currently processed Markdown file. This path may be nonexistent. 30 | 31 | If you develop a preprocessor that accepts some path, by default it is better to be a path relative to the currently processed Markdown file. 32 | 33 | Also, since Foliant 1.0.9, attribute values may be enclosed into double (`"`) or single (`'`) quotes. 34 | -------------------------------------------------------------------------------- /src/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - changelog 4 | --- 5 | 6 | # Welcome to Foliant! 7 | 8 | > Better spend one day learning to fly and get there in five minutes than walking. 9 | 10 | Foliant is an all-in-one single-source documentation authoring tool. It lets you produce standalone documents in **pdf** and **docx**, build **static websites** and upload pages to **Confluence**, all from single Markdown source. 11 | 12 | Foliant is a higher order tool, which means it uses other programs to do its job. For building pdf and docx, it can use [Pandoc](https://pandoc.org/) or [md-to-pdf](https://github.com/simonhaenisch/md-to-pdf), for websites [MkDocs](https://www.mkdocs.org/), [Aglio](https://github.com/danielgtaylor/aglio) or [Slate](https://github.com/slatedocs/slate). 13 | 14 | Foliant preprocessors let you reuse parts of your documents, show and hide content with flags, render diagrams from text, and much more. 15 | 16 | Foliant is highly extensible, so if it lacks some functions or output formats you can always make a plugin for it or request one from our team. 17 | 18 | > Logo made by [Hand Drawn Goods](http://handdrawngoods.com/) from [flaticon.com](https://www.flaticon.com/). 19 | 20 | ## Who Is It for? 21 | 22 | You’ll love Foliant if you: 23 | 24 | * need to ship documentation as pdf, docx, and websites 25 | * want to use Markdown with consistent extension system instead of custom syntax for every new bit of functionality 26 | * like reStructuredText’s extensibility and AsciiDoc’s flexibility, but would rather use Markdown 27 | * want a tool that you can extend with custom plugins without dealing with something as over-engineered as Sphinx 28 | * want to work with docs as code and make them a part of your CI pipeline 29 | * have a lot of segregated repositories with sources of your documents and want to standardize the documentation approach. 30 | 31 | ## Changelog 32 | 33 | Here is the changelog of [Foliant Core](https://github.com/foliant-docs/foliant/), the main and only strictly required package. See also the history of releases of numerous Foliant extensions. 34 | 35 | 36 | -------------------------------------------------------------------------------- /src/tutorials/db/db.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - tutorial 4 | - database 5 | --- 6 | 7 | # Introduction 8 | 9 | In these tutorials we will show you a way to document your database using Foliant. Right now there are options available for those of you who use **PostgreSQL**, **Oracle**, **MySQL**, **MS SQL Server** and **DBML**. If your DBMS is not in the list, [send us an issue](https://github.com/foliant-docs/foliantcontrib.dbdoc/issues), we'll do our best to add the support to it as fast as possible. 10 | 11 | ## The principles 12 | 13 | Generally, we want to keep our docs as close to the code as possible. For documenting the source code of an application we usually can utilize the power of Swagger to generate docs from comments in the sources. Since there’s no Swagger for databases, we had to invent something similar. 14 | 15 | We are going to add actual descriptions of the tables and fields using *comments*. Comment (not to be confused with SQL script `-- comment`) is a special entity which in one way or another is present in most DBMSs. They don’t affect the data or table structure, they are only used for documentation purposes. You can add a comment like this: 16 | 17 | ```sql 18 | COMMENT ON TABLE "Clients" IS "Table holding info about the clients" 19 | ``` 20 | 21 | After describing all your entities inside your database, we need to get all this information for our document. For this we will use Foliant DBDoc preprocessor. It queries the database to get its structure (including the comments) and converts it into Markdown. We can then use this Markdown to generate a static site for our documentation. 22 | 23 | ## The tutorials 24 | 25 | First tutorial is about creating a document out of [DBML](https://dbml.org/) schema. DBML is not a database but a simplified language for describing databases. 26 | 27 | The other two tutorials focus on the process of documenting actual databases. We have tutorials for PostgreSQL and Oracle. But the process of documenting other databases is quite similar. 28 | 29 | Documenting with DBML specification 30 | 31 | Documenting Oracle Database 32 | 33 | Documenting PostgreSQL Database 34 | -------------------------------------------------------------------------------- /src/quickstart.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - tutorial 4 | --- 5 | 6 | # Quickstart 7 | 8 | If you don't have Foliant installed, please follow the instructions first. 9 | 10 | **Step 1.** Create a new project 11 | 12 | ```bash 13 | $ foliant init 14 | ``` 15 | 16 | Or with Docker 17 | 18 | ```bash 19 | $ docker run --rm -it --user $(id -u):$(id -g) -v $(pwd):/usr/src/app -w /usr/src/app foliant/foliant init 20 | ``` 21 | 22 | **Step 2.** cd into the folder created by command 23 | 24 | ```bash 25 | $ cd my-project 26 | ``` 27 | 28 | **Step 3.** Edit the Markdown source of your documentation located in `src/index.md`. 29 | 30 | To build a static site with [MkDocs](https://www.mkdocs.org/), install the MkDocs backend (skip this step if you are using Docker) 31 | 32 | ```bash 33 | pip3 install foliantcontrib.mkdocs 34 | ``` 35 | 36 | **Step 4.** Build the site with `foliant make` command 37 | 38 | ```bash 39 | $ foliant make site 40 | ``` 41 | 42 | Or with Docker 43 | 44 | ```bash 45 | $ docker-compose run --rm foliant make site 46 | ``` 47 | 48 | **Done!** Your site is generated in the `My_Project-2020-05-25.mkdocs` folder, crank up a webserver to take a look at it 49 | 50 | ```bash 51 | $ python3 -m http.server -d My_Project-2020-05-25.mkdocs 52 | Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ... 53 | ``` 54 | 55 | Now let's build a DOCX out of the same source. You will need [Pandoc](https://pandoc.org/) and Pandoc backend for that, the instructions for installing them are in the installation guide. 56 | 57 | **Step 5.** Build docx 58 | 59 | ```bash 60 | $ foliant make docx 61 | ``` 62 | 63 | With Docker you will need to adjust the Dockerfile first, replace the first line with the following 64 | 65 | ```diff 66 | - FROM foliant/foliant 67 | + FROM foliant/foliant:pandoc 68 | ``` 69 | 70 | and rebuild the image 71 | 72 | ```bash 73 | $ docker-compose build 74 | ``` 75 | 76 | Finally, run the make command inside the container 77 | 78 | ```bash 79 | $ docker-compose run --rm foliant make docx 80 | ``` 81 | 82 | **Done!** The `My_Project-2020-05-25.docx` is created in the project dir. 83 | 84 | *** 85 | 86 | If you want to know more about how Foliant works, check out the or just dive straight into . 87 | -------------------------------------------------------------------------------- /src/installation.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - tutorial 4 | - install 5 | --- 6 | 7 | # Installation 8 | 9 | Installation of Foliant is split into three stages: installing Python with your system’s package manager, installing Foliant with pip, and optionally installing Pandoc and TeXLive bundle. Below you’ll find the instructions for three popular platforms: macOS, Windows, and Ubuntu. 10 | 11 | Alternatively, you can avoid installing Foliant and its dependencies on your system by using Docker and Docker Compose. 12 | 13 | 14 | ## macOS 15 | 16 | 1. Install Python 3 with Homebrew: 17 | 18 | $ brew install python3 19 | 20 | 2. Install Foliant with pip: 21 | 22 | $ pip3 install foliant foliantcontrib.init 23 | 24 | 3. If you plan to bake PDF or DOCX, install Pandoc and MacTeX with Homebrew: 25 | 26 | $ brew install pandoc mactex librsvg 27 | 28 | Finally, install the Pandoc backend: 29 | 30 | $ pip3 install foliantcontrib.pandoc 31 | 32 | ## Windows 33 | 34 | 0. Install [Scoop package manager](https://scoop.sh/) in PowerShell: 35 | 36 | $ iex (new-object net.webclient).downloadstring('https://get.scoop.sh') 37 | 38 | 1. Install Python 3 with Scoop: 39 | 40 | $ scoop install python 41 | 42 | 2. Install Foliant with pip: 43 | 44 | $ python -m pip install foliant foliantcontrib.init 45 | 46 | 3. If you plan to bake pdf or DOCX, install Pandoc and MikTeX with Scoop: 47 | 48 | $ scoop install pandoc latex 49 | 50 | Finally, install the Pandoc backend: 51 | 52 | $ pip3 install foliantcontrib.pandoc 53 | 54 | ## Ubuntu 55 | 56 | 1. Install Python 3 with apt. 57 | 58 | On 18.04 or higher Python 3 will already be installed. Check that by running: 59 | 60 | $ python3 61 | 62 | If it is not installed, here's a way to install the latest version: 63 | 64 | $ sudo apt update 65 | $ sudo apt install software-properties-common 66 | $ sudo add-apt-repository ppa:deadsnakes/ppa 67 | $ sudo apt install python3.9 python3-pip 68 | 69 | 2. Install Foliant with pip: 70 | 71 | $ pip3 install foliant foliantcontrib.init 72 | 73 | 3. If you plan to bake pdf or DOCX, install Pandoc and TeXLive with apt and wget: 74 | 75 | $ sudo apt update 76 | $ sudo apt install -y texlive-full librsvg2-bin pandoc 77 | 78 | Finally, install the Pandoc backend: 79 | 80 | $ pip3 install foliantcontrib.pandoc 81 | 82 | 83 | ## Docker 84 | 85 | There is a selection of Docker images for Foliant in the [Docker hub](https://hub.docker.com/r/foliant/foliant): 86 | 87 | * `foliant/foliant:slim` — minimal image of Foliant with no extensions; 88 | * `foliant/foliant` — the basic image with just Foliant core and the `init` command; 89 | * `foliant/foliant:pandoc` — asic image with the addition of TexLive and Pandoc for building PDF and DOCX; 90 | * `foliant/foliant:full` — the full image with all official Foliant extensions and third-party tools required for them to work. 91 | 92 | Choose the image you want and run the `docker pull command` 93 | 94 | ```bash 95 | $ docker pull foliant/foliant 96 | ``` 97 | 98 | If you are new to Docker, check our tutorial on using Foliant with Docker. 99 | -------------------------------------------------------------------------------- /repos.yml: -------------------------------------------------------------------------------- 1 | - https://github.com/foliant-docs/foliant.git 2 | - https://github.com/foliant-docs/foliantcontrib.admonitions.git 3 | - https://github.com/foliant-docs/foliantcontrib.aglio.git 4 | - https://github.com/foliant-docs/foliantcontrib.alt_structure.git 5 | - https://github.com/foliant-docs/foliantcontrib.anchors.git 6 | - https://github.com/foliant-docs/foliantcontrib.apilinks.git 7 | - https://github.com/foliant-docs/foliantcontrib.apireferences.git 8 | - https://github.com/foliant-docs/foliantcontrib.archeme.git 9 | - https://github.com/foliant-docs/foliantcontrib.argdown.git 10 | - https://github.com/foliant-docs/foliantcontrib.badges.git 11 | - https://github.com/foliant-docs/foliantcontrib.bindfigma.git 12 | - https://github.com/foliant-docs/foliantcontrib.bindsympli.git 13 | - https://github.com/foliant-docs/foliantcontrib.blockdiag.git 14 | - https://github.com/foliant-docs/foliantcontrib.bpmn.git 15 | - https://github.com/foliant-docs/foliantcontrib.bump.git 16 | - https://github.com/foliant-docs/foliantcontrib.checksources.git 17 | - https://github.com/foliant-docs/foliantcontrib.confluence.git 18 | - https://github.com/foliant-docs/foliantcontrib.csvtables.git 19 | - https://github.com/foliant-docs/foliantcontrib.customids.git 20 | - https://github.com/foliant-docs/foliantcontrib.dbdoc.git 21 | - https://github.com/foliant-docs/foliantcontrib.dbmldoc.git 22 | - https://github.com/foliant-docs/foliantcontrib.docus.git 23 | - https://github.com/foliant-docs/foliantcontrib.downloadfile.git 24 | - https://github.com/foliant-docs/foliantcontrib.elasticsearch.git 25 | - https://github.com/foliant-docs/foliantcontrib.epsconvert.git 26 | - https://github.com/foliant-docs/foliantcontrib.escapecode.git 27 | - https://github.com/foliant-docs/foliantcontrib.flags.git 28 | - https://github.com/foliant-docs/foliantcontrib.flatten.git 29 | - https://github.com/foliant-docs/foliantcontrib.graphviz.git 30 | - https://github.com/foliant-docs/foliantcontrib.gupload.git 31 | - https://github.com/foliant-docs/foliantcontrib.history.git 32 | - https://github.com/foliant-docs/foliantcontrib.imagemagick.git 33 | - https://github.com/foliant-docs/foliantcontrib.imgcaptions.git 34 | - https://github.com/foliant-docs/foliantcontrib.imgconvert.git 35 | - https://github.com/foliant-docs/foliantcontrib.includes.git 36 | - https://github.com/foliant-docs/foliantcontrib.init.git 37 | - https://github.com/foliant-docs/foliantcontrib.macros.git 38 | - https://github.com/foliant-docs/foliantcontrib.mdtopdf.git 39 | - https://github.com/foliant-docs/foliantcontrib.mermaid.git 40 | - https://github.com/foliant-docs/foliantcontrib.meta.git 41 | - https://github.com/foliant-docs/foliantcontrib.metagraph.git 42 | - https://github.com/foliant-docs/foliantcontrib.mkdocs.git 43 | - https://github.com/foliant-docs/foliantcontrib.multilinetables.git 44 | - https://github.com/foliant-docs/foliantcontrib.multiproject.git 45 | - https://github.com/foliant-docs/foliantcontrib.notifier.git 46 | - https://github.com/foliant-docs/foliantcontrib.pandoc.git 47 | - https://github.com/foliant-docs/foliantcontrib.pgsqldoc.git 48 | - https://github.com/foliant-docs/foliantcontrib.plantuml.git 49 | - https://github.com/foliant-docs/foliantcontrib.project_graph.git 50 | - https://github.com/foliant-docs/foliantcontrib.ramldoc.git 51 | - https://github.com/foliant-docs/foliantcontrib.reindexer.git 52 | - https://github.com/foliant-docs/foliantcontrib.removeexcess.git 53 | - https://github.com/foliant-docs/foliantcontrib.replace.git 54 | - https://github.com/foliant-docs/foliantcontrib.runcommands.git 55 | - https://github.com/foliant-docs/foliantcontrib.showcommits.git 56 | - https://github.com/foliant-docs/foliantcontrib.slate.git 57 | - https://github.com/foliant-docs/foliantcontrib.slugs.git 58 | - https://github.com/foliant-docs/foliantcontrib.subset.git 59 | - https://github.com/foliant-docs/foliantcontrib.superlinks.git 60 | - https://github.com/foliant-docs/foliantcontrib.swaggerdoc.git 61 | - https://github.com/foliant-docs/foliantcontrib.templateparser.git 62 | - https://github.com/foliant-docs/foliantcontrib.templates.preprocessor.git 63 | - https://github.com/foliant-docs/foliantcontrib.testcoverage.git 64 | - https://github.com/foliant-docs/foliantcontrib.testrail.git 65 | - https://github.com/foliant-docs/foliantcontrib.utils.git 66 | - https://github.com/foliant-docs/foliantcontrib.yaml_include.git 67 | - https://github.com/imagineui/foliantcontrib.imagineui.git -------------------------------------------------------------------------------- /foliant.yml: -------------------------------------------------------------------------------- 1 | title: &title Foliant 2 | slug: foliant-docs 3 | 4 | escape_code: true 5 | 6 | chapters: 7 | - index.md 8 | - installation.md 9 | - quickstart.md 10 | - Tutorials: 11 | - tutorials/first_project.md 12 | - tutorials/docker.md 13 | - tutorials/api.md 14 | - Documenting Databases with Foliant: 15 | - tutorials/db/db.md 16 | - tutorials/db/dbml.md 17 | - tutorials/db/oracle.md 18 | - tutorials/db/pgsql.md 19 | - Creating a Preprocessor: 20 | - tutorials/preprocessor/intro.md 21 | - tutorials/preprocessor/generator.md 22 | - tutorials/preprocessor/preprocessor.md 23 | - tutorials/preprocessor/install.md 24 | - architecture.md 25 | - config.md 26 | - debugging_builds.md 27 | - meta.md 28 | - dev_reference.md 29 | - Backends: 30 | - backends/aglio.md 31 | - backends/confluence.md 32 | - backends/mdtopdf.md 33 | - MkDocs: backends/mkdocs.md 34 | - backends/pandoc.md 35 | - backends/slate.md 36 | - Preprocessors: 37 | - General Notes: preprocessors/general_notes.md 38 | - preprocessors/admonitions.md 39 | - preprocessors/anchors.md 40 | - preprocessors/apireferences.md 41 | - preprocessors/archeme.md 42 | - preprocessors/argdown.md 43 | - preprocessors/badges.md 44 | - preprocessors/bindfigma.md 45 | - preprocessors/bindsympli.md 46 | - preprocessors/blockdiag.md 47 | - preprocessors/bpmn.md 48 | - preprocessors/checksources.md 49 | - preprocessors/confluence.md 50 | - preprocessors/csvtables.md 51 | - preprocessors/customids.md 52 | - preprocessors/dbmldoc.md 53 | - preprocessors/dbdoc.md 54 | - preprocessors/elasticsearch.md 55 | - preprocessors/epsconvert.md 56 | - preprocessors/escapecode.md 57 | - preprocessors/flags.md 58 | - preprocessors/flatten.md 59 | - preprocessors/glossary.md 60 | - preprocessors/graphviz.md 61 | - preprocessors/history.md 62 | - preprocessors/imagemagick.md 63 | - preprocessors/imagineui.md 64 | - preprocessors/imgcaptions.md 65 | - preprocessors/imgconvert.md 66 | - preprocessors/includes.md 67 | - preprocessors/macros.md 68 | - preprocessors/mermaid.md 69 | - preprocessors/metagraph.md 70 | - preprocessors/multilinetables.md 71 | - preprocessors/pgsqldoc.md 72 | - preprocessors/plantuml.md 73 | - preprocessors/ramldoc.md 74 | - preprocessors/reindexer.md 75 | - preprocessors/removeexcess.md 76 | - preprocessors/replace.md 77 | - preprocessors/repolink.md 78 | - preprocessors/runcommands.md 79 | - preprocessors/showcommits.md 80 | - preprocessors/superlinks.md 81 | - preprocessors/swaggerdoc.md 82 | - preprocessors/templateparser.md 83 | - preprocessors/testrail.md 84 | - CLI Extensions: 85 | - cli/bump.md 86 | - cli/gupload.md 87 | - cli/meta_generate.md 88 | - Init: cli/init/index.md 89 | - Init Templates: 90 | - cli/init/templates/preprocessor.md 91 | - cli/src.md 92 | - cli/subset.md 93 | - Config Extensions: 94 | - config/alt_structure.md 95 | - config/downloadfile.md 96 | - config/from.md 97 | - config/slugs.md 98 | - config/yaml_include.md 99 | - releases.md 100 | - tags.md 101 | 102 | preprocessors: 103 | - macros: 104 | macros: 105 | ref: {pandoc}{mkdocs} 106 | - flags 107 | - includes 108 | - superlinks 109 | - anchors 110 | - history: 111 | target_heading_level: 2 112 | rss: true 113 | rss_link: https://foliant-docs.github.io/docs/ 114 | rss_title: Foliant Releases History 115 | rss_description: Releases of Foliant documentation authoring tool and its extensions. 116 | repos: !include repos.yml 117 | 118 | backend_config: 119 | pandoc: 120 | template: !path template/docs.tex 121 | vars: 122 | title: *title 123 | subtitle: User’s Manual 124 | logo: !path template/octopus-black-512.png 125 | params: 126 | pdf_engine: xelatex 127 | listings: true 128 | mkdocs: 129 | mkdocs.yml: !include mkdocs.yml 130 | -------------------------------------------------------------------------------- /src/tutorials/db/pgsql.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - tutorial 4 | - database 5 | --- 6 | 7 | # Documenting PostgreSQL Database 8 | 9 | > Please note that this article will cover only the basic usage of the tools. For detailed information on the features and customizing output refer to each component’s docs. 10 | 11 | ## Installing prerequisites 12 | 13 | You will need to install some prerequisites. If you are running Foliant natively, follow the guide below. If you are working with our Full Docker image, you don’t need to do anything, you can skip to the next stage. 14 | 15 | First, you will need Foliant, of course. If you don’t have it yet, please, refer to the installation guide. 16 | 17 | Install PostgreSQL and its Python connector. 18 | 19 | ```bash 20 | $ pip3 install psycopg2-binary 21 | ``` 22 | 23 | Install DBDoc and PlantUML preprocessors, and the Slate backend: 24 | 25 | ```bash 26 | $ pip3 install foliantcontrib.dbdoc foliantcontrib.slate, foliantcontrib.plantuml 27 | ``` 28 | 29 | We are going to use [Slate](https://github.com/slatedocs/slate/) for building a static website with documentation, so you will need to [install Slate dependencies](https://github.com/slatedocs/slate/wiki/Using-Slate-Natively). 30 | 31 | Finally, [Install PlantUML](https://plantuml.com/ru/starting), we will need it to draw the database scheme. 32 | 33 | ## Creating project 34 | 35 | Let’s create a Foliant project for our experiments. `cd` to the directory where you want your project created and run the `init` command: 36 | 37 | ```bash 38 | $ cd ~/foliant_projects 39 | $ foliant init 40 | Enter the project name: Database Docs 41 | Generating project... Done 42 | ──────────────────── 43 | Project "Database Docs" created in database-docs 44 | 45 | $ cd database-docs 46 | ``` 47 | 48 | The other option is to clone the [Foliant Project template](https://github.com/foliant-docs/foliant_project_template/) repository: 49 | 50 | ```bash 51 | $ cd ~/foliant_projects 52 | $ mkdir database-docs 53 | $ git clone https://github.com/foliant-docs/foliant_project_template.git database-docs 54 | Cloning into 'database-docs'... 55 | remote: Enumerating objects: 11, done. 56 | remote: Counting objects: 100% (11/11), done. 57 | remote: Compressing objects: 100% (7/7), done. 58 | remote: Total 11 (delta 1), reused 11 (delta 1), pack-reused 0 59 | Unpacking objects: 100% (11/11), done. 60 | $ cd database-docs 61 | ``` 62 | 63 | ## Setting up project 64 | 65 | Now it’s time to set up our config. Open `foliant.yml` and add the following lines: 66 | 67 | ```diff 68 | title: Database Docs 69 | 70 | chapters: 71 | - index.md 72 | 73 | +preprocessors: 74 | + - dbdoc: 75 | + dbms: pgsql 76 | + host: localhost 77 | + port: 5432 78 | + dbname: posgres 79 | + user: posgres 80 | + password: posgres 81 | + - plantuml 82 | + 83 | ``` 84 | 85 | Make sure to use proper credentials for your PostgreSQL database. If you are running Foliant from docker, you can use `host: host.docker.internal` to access `localhost` from docker. 86 | 87 | > Note: if plantuml is not available under `$ plantuml` in your system, you will also need to specify path to platnum.jar in preprocessor settings like this: 88 | > 89 | > ```yaml 90 | > - plantuml: 91 | > plantuml_path: /usr/bin/plantuml.jar 92 | > ``` 93 | 94 | Finally, we need to point Foliant the place in the Markdown source files where the generated documentation should be inserted. Since we already have an `index.md` chapter created for us by `init` command, let’s put it in there. Open `src/index.md` and make it look like this: 95 | 96 | ```diff 97 | # Welcome to Database Docs 98 | 99 | -Your content goes here. 100 | + 101 | + 102 | ``` 103 | 104 | ## Building site 105 | 106 | All preparations done, let’s build our site: 107 | 108 | ``` 109 | $ foliant make site -w slate 110 | Parsing config... Done 111 | Applying preprocessor dbdoc... Done 112 | Applying preprocessor plantuml... Done 113 | Applying preprocessor flatten... Done 114 | Applying preprocessor _unescape... Done 115 | Making site... Done 116 | ... 117 | ──────────────────── 118 | Result: Database_Docs-2020-06-03.slate/ 119 | ``` 120 | 121 | If you are using Docker, the command is: 122 | 123 | ``` 124 | $ docker-compose run --rm foliant make site -w slate 125 | ``` 126 | 127 | Now open `Database_Docs-2020-06-03.slate/index.html` and look what you’ve got: 128 | 129 | ![](img/oracle.png) 130 | 131 | That looks good enough, but you may want to tweak the appearance of your site. You can edit the Jinja-template to change the way DBDoc generates markdown out of your schema. The default template can be found [here](https://github.com/foliant-docs/foliantcontrib.dbdoc/blob/master/foliant/preprocessors/dbdoc/pgsql/templates/doc.j2). Edit it and save in your project dir, then specify in the `doc_template` parameter. If you want to change the looks of your site, please, refer for instructions in Slate backend documentation. 132 | -------------------------------------------------------------------------------- /src/tutorials/db/dbml.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - tutorial 4 | - database 5 | --- 6 | 7 | # Documenting DBML schema 8 | 9 | Quote from the official website: *[DBML](https://dbml.org/) (Database Markup Language) is an open-source DSL language designed to define and document database schemas and structures. It is designed to be simple, consistent and highly-readable.* And that makes it a perfect choice for the designing stage of your database. You can create your table structure without messing with cumbersome SQL in a more readible way like this: 10 | 11 | ```sql 12 | Table users { 13 | id integer 14 | username varchar 15 | role varchar 16 | created_at timestamp 17 | } 18 | 19 | Table posts { 20 | id integer [primary key] 21 | title varchar 22 | body text [note: 'Content of the post'] 23 | user_id integer 24 | status post_status 25 | created_at timestamp 26 | } 27 | 28 | Enum post_status { 29 | draft 30 | published 31 | private [note: 'visible via URL only'] 32 | } 33 | 34 | Ref: posts.user_id > users.id // many-to-one 35 | ``` 36 | 37 | As you may have noticed, DBML also has tools to document pieces of you schema using *notes* (`body text [note: 'Content of the post']`) and comments (`Ref: posts.user_id > users.id // many-to-one`). 38 | 39 | So how can we convert DBML schema descriptions into a human-readible document? The idea is pretty simple: we parse the DBML definitions and pass them to a Jinja template, which renders markdown for us. After that we use one of our backends (we will use Slate in this tutorial) to build a static site out of it. 40 | 41 | We won’t need to do it all manually, of course, we just need to configure Foliant to do it for us. 42 | 43 | ## Installing prerequisites 44 | 45 | If you are running Foliant natively, you will need to install some prerequisites. But if you are working with our Full Foliant Docker image, you don’t need to do that, just skip to the next stage. 46 | 47 | First you will need Foliant, of course. If you don’t have it yet, please, refer to the installation guide. 48 | 49 | Install DBMLDoc and PlantUML preprocessors, and the Slate backend: 50 | 51 | ```bash 52 | $ pip3 install foliantcontrib.dbmldoc foliantcontrib.slate, foliantcontrib.plantuml 53 | ``` 54 | 55 | We are going to use Slate for building a static website with documentation, so you will also need to [install Slate dependencies](https://github.com/slatedocs/slate/wiki/Using-Slate-Natively). 56 | 57 | Finally, [install PlantUML](https://plantuml.com/ru/starting), we will need it to draw database scheme. 58 | 59 | ## Creating project 60 | 61 | Let’s create a Foliant project for our experiments. `cd` into the directory where you want your project created and run the `init` command: 62 | 63 | ```bash 64 | $ cd ~/foliant_projects 65 | $ foliant init 66 | Enter the project name: Database Docs 67 | Generating project... Done 68 | ──────────────────── 69 | Project "Database Docs" created in database-docs 70 | 71 | $ cd database-docs 72 | ``` 73 | 74 | The other option is to clone the [Foliant Project template](https://github.com/foliant-docs/foliant_project_template/) repository: 75 | 76 | ```bash 77 | $ cd ~/foliant_projects 78 | $ mkdir database-docs 79 | $ git clone https://github.com/foliant-docs/foliant_project_template.git database-docs 80 | Cloning into 'database-docs'... 81 | remote: Enumerating objects: 11, done. 82 | remote: Counting objects: 100% (11/11), done. 83 | remote: Compressing objects: 100% (7/7), done. 84 | remote: Total 11 (delta 1), reused 11 (delta 1), pack-reused 0 85 | Unpacking objects: 100% (11/11), done. 86 | $ cd database-docs 87 | ``` 88 | 89 | Next, let’s download the sample DBML spec and save it into `schema.dbml` in the root your Foliant project: 90 | 91 | ```bash 92 | $ wget https://raw.githubusercontent.com/holistics/dbml/master/packages/dbml-core/__tests__/parser/dbml-parse/input/general_schema.in.dbml -O schema.dbml 93 | ``` 94 | 95 | ## Setting up project 96 | 97 | Now it’s time to set up our config. Open `foliant.yml` and add the following lines: 98 | 99 | ```diff 100 | title: Database Docs 101 | 102 | chapters: 103 | - index.md 104 | 105 | +preprocessors: 106 | + - dbmldoc: 107 | + spec_path: !path schema.dbml 108 | + - plantuml 109 | + 110 | ``` 111 | 112 | We’ve added the PlantUML and DBMLDoc preprocessors to the pipeline and specified path to our DBML sample schema. DBMLDoc will parse the schema and convert it into Markdown, plantuml will draw the visual diagram of our DB schema. 113 | 114 | > Note: if plantuml is not available under `$ plantuml` in your system, you will also need to specify path to plantuml.jar in preprocessor settings like this: 115 | > 116 | > ```yaml 117 | > - plantuml: 118 | > plantuml_path: /usr/bin/plantuml.jar 119 | > ``` 120 | 121 | Finally, we need to point Foliant the place in the Markdown source files where the generated documentation should be inserted. Since we already have an `index.md` chapter created for us by `init` command, let’s put it in there. Open `src/index.md` and make it look like this: 122 | 123 | ```diff 124 | # Welcome to Database Docs 125 | 126 | -Your content goes here. 127 | + 128 | + 129 | ``` 130 | 131 | ## Building site 132 | 133 | All preparations are finished, let’s build our site: 134 | 135 | ``` 136 | $ foliant make site -w slate 137 | Parsing config... Done 138 | Applying preprocessor dbmldoc... Done 139 | Applying preprocessor plantuml... Done 140 | Applying preprocessor flatten... Done 141 | Applying preprocessor _unescape... Done 142 | Making site... Done 143 | ... 144 | ──────────────────── 145 | Result: Database_Docs-2020-06-03.slate/ 146 | ``` 147 | 148 | If you are using Docker, the command is: 149 | 150 | ``` 151 | $ docker-compose run --rm foliant make site -w slate 152 | ``` 153 | 154 | Now open `Database_Docs-2020-06-03.slate/index.html` and look at the results: 155 | 156 | ![](img/dbml.png) 157 | 158 | That looks good enough, but you may want to tweak the appearance of your site. You can edit the Jinja-template to change the way DBMLDoc generates markdown out of your schema. After the first build, the default template should have appeared in your project dir under the name `dbml.j2`. If you want to change the looks of you site, please, refer to the instructions in Slate backend documentation. 159 | -------------------------------------------------------------------------------- /src/architecture.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - overview 4 | - architecture 5 | --- 6 | 7 | # Architecture And Basic Design Concepts 8 | 9 | ## Overview 10 | 11 | Foliant is an open-source application written in Python. 12 | 13 | [![Overview of Foliant Architecture](images/architecture-overview.png)](https://raw.githubusercontent.com/foliant-docs/docs/master/src/images/architecture-overview.png) 14 | 15 | Foliant has a modular architecture. It consists of three layers: 16 | 17 | * **Configuration Layer** reads Foliant project configuration file and CLI parameters supplied by the user; 18 | * **Preprocessing Layer** adjusts the Markdown sources before the build; 19 | * **Build Layer** produces the documentation in the final format. 20 | 21 | Each layer is supervised by [Foliant Core](https://github.com/foliant-docs/foliant/). *Foliant Core* is a relatively compact and rarely updated Python package. It is a dispatcher which manages installed extensions according to the configuration. 22 | 23 | Let's take a closer look at each layer of Foliant's architecture. 24 | 25 | [![Architecture of Foliant](images/architecture-detailed.png)](https://raw.githubusercontent.com/foliant-docs/docs/master/src/images/architecture-detailed.png) 26 | 27 | ### Configuration Layer 28 | 29 | At the configuration Layer, Foliant processes the CLI-command and reads the command arguments, which were supplied by the user. The Main Foliant command is `make`, it is the command which builds the documentation project. But there are other commands which may do other things, for example, display the project's metadata (the `meta generate` command) or generate a new project file structure (the `init` command). 30 | 31 | If `make` command was used, Foliant reads and processes the project configuration file. At this stage, all installed Configuration Extensions are applied to the project config. 32 | 33 | ### Preprocessing Layer 34 | 35 | At the preprocessing layer, Foliant runs the Preprocessor Pipeline, that was defined in the config. Each preprocessor is applied to the Markdown source in the specified order. Preprocessors may: 36 | 37 | - call external services, for example, get data from a Swagger API website or an SQL Database; 38 | - use local files, for example, templates for text generation, or Markdown snippets for content reuse; 39 | - call external tools, for example, PlantUML to generate diagrams from code, or ImageMagick to resize images. 40 | 41 | Finally, the preprocessor may not use any external services or local files, but do the processing itself. For example, perform auto-replace in the text or generate a glossary for the terms in the project. 42 | 43 | ### Build Layer 44 | 45 | At the build layer, Foliant runs the Backend, which was specified in the `make` command parameters. The Backend produces the documentation in the final format. It may be a local file like PDF or a directory with static website contents, or the Backend may upload the result to an external service like Confluence. 46 | 47 | ## Foliant Extensions 48 | 49 | As was mentioned above, the main Foliant package is Foliant Core. But Foliant Core itself does not build documentation projects, instead it delegates this job to extensions. The Core package also defines base classes for all types of extensions. 50 | 51 | There are 4 types of base Foliant extensions. 52 | 53 | * **CLI extensions** extend Foliant’s command-line interface and provide additional actions that may be called from the command line. This is always the topmost component of any Foliant's action. *foliant* ***make*** is in fact a CLI extension that builds projects. 54 | * **Config extensions** allow to customize the project configuration parsing, add custom YAML tags and new configuration options. For example, MultiProject extension adds a YAML tag `!from` which allows to include multiple nested Foliant projects into a single parent project. 55 | * **Preprocessors** are modules which apply various transformations to the source Markdown content before passing it to a backend. The transformations include: 56 | 57 | * replacing parts of content according to specific rules; 58 | * rendering diagrams and schemes from source code; 59 | * embedding content from external files; 60 | * getting data for your documentation project from external services, e.g. remote Git repositories, Swagger, Testrail, Figma, Sympli, SQL Databases etc.; 61 | * seting high-level semantic relations between different parts of content to provide smart cross-target links, or restructure single-source documentation automatically and context-dependently; 62 | * running arbitrary external commands. 63 | 64 | Each Foliant project may use any number of preprocessors. Preprocessors are applied sequentially, one after another. The same preprocessor may appear more than once in the pipeline. 65 | * **Backends** build the project's Markdown content into final formats which we call *targets*, e.g. PDF files or static sites. Backends may call third-party software to produce the final documentation or upload your content to an external service, e.g. Confluence. A single backend may generate multiple targets. Different backends may build the same target. For example, a static site (the `site` target) can be built with 3 official backends: MkDocs, Slate, and Aglio. If several of them are installed, user may specify the certain backend in the `foliant make` command or it will be asked interactively. 66 | 67 | 68 | ## Project Build Process 69 | 70 | The project build process is operated by Foliant CLI extension called *make*, which is a part of Foliant Core package. 71 | 72 | **The steps of the build process** 73 | 74 | 1. User calls a `make` command specifying the backend and the target he wants to build, for example: 75 | 76 | $ foliant make site --with mkdocs 77 | 78 | In this example, the target is `site` and the backend is `mkdocs`. `--with` argument is optional, `make` will assume the backend or ask for user input if there are several options for the target. 79 | 80 | 2. `make` launches the project build in the following stages: 81 | 1. **Configuration parsing**. The project configuration file (`foliant.yml` by default) is processed by each installed *Config extension* and saved into the internal context. 82 | 2. **Copying sources**. The `src` folder which holds Markdown source files of the project is copied into a temporary folder (`__folianttmp__` by default). Preprocessors will only affect the copies, leaving the sources intact. 83 | 3. **Preprocessing**. Each *preprocessor* defined in the project configuration file is subsequently applied to the temporary folder with copies of Markdown sources. The preprocessors run in an order in which they are specified in the `preprocessors` list, but each backend may implicitly add specific preprocessors to the beginning or the end of this list. 84 | 4. **Producing output format**. The chosen *backend* takes the Markdown files from the temporary folder and converts them into the target format. 85 | 5. **Removing temporary files**. If `make` wasn't run with `--keep-tmp|-k` argument, the temporary folder with preprocessed Markdown sources is removed from the project dir. 86 | -------------------------------------------------------------------------------- /src/tutorials/db/oracle.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - tutorial 4 | - database 5 | --- 6 | 7 | # Documenting Oracle Database 8 | 9 | > Please note that in this article covers only the basic usage of the tools. For detailed information on features and customizing output refer to each component’s docs. 10 | 11 | 12 | ## Installing prerequisites 13 | 14 | First you will need to install some prerequisites. If you are running Foliant natively, follow the guide below. If you are working with our Full Docker image, you will just need the last paragraph in this section. 15 | 16 | First, you will need Foliant, of course. If you don’t have it yet, please, refer to the installation guide. 17 | 18 | Install Python connector for Oracle database. 19 | 20 | ```bash 21 | $ pip3 install cx_Oracle 22 | ``` 23 | 24 | Install DBDoc and PlantUML preprocessors, and the Slate backend: 25 | 26 | ```bash 27 | $ pip3 install foliantcontrib.dbdoc foliantcontrib.slate, foliantcontrib.plantuml 28 | ``` 29 | 30 | We are going to use Slate for building a static website with documentation, so you will need to [install Slate dependencies](https://github.com/slatedocs/slate/wiki/Using-Slate-Natively). 31 | 32 | [Install PlantUML](https://plantuml.com/ru/starting), we will need it to draw the database scheme. 33 | 34 | docker_oracle 35 | 36 | Install [Oracle Instant Client](https://www.oracle.com/database/technologies/instant-client.html) if you don’t have it. We will need it to query the database. 37 | 38 | If you are using Docker, you will need to add Oracle Instant Client to your image. Since it is a proprietary software, we cannot include it in our Full Docker Image. But you can do it yourself. Our image is based on Ubuntu, so you can find instructions on how to install Oracle Instant Client on Ubuntu (spoiler: it’s not that easy) and add those commands into the Dockerfile, or just find those commands made by someone else. For example, from this [Dockerfile by Sergey Makinen](https://github.com/sergeymakinen/docker-oracle-instant-client/blob/master/12.2/Dockerfile). Copy all commands starting from the third line into your `Dockerfile` and run `docker-compose build` to rebuild the image. 39 | 40 | 41 | ??? "For the sake of reliability another variant of the Oracle-ready `Dockefile` is provided below:" 42 | 43 | ```Dockerfile 44 | FROM foliant/foliant:full 45 | 46 | RUN pip3 install cx_Oracle 47 | 48 | ENV DEBIAN_FRONTEND noninteractive 49 | 50 | ENV ORACLE_INSTANTCLIENT_MAJOR 21 51 | ENV ORACLE /usr/local/oracle 52 | ENV ORACLE_HOME $ORACLE/lib/oracle/$ORACLE_INSTANTCLIENT_MAJOR/client64 53 | ENV LD_LIBRARY_PATH $LD_LIBRARY_PATH:$ORACLE_HOME/lib 54 | ENV C_INCLUDE_PATH $C_INCLUDE_PATH:$ORACLE/include/oracle/$ORACLE_INSTANTCLIENT_MAJOR/client64 55 | 56 | RUN apt-get update && apt-get install -y libaio1 \ 57 | curl rpm2cpio cpio \ 58 | && mkdir $ORACLE && TMP_DIR="$(mktemp -d)" && cd "$TMP_DIR" \ 59 | && curl -L https://download.oracle.com/otn_software/linux/instantclient/218000/oracle-instantclient-basic-21.8.0.0.0-1.el8.x86_64.rpm -o basic.rpm \ 60 | && rpm2cpio basic.rpm | cpio -i -d -v && cp -r usr/* $ORACLE && rm -rf ./* \ 61 | && ln -s libclntsh.so.12.1 $ORACLE/lib/oracle/$ORACLE_INSTANTCLIENT_MAJOR/client64/lib/libclntsh.so.$ORACLE_INSTANTCLIENT_MAJOR \ 62 | && ln -s libocci.so.12.1 $ORACLE/lib/oracle/$ORACLE_INSTANTCLIENT_MAJOR/client64/lib/libocci.so.$ORACLE_INSTANTCLIENT_MAJOR \ 63 | && echo "$ORACLE_HOME/lib" > /etc/ld.so.conf.d/oracle.conf && chmod o+r /etc/ld.so.conf.d/oracle.conf && ldconfig \ 64 | && rm -rf /var/lib/apt/lists/* && apt-get purge -y --auto-remove curl rpm2cpio cpio 65 | ``` 66 | 67 | ## Creating project 68 | 69 | Let’s create a Foliant project for our experiments. `cd` to the directory where you want your project created and run the `init` command: 70 | 71 | ```bash 72 | $ cd ~/foliant_projects 73 | $ foliant init 74 | Enter the project name: Database Docs 75 | Generating project... Done 76 | ──────────────────── 77 | Project "Database Docs" created in database-docs 78 | 79 | $ cd database-docs 80 | ``` 81 | 82 | The other option is to clone the [Foliant Project template](https://github.com/foliant-docs/foliant_project_template/) repository: 83 | 84 | ```bash 85 | $ cd ~/foliant_projects 86 | $ mkdir database-docs 87 | $ git clone https://github.com/foliant-docs/foliant_project_template.git database-docs 88 | Cloning into 'database-docs'... 89 | remote: Enumerating objects: 11, done. 90 | remote: Counting objects: 100% (11/11), done. 91 | remote: Compressing objects: 100% (7/7), done. 92 | remote: Total 11 (delta 1), reused 11 (delta 1), pack-reused 0 93 | Unpacking objects: 100% (11/11), done. 94 | $ cd database-docs 95 | ``` 96 | 97 | ## Setting up project 98 | 99 | Now it’s time to set up our config. Open `foliant.yml` and add the following lines: 100 | 101 | ```diff 102 | title: Database Docs 103 | 104 | chapters: 105 | - index.md 106 | 107 | +preprocessors: 108 | + - dbdoc: 109 | + dbms: oracle 110 | + host: localhost 111 | + port: 1521 112 | + dbname: orcl 113 | + user: hr 114 | + password: oracle 115 | + - plantuml 116 | + 117 | ``` 118 | 119 | Make sure to use proper credentials for your Oracle database. If you are running Foliant from docker, you can use `host: host.docker.internal` to access `localhost` from docker. 120 | 121 | > Note: if plantuml is not available under `$ plantuml` in your system, you will also need to specify path to platnum.jar in preprocessor settings like this: 122 | > 123 | > ```yaml 124 | > - plantuml: 125 | > plantuml_path: /usr/bin/plantuml.jar 126 | > ``` 127 | 128 | Finally, we need to point Foliant the place in the Markdown source files where the generated documentation should be inserted. Since we already have an `index.md` chapter created for us by `init` command, let’s put it in there. Open `src/index.md` and make it look like this: 129 | 130 | ```diff 131 | # Welcome to Database Docs 132 | 133 | -Your content goes here. 134 | + 135 | + 136 | ``` 137 | 138 | ## Building site 139 | 140 | All preparations done, let’s build our site: 141 | 142 | ``` 143 | $ foliant make site -w slate 144 | Parsing config... Done 145 | Applying preprocessor dbdoc... Done 146 | Applying preprocessor plantuml... Done 147 | Applying preprocessor flatten... Done 148 | Applying preprocessor _unescape... Done 149 | Making site... Done 150 | ... 151 | ──────────────────── 152 | Result: Database_Docs-2020-06-03.slate/ 153 | ``` 154 | 155 | If you are using Docker, the command is: 156 | 157 | ``` 158 | $ docker-compose run --rm foliant make site -w slate 159 | ``` 160 | 161 | Now open `Database_Docs-2020-06-03.slate/index.html` and look what you’ve got: 162 | 163 | ![](img/oracle.png) 164 | 165 | That looks good enough, but you may want to tweak the appearance of your site. You can edit the Jinja-template to change the way DBDoc generates markdown out of your schema. The default template can be found [here](https://github.com/foliant-docs/foliantcontrib.dbdoc/blob/master/foliant/preprocessors/dbdoc/oracle/templates/doc.j2). Edit it and save in your project dir, then specify in the `doc_template` parameter. If you want to change the looks of your site, please, refer for instructions in Slate backend documentation. 166 | -------------------------------------------------------------------------------- /src/tutorials/preprocessor/generator.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - tutorial 4 | - preprocessor 5 | --- 6 | 7 | # Creating the Gibberish Generator 8 | 9 | There are already several Python packages present on PyPi which generate placeholder texts like [loremipsum](https://github.com/monkeython/loremipsum) but we won't deprive ourselves of the fun of creating our own. 10 | 11 | Let's define some requirements: 12 | 13 | - The generated text should consist of sentences that start with a capital letter and end with a dot. 14 | - There should be a way of controlling the size of the sentence and the number of sentences in the resulting text. 15 | - The words in the text should have at least a slight resemblance with real language words. 16 | 17 | The last requirement is a bit tricky: we don't want words like `q` or `zxd` in our text, or at least not too many of those, so that the text looks a bit more real. So what we will do is create a simple `gen_word` function which will generate a word with a random number of letters, but the letters will be picked in a more controlled way by another function called `pick_letter`: 18 | 19 | ```python 20 | from random import randint 21 | 22 | def gen_word(): 23 | word_len = randint(2, 9) # [1] 24 | return ''.join(pick_letter() for _ in range(word_len)) # [2] 25 | ``` 26 | 27 | 1. We've restricted the length of the words to 2 to 9 letters so we could avoid too short and too long words. 28 | 2. The `pick_letter` function will be supplying us with random letters. 29 | 30 | Now to the `pick_letter` function. To make the words look real we don't want this function to return too many of the letters q, w, x and z, which don't appear in the words often. We also want to get more vowels than consonants: `kiobe` looks more like a word than `lknsd`. 31 | 32 | Here's one way to do it 33 | 34 | ```python 35 | from random import choice, random 36 | 37 | def pick_letter(): 38 | rare_letters = 'qwxz' 39 | vowels = 'aeiouy' 40 | consonants = 'cdfghjklmnprstv' 41 | 42 | pick = random() # [1] 43 | if pick > 0.9: # [2] 44 | return choice(rare_letters) # [3] 45 | elif pick > 0.25: # [4] 46 | return choice(vowels) # [5] 47 | else: 48 | return choice(consonants) # [6] 49 | ``` 50 | 51 | 1. Get a random float number from the [`random`](https://docs.python.org/3/library/random.html#random.random) function. 52 | 2. Since `random` returns a float from 0.0 to 1.0, there's about a 10% chance of getting a float that is larger than 0.9. 53 | 3. In this case, we will randomly pick one of the rare letters: q, w, x, or z with the [`choice`](https://docs.python.org/3/library/random.html#random.choice) function. 54 | 4. The chance of getting a float between 0.25 and 0.9 is about 65%. 55 | 5. In this case, we will return a vowel. 56 | 6. Finally, with a chance of about 25%, we will be returning one of the remaining consonants. 57 | 58 | Let's put it all together and test our `gen_word` function 59 | 60 | ```python 61 | >>> gen_word() 62 | 'eojuo' 63 | >>> gen_word() 64 | 'soe' 65 | >>> gen_word() 66 | 'qwiim' 67 | >>> gen_word() 68 | 'itookao' 69 | ``` 70 | 71 | Oh my god, I think we've just created the Finnish language! Jokes aside, it seems that our words generator works fine. 72 | 73 | Now we need to create functions for generating sentences and putting them together in a text. 74 | 75 | ```python 76 | def gen_sentence(num_words=7): # [1] 77 | words = (gen_word() for _ in range(num_words)) # [2] 78 | return ' '.join(words).capitalize() # [3] 79 | ``` 80 | 81 | 1. The number of words in the sentence is determined by the `num_words` parameter with a sensible default of 7 words. 82 | 2. Creating a [generator](https://docs.python.org/3/reference/expressions.html#generator-expressions) that will yield a new word a required number of times. 83 | 3. Joining the generated words into a single string, separated by spaces. We are also making the first word capitalized in our sentence. 84 | 85 | A quick test to make sure it works 86 | 87 | ```python 88 | >>> gen_sentence() 89 | 'Oveecyyi tukzgoli zvo uqyi ujiffrl viivu odui' 90 | >>> gen_sentence(3) 91 | 'Ioyieyug ie hkeepnyo' 92 | ``` 93 | 94 | And now to the whole text generator 95 | 96 | ```python 97 | def gen_text(num_sentences=10): # [1] 98 | sizes = (randint(3, 12) for _ in range(num_sentences)) # [2] 99 | sentences = (gen_sentence(size) for size in sizes) # [3] 100 | return '. '.join(sentences) + '.' # [4] 101 | ``` 102 | 103 | 1. The text generator will accept one parameter `num_sentences` with a default of 10. 104 | 2. Creating a generator that will yield a number of words in each sentence a required number of times. We are limiting the sentence size here to 3 to 12 words. 105 | 3. Creating a generator that will yield a new sentence a required number of times. 106 | 4. Joining the generated sentences into a single string, separated by dots. We are also adding a dot at the end of the text. 107 | 108 | Time for the final test! 109 | 110 | ```python 111 | >>> gen_text() 112 | 'Eeaidmt cznm aeoiemino ivjuyauq exieh aoioayif yavfkoa tasojm xuz qizxiyum iyoi fajo. Anuipcauo uac eunjtou oiy hougqf tulztiawk qooulu eiewewaii. Lxi isoxuau ooovox wtopuodu oom ougvoeyy ou calxja io reicye yaioyzx. Usmyuavq yoyu xioqei iiu ateuyau yeroueut gucuifuth tiazkkgc. Oyqzuy rnzouq ajiof qaxewxufo. Utiselorc qpoaoydoi kyvyiuao ofxaoiy ueyaoi azdacy lieaiiy au vteccye. Lopgygsz efixuio gi eyzeuxoa eea qwaycx impoetvy eoyijaum uoiighcq lyaxa xy. Yo yazd oio yyn gvyifzaeo eyz iewueuqze yy yeadvtx dqmdiy. Agiiorixk yae tvmu eeeoe aqjy eqnsouejn. Szejaae yl vuoaewt aujc nvkols auokud reaqopae.' 113 | >>> gen_text(2) 114 | 'Uyayu xpriicoe usao yua duleekayi loqk iop saiy iuys sciyaihs. Onacrtog ual iei nuuoaz gdgia yyoui.' 115 | ``` 116 | 117 | Our gibberish generator turned out quite decent. Now it's time to make it a Foliant preprocessor. 118 | 119 | 120 | ??? example "Complete source of the generator module" 121 | ```python 122 | from random import choice 123 | from random import randint 124 | from random import random 125 | 126 | 127 | def pick_letter() -> str: 128 | """ 129 | Pick a random letter. 130 | Vowels have a higher chance of picking. 131 | Letters q, w, x and z have the lowest chance of picking. 132 | """ 133 | 134 | rare_letters = 'qwxz' 135 | vowels = 'aeiouy' 136 | consonants = 'cdfghjklmnprstv' 137 | 138 | pick = random() 139 | if pick > 0.9: 140 | return choice(rare_letters) 141 | elif pick > 0.3: 142 | return choice(vowels) 143 | else: 144 | return choice(consonants) 145 | 146 | def gen_word() -> str: 147 | """Return a word consisting of 2 to 9 letters.""" 148 | word_len = randint(2, 9) 149 | return ''.join(pick_letter() for _ in range(word_len)) 150 | 151 | 152 | def gen_sentence(num_words: int = 7) -> str: 153 | """Generate a sentence consisting of `num_words` words.""" 154 | words = (gen_word() for _ in range(num_words)) 155 | return ' '.join(words).capitalize() 156 | 157 | 158 | def gen_text(num_sentences: int = 10) -> str: 159 | """ 160 | Generate a paragraph of gibberish consisting of `num_sentences` 161 | senteces, each consisting of 3 to 12 words. 162 | """ 163 | 164 | sizes = (randint(3, 12) for _ in range(num_sentences)) 165 | sentences = (gen_sentence(size) for size in sizes) 166 | return '. '.join(sentences) + '.' 167 | ``` 168 | 169 | 170 | Next: 171 | 172 | Previous: 173 | -------------------------------------------------------------------------------- /src/tutorials/preprocessor/install.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - tutorial 4 | - preprocessor 5 | --- 6 | 7 | # Installing and Testing 8 | 9 | Right now our preprocessor folder looks like this. 10 | 11 | ```bash 12 | $ tree 13 | . 14 | └── foliant 15 | └── preprocessors 16 | └── gibberish.py 17 | 18 | 2 directories, 1 file 19 | ``` 20 | 21 | To make it an installable Python package we need to add a `setup.py` file to the root folder. 22 | 23 | Here's an [article on creating setup files](https://docs.python.org/3/distutils/setupscript.html) from the official docs. Usually, we just take one of the `setup.py`s from an existing preprocessor as a template or use this official Foliant [snippet](https://github.com/foliant-docs/foliantcontrib.templates.preprocessor/blob/develop/setup.py). 24 | 25 | Here's what your `setup.py` may look like. 26 | 27 | ```python 28 | from setuptools import setup 29 | 30 | 31 | SHORT_DESCRIPTION = 'Gibberish preprocessor for Foliant.' # [*] 32 | 33 | try: 34 | with open('README.md', encoding='utf8') as readme: 35 | LONG_DESCRIPTION = readme.read() 36 | 37 | except FileNotFoundError: 38 | LONG_DESCRIPTION = SHORT_DESCRIPTION 39 | 40 | 41 | setup( 42 | name='foliantcontrib.gibberish', # [*] 43 | description=SHORT_DESCRIPTION, 44 | long_description=LONG_DESCRIPTION, 45 | long_description_content_type='text/markdown', 46 | version='1.0.0', 47 | author='Simon Garfunkel', # [*] 48 | author_email='simong@example.com', # [*] 49 | url='https://github.com/foliant-docs/foliantcontrib.gibberish', # [*] 50 | packages=['foliant.preprocessors'], 51 | license='MIT', 52 | platforms='any', 53 | install_requires=[ 54 | 'foliant>=1.0.8', 55 | ], 56 | classifiers=[ 57 | "Development Status :: 5 - Production/Stable", 58 | "Environment :: Console", 59 | "Intended Audience :: Developers", 60 | "License :: OSI Approved :: MIT License", 61 | "Operating System :: OS Independent", 62 | "Programming Language :: Python", 63 | "Topic :: Documentation", 64 | "Topic :: Utilities", 65 | ] 66 | ) 67 | ``` 68 | 69 | Lines marked with asterisks you would probably want to change to suit your preprocessor. Also, note that we referred to the contents of the `README.md` as the full description of the package. It's a good time to add a readme for your preprocessor. Explain what your preprocessor does and what options it has. You may use one of the official preprocessors for possible readme structure. 70 | 71 | Now the folder structure should look like this 72 | 73 | ```bash 74 | $ tree 75 | . 76 | ├── foliant 77 | │ └── preprocessors 78 | │ └── gibberish.py 79 | ├── README.md 80 | └── setup.py 81 | 82 | 2 directories, 3 files 83 | ``` 84 | 85 | Time to test if the preprocessor actually works. First, install it by running this command inside the preprocessor folder. 86 | 87 | ```bash 88 | $ pip3 install . 89 | ``` 90 | 91 | Create an empty Foliant project using the `init` command: 92 | 93 | ```bash 94 | $ foliant init # creating the empty project 95 | Enter the project name: Gibberish Test 96 | Generating project... Done 97 | ──────────────────── 98 | Project "Gibberish Test" created in gibberish-test 99 | $ cd gibberish-test # entering the created project folder 100 | $ tree # inspecting the project file structure 101 | . 102 | ├── docker-compose.yml 103 | ├── Dockerfile 104 | ├── foliant.yml 105 | ├── README.md 106 | ├── requirements.txt 107 | └── src 108 | └── index.md 109 | 110 | 1 directory, 6 files 111 | ``` 112 | 113 | First, let's add our preprocessor to the `foliant.yml`. 114 | 115 | ```diff 116 | title: Gibberish Test 117 | 118 | + preprocessors: 119 | + - gibberish 120 | + 121 | chapters: 122 | - index.md 123 | ``` 124 | 125 | Now let's edit the `index.md` and use the `` tag a few times. 126 | 127 | ```html 128 | # Welcome to Gibberish Test 129 | 130 | Here's some gibberish: 131 | 132 | 133 | 134 | Here are just two sentences of gibberish: 135 | 136 | 137 | ``` 138 | 139 | Let's build our project into the `pre` target. This target doesn't create a PDF or a DOCX, it just returns the preprocessed Markdown text, which perfectly suits our testing needs. 140 | 141 | ```bash 142 | $ foliant make pre 143 | Parsing config... Done 144 | Applying preprocessor gibberish... Done 145 | Applying preprocessor _unescape... Done 146 | ──────────────────── 147 | Result: Gibberish_Test-2021-08-16.pre 148 | ``` 149 | 150 | Inspect the results 151 | 152 | ``` 153 | $ cat Gibberish_Test-2021-08-16.pre/index.md 154 | # Welcome to Gibberish Test 155 | 156 | Here's some gibberish: 157 | 158 | Yxz izyuo sjo iir tewo qvqc etosaeeuo iecaizaso aaeoeuo iyey. Apavaiqfu eqaaa eecyo ioiiyuoay ah caou iets. Yooyofa iiynndea yiuqehlq uizu yca. Pi iuld ixuaeqei ousogp yu ushggxyq yiia uiuyjo. Ofoemct ciyfuup uufiy avkfeqa ehtjoj ietwohoo xqgif. Iwohqoeao snf uozlw qeasoqzu gevuywxui ou xypikyyqu on hrx. Ruagoisia ivga ovzho da oziazioic. Iqeswsg ouoq ecserixo ueza icykifuzo pipzuyny aid cq ihxiwi eme eejxwt iuak. Oui goido yduz eeyfahxil dyiya mezifeo iym xuuvyiy. Iii yucnyyyq eono qyqu uu ioo sqwcjuhip. 159 | 160 | Here are just two sentences of gibberish: 161 | 162 | Lof peuoy iiouy yyau qggedo evuoucaig. Pziqgsg ekiqepyu laeiridyc. 163 | ``` 164 | 165 | Looks like everything worked fine. Now let's set the `default_size` parameter to check if preprocessor options work too. Edit the `foliant.yml` 166 | 167 | ```diff 168 | title: Gibberish Test 169 | 170 | preprocessors: 171 | - - gibberish 172 | + - gibberish: 173 | + default_size: 1 174 | 175 | chapters: 176 | - index.md 177 | 178 | ``` 179 | 180 | And run the build 181 | 182 | ```bash 183 | $ foliant make pre 184 | Parsing config... Done 185 | Applying preprocessor gibberish... Done 186 | Applying preprocessor _unescape... Done 187 | ──────────────────── 188 | Result: Gibberish_Test-2021-08-16.pre 189 | ``` 190 | 191 | Now the first `` tag should be replaced with just one line of text. Let's check that 192 | 193 | ``` 194 | cat Gibberish_Test-2021-08-16.pre/index.md 195 | # Welcome to Gibberish Test 196 | 197 | Here's some gibberish: 198 | 199 | Jy si zhwtyu acneec qeugeya ax qqofaiu ydyyyxz. 200 | 201 | Here are just two sentences of gibberish: 202 | 203 | Wnuhocx uqny ns. Iu ieuiaea iogyjyfy kl eyyeex agayii aioaac yacjume. 204 | ``` 205 | 206 | Everything works as expected. Now you can add a `LICENSE` and a `changelog.md` to your preprocessor folder and publish it in GitHub and pypi, so that others could use your wonderful creation too! 207 | 208 | The repository with full code of Gibberish preprocessor is available [here](https://github.com/foliant-docs/preprocessor_tutorial). 209 | 210 | # Summary 211 | 212 | Now you know the basics of creating preprocessors for Foliant. But there's a lot more to learn! Study the code of different preprocessors created by our team to find out different approaches to solving techwriters' problems. Refer to the for all helper functions, classes and their attributes available for building Foliant extensions. 213 | 214 | When you get comfortable creating simple preprocessors you may find the [`utils` package](https://github.com/foliant-docs/foliantcontrib.utils) useful. It contains different tools which perform common tasks in preprocessors like [dealing with the `chapters` section](https://github.com/foliant-docs/foliantcontrib.utils/blob/master/docs/chapters.md) in foliant.yml or efficiently [combining options](https://github.com/foliant-docs/foliantcontrib.utils/blob/master/docs/combined_options.md) from foliant.yml and XML tags. There's also a powerful [`BasePreprocessorExt` class](https://github.com/foliant-docs/foliantcontrib.utils/blob/master/docs/preprocessor_ext.md) which encapsulates some boilerplate code for your preprocessors and offers advanced tools for warnings output and more. 215 | 216 | That's all for now. We wish you luck in extending Foliant! Send us a message if you want your preprocessor included in the official Foliant docs. 217 | 218 | Previous: 219 | -------------------------------------------------------------------------------- /src/debugging_builds.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - overview 4 | - debug 5 | --- 6 | 7 | # Debugging Builds 8 | 9 | Building simple documentation projects with Foliant is usually straightforward. But Foliant is a powerful, customizable, and very flexible tool, capable of turning your most complex ideas into beautiful documents. If you understand exactly what you want to achieve, you can formalize it at the project config level, and Foliant will perform your task efficiently and precisely. 10 | 11 | But sometimes it is difficult to configure all preprocessors and backends properly in one go. Some settings are pretty subtle and some preprocessors are quite complicated. The order of applying the preprocessors matters. Some preprocessors may work unexpectedly when paired with others. Fetching data from external sources may also become a bottleneck. The list goes on. 12 | 13 | Fortunately, Foliant will not ask you to diagnose problems with the car engine without opening the hood. Foliant provides advanced diagnostic facilities such as: 14 | 15 | * detailed event logging in the debug mode; 16 | * the pre backend which does nothing, i.e. just returns the preprocessed Markdown; 17 | * an option to keep the temporary working directory for further analysis. 18 | 19 | ## Notes on Docker Use 20 | 21 | In practice, Foliant is more commonly used with Docker. 22 | 23 | Here's a tip for debugging Foliant projects with docker. 24 | 25 | It’s useful to add one more service to your project's default `docker-compose.yml`. We will call it `bash` and it will run containers with an interactive shell: 26 | 27 | ```yml 28 | version: '3' 29 | 30 | services: 31 | foliant: 32 | build: 33 | context: ./ 34 | dockerfile: ./Dockerfile 35 | volumes: 36 | - ./:/usr/src/app/ 37 | bash: 38 | build: 39 | context: ./ 40 | dockerfile: ./Dockerfile 41 | volumes: 42 | - ./:/usr/src/app/ 43 | entrypoint: /bin/bash 44 | ``` 45 | 46 | Now you can run a container based on the project’s image with an interactive shell. To open the shell for root, run: 47 | 48 | ```bash 49 | $ docker-compose run --rm bash 50 | ``` 51 | 52 | To open shell for a user with the same user ID and group ID as your current user on the host machine: 53 | 54 | ```bash 55 | $ docker-compose run --user="$(id -u):$(id -g)" --rm bash 56 | ``` 57 | 58 | All debugging approaches which we will discuss next are represented as native Foliant commands, but they are applicable for the Docker way too. Just start your commands with `docker-compose run --rm ` or `docker-compose run --user="$(id -u):$(id -g)" --rm ` to run them within Docker containers. 59 | 60 | ## Logging 61 | 62 | The `foliant make ...` command runs Foliant in the regular logging mode. In this mode, Foliant and its extensions will only log events with levels of `critical`, `error`, and `warning`. Note that some preprocessors may generate a lot of specific warnings which may or may not indicate that something went wrong. These messages are usually worth studying anyway though. 63 | 64 | The new log file is created for each build, unless there were no errors and warnings. The logs are stored by default in the project root under the name `.log`, for example, `1628582527.log`. With such a naming convention the log file for the latest build will always be last in alphabetical order. The location of the log files may be customized by the `--logs|-l` command-line option. 65 | 66 | **Debugging Mode** 67 | debug_mode 68 | 69 | Foliant provides the `--debug` or `-d` command-line option which enables the debugging mode. In this mode, Foliant and its extensions log not just events with levels `critical`, `error` and `warning`, but also events with levels `debug` and `info`. The amount of information you will get from such events depends on the implementation of a particular extension. Complex preprocessors like Includes usually log their actions in great detail. The messages of the `info` level are usually informative: they may mark the beginning or end of some preprocessor’s work, for example. The messages of the `debug` level generally show the status of atomic operations, for example, reading data from a certain file. These messages often contain the values of the variables which are important in the current context: paths to files, external commands that are called, etc. But to make sense of these values prepare to get your hands dirty, or, in other words, read and understand the code of the corresponding extension. 70 | 71 | Here's an example of a command that tells Foliant to build PDF with Pandoc in debug mode: 72 | 73 | ```bash 74 | $ foliant make pdf --with pandoc --debug 75 | ``` 76 | 77 | Each log is a text file that contains a number of lines (records). Each record represents a single event and consists of 4 separate fields: 78 | 79 | * date and time of the event registration; 80 | * context (module name) in which the event was registered; 81 | * event log level: one of `CRITICAL`, `ERROR`, `WARNING`, `DEBUG`, `INFO`; 82 | * message text that explains the essence of the event. 83 | 84 | For example, the first record of a log usually looks like that: 85 | 86 | ``` 87 | 2020-06-25 09:40:54,419 | flt | INFO | Build started. 88 | ``` 89 | 90 | The string `flt` in the second field means Foliant itself (Foliant Core). 91 | 92 | The context is hierarchical. The following record represents an event that is registered in the Includes preprocessor which was implicitly called by the Flatten preprocessor, which was implicitly called during project build by Pandoc backend. 93 | 94 | ``` 95 | 2020-06-25 09:40:54,678 | flt.pandoc.flatten.includes | DEBUG | Processing Markdown file: /usr/src/app/__folianttmp__/__all__.md 96 | ``` 97 | 98 | In the next example, Pandoc backend logs the external command that is called to build needed target: 99 | 100 | ``` 101 | 2020-06-25 09:40:54,684 | flt.pandoc | DEBUG | PDF generation command: pandoc --template="/foliant_stuff/pandoc_templates/tex_templates/main.tex" --output "My_Awesome_Project-1.0-2020-06-25.pdf" --variable title="My Awesome Project" --variable version="1.0" --variable subtitle="Description Of My Awesome Project" --variable logo="/foliant_stuff/pandoc_templates/logos/logo.png" --variable year="2020" --variable title_page --variable toc --variable tof --pdf-engine=xelatex --listings -f markdown __folianttmp__/__all__.md 102 | ``` 103 | 104 | If you suspect that the command executes wrong, you can run it directly in an interactive shell and study the results. 105 | 106 | Detailed logging in debug mode allows you to quickly localize problems zooming in from Foliant itself to a specific Foliant extension, a specific Markdown source file, or a specific line of code. This takes effort but with practice allows one to solve complex problems in minimal time. 107 | 108 | ## Debugging extensions 109 | 110 | Each Foliant backend takes preprocessed Markdown content and passes it to an external command (see ). For debugging backends it's essential to see the content which the backend actually gets. 111 | 112 | During the build source files of Foliant project are copied to a temporary working directory. By default, it is called `__folianttmp__/` and located in the “root” directory of the project. Source Markdown files of the project are kept unchanged during the build. Any transformations are applied only to the files located in the temporary working directory. 113 | 114 | ### The pre backend 115 | 116 | Foliant Core provides the built-in backend `pre` which does nothing. More precisely, this backend makes the `pre` target. The `pre` target is obtained simply by copying the temporary working directory to a subdirectory inside the project root as the result of the build. 117 | 118 | The `pre` target is essentially the content that comes after all preprocessors are applied, but before any backend (other than `pre`) is called. 119 | 120 | **Determining the cause of the problem** 121 | 122 | `pre` backend is convenient to determine the stage of a build which causes problems: 123 | 124 | * configuration stage (reading the configuration file), 125 | * preprocessing stage (transforming the Markdown content with extensions) 126 | * or backend stage (producing the output format). 127 | 128 | If you build a `pre` target and the results seem fine, then there is a problem with your *backend* and you have to debug that. You may start with the keep-tmp which we will discuss next. 129 | 130 | If the problem persists in the results, produced by `pre`, then it's one of the preprocessors causing trouble or the configuration parser not working properly. In this case, it's a nice idea to stick with the `pre` target during your experiments so you won't need to wait each time for the backend to complete producing the target while you are debugging the build. 131 | 132 | To build a Foliant project to the `pre` target, run the command: 133 | 134 | ```bash 135 | $ foliant make pre 136 | ``` 137 | 138 | ### Keeping the project sources 139 | 140 | In addition to the `pre` backend, Foliant Core supports the `--keep_tmp` or `-k` command-line option. By default, the temporary working directory (`__folianttmp__`) is removed after the project build. But if the `--keep-tmp` or `-k` option is specified, the temporary working directory will stay in the project root after build. 141 | 142 | This directory will contain the files that are modified by all preprocessors and the chosen backend. 143 | 144 | If you have determined that the backend causes issues, pre won't help you anymore. Run the build with `-k` argument and study the working dir. If it seems fine, then the problem may be with the command that the backend runs to convert Markdown to a target format. Time to study logs! 145 | 146 | The following command tells Foliant to build PDF with Pandoc, keeping the temporary working directory after build: 147 | 148 | ```bash 149 | $ foliant make pdf --with pandoc --keep_tmp 150 | ``` 151 | 152 | 153 | 154 | ## Killing Two Birds With One Stone 155 | 156 | Now you know what debugging facilities are provided by Foliant. But we strongly recommend you make it a rule to start debugging Foliant projects with one universal shell command: 157 | 158 | ```bash 159 | $ foliant make pre --debug 160 | ``` 161 | 162 | This command tells Foliant to build the `pre` target in the debug mode. And this is a very effective way to get closer to understanding what is wrong with your project. 163 | -------------------------------------------------------------------------------- /src/tutorials/docker.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - tutorial 4 | --- 5 | 6 | # Running Foliant in Docker 7 | 8 | Foliant's design philosophy says that everybody should do what they do best. We don't aim to create a universal text processing combine which covers all needs of a technical writer by itself. Instead Foliant introduces integrations with different beautiful open source tools which specialize on a little chunk of work and do it perfectly. 9 | 10 | This approach comes with a disadvantage that you have to install each one of the tools you are using in the project for Foliant to work. You may do it once on your machine but Foliant projects usually need to work as well for other people if they decide to clone your project's repository. And these people may not have the right tool installed, or they may have another version of it, or even an operating system which doesn't have the tool at all. 11 | 12 | Docker solves this problem by creating a virtual environment which will be consistent among different machines and even different operating systems. All the required tools will be installed and configured inside this virtual environment so all it's left to do is to run the build. 13 | 14 | Working with Docker may seem complicated for non-programmers, but we will try to make it simple. We will concentrate on practical examples and keep the technical details out of this tutorial. If you want them — check the [Docker documentation](https://docs.docker.com/). 15 | 16 | ## Getting Docker 17 | 18 | The first step is to download and install Docker. 19 | 20 | **Windows** 21 | 22 | Go to [https://www.docker.com/get-started](https://www.docker.com/get-started) and download Docker installer. 23 | 24 | Follow the instructions of the installer. In the end, it may ask you to restart the computer. After restarting, run Docker by the shortcut in your Start menu. 25 | 26 | **Linux** 27 | 28 | Follow the [instructions](https://docs.docker.com/engine/install/) for your Linux distribution on the official website. 29 | 30 | After that [install Docker Compose](https://docs.docker.com/compose/install/#install-compose-on-linux-systems). 31 | 32 | **MacOs** 33 | 34 | Download and install Docker from [this page](https://hub.docker.com/editions/community/docker-ce-desktop-mac/). 35 | 36 | ## Creating a Test Project 37 | 38 | Now that we’ve got Docker, we can create our test project. 39 | 40 | If you have Foliant installed on your system, run the `init` command 41 | 42 | ```bash 43 | $ foliant init 44 | ``` 45 | 46 | Type the name of the project and `cd` into the freshly created folder. 47 | 48 | But that's the beauty of the Docker way, you don't even need to have Foliant installed on you computer to build Foliant projects. Instead of using `init` you can clone the [Foliant Project template](https://github.com/foliant-docs/foliant_project_template). It’s an empty Foliant project with the required file and directory structure, including necessary Docker configs. It's similar to what you get by running `foliant init`. 49 | 50 | Now `cd` to the cloned directory and remove the `.git` folder, which still points to the template repository. 51 | 52 | ## Setting up Docker configs 53 | 54 | We've got a basic project which we already can build with Docker. 55 | 56 | Inside the project dir run: 57 | 58 | ```bash 59 | $ docker-compose run --rm foliant make site 60 | ``` 61 | 62 | Right now our project can only build an MkDocs site. If we try to build a pdf we will get 63 | 64 | ```bash 65 | $ docker-compose run --rm foliant make pdf 66 | No backend available for pdf. 67 | ``` 68 | 69 | If you are already familiar with Foliant you know that to build PDFs you need to install [Pandoc](https://pandoc.org/) with TeXLive and Pandoc backend. So how do we install that in a Docker container? 70 | 71 | In your project root you have a `Dockerfile`. This file describes the steps required to set up your virtual container. 72 | 73 | If you open the `Dockerfile`, you will see that apart from comments it contains three lines: 74 | 75 | ``` 76 | FROM foliant/foliant 77 | 78 | COPY requirements.txt . 79 | 80 | RUN pip3 install -r requirements.txt 81 | ``` 82 | 83 | The first line means that we start out with the base Foliant image, more on that later. The second one copies the file `requirements.txt` from your project folder into the container and the last one installs all Python dependencies from this file with `pip` from inside the container. 84 | 85 | `requirements.txt` is a file where all your Python dependencies for the project live. It means that adding the Pandoc backend to the virtual environment is a matter of adding it into `requirements.txt`. Let's do this now: 86 | 87 | ```diff 88 | foliantcontrib.mkdocs 89 | + foliantcontrib.pandoc 90 | 91 | ``` 92 | 93 | With Pandoc and TeXLive it's not that easy, because they are not Python packages. But don't worry, it's still easy enough. 94 | 95 | Your virtual container is based on `foliant/foliant` image, which is in turn based on Ubuntu operating system. So all you need to do is to find the right commands to install the required packages as if you were on Ubuntu. 96 | 97 | These commands are 98 | 99 | ```bash 100 | apt update 101 | apt install -y texlive-full librsvg2-bin 102 | apt install -y pandoc 103 | ``` 104 | 105 | So we take this commands and put them in our `Dockerfile`, but we will put `RUN` before each one to explain Docker our intentions. The order in which lines appear in the `Dockerfile` is important. Docker does a nice job of caching stages of container build, so make a rule of putting the commands which less prone to change at the start. 106 | 107 | In our case we will probably be editing our `requirements.txt` further down the line, but the pandoc installation commands are unlikely to change so we put them first: 108 | 109 | ```diff 110 | FROM foliant/foliant 111 | 112 | + ENV DEBIAN_FRONTEND=noninteractive 113 | + RUN apt update 114 | + RUN apt install -y texlive-full librsvg2-bin 115 | + RUN apt install -y pandoc 116 | 117 | COPY requirements.txt . 118 | 119 | RUN pip3 install -r requirements.txt 120 | ``` 121 | 122 | We've also added an environment variable `DEBIAN_FRONTEND` which is required to install texlive-full inside a Docker container. Consider it magic, just don't forget to add it each time you install texlive in Docker. 123 | 124 | Now we need to rebuild our container. If we were to run the `docker-compose run` command now, it would still run in the old container, which doesn't have pandoc. So let's build it 125 | 126 | ```bash 127 | $ docker-compose build 128 | ``` 129 | 130 | This command will now take time to complete because of the TeXLive engine which is HUGE. Don't worry, you will need to wait for so long just once. 131 | 132 | Now, as it's starting to get dark and you can hear the workers coming home from the factories, our image has finished building. 133 | 134 | Let's make a PDF! 135 | 136 | ```bash 137 | $ docker-compose run --rm foliant make pdf 138 | ``` 139 | 140 | If all went right you will see a PDF file in your project folder. 141 | 142 | ## Using different Foliant Docker images 143 | 144 | You've noticed that `docker-compose build` command took a lot of time to complete because it needed to download and install the massive TexLive engine. It would be a pain to repeat this for each new Foliant project. 145 | 146 | Luckily, Foliant offers [a selection of Docker images](https://hub.docker.com/r/foliant/foliant/tags), each of which offers different number of tools preinstalled. One of the images is called `pandoc` and has the same packages which we've installed in the previous section. 147 | 148 | The full list is: 149 | 150 | * `slim` — minimal image of Foliant with no extensions; 151 | * `latest` — same as `slim` but with the `foliant init` command support; 152 | * `pandoc` — image of Foliant with Pandoc backend, Pandoc itself, and LaTeX (`texlive-full` Ubuntu package); 153 | * `full` — most complete image of Foliant with all released extensions and dependencies required for them. 154 | 155 | Let's update our project to use the `pandoc` image instead of manually installing the dependencies. 156 | 157 | The image to use for the project is specified on the first line of the `Dockerfile`. Open it and replace the first line with: 158 | 159 | ```diff 160 | - FROM foliant/foliant 161 | + FROM foliant/foliant:pandoc 162 | ``` 163 | 164 | Now remove the lines which we've added previouslly so your `Dockerfile` looks like this: 165 | 166 | ``` 167 | FROM foliant/foliant:pandoc 168 | 169 | RUN pip3 install -r requirements.txt 170 | ``` 171 | 172 | Next, remove the Pandoc backend from `requirements.txt` as it is also preinstalled in the `pandoc` image. 173 | 174 | Finally, rebuild the image and run the PDF making command: 175 | 176 | ``` 177 | $ docker-compose build 178 | $ docker-compose run --rm foliant make pdf 179 | ``` 180 | 181 | Once the `pandoc` image is downloaded, the build commands will always run very fast. 182 | 183 | ## Working with Foliant full image 184 | 185 | We've learned how to use Foliant with Docker, how to install dependencies inside the container and how to use different Foliant images. 186 | 187 | Now it's time to learn about the `full` Foliant image. This is the most powerful one of all. It has all official Foliant extensions and all their dependencies preinstalled. 188 | 189 | Once you base your `Dockerfile` on this image you will have whole power of Foliant at your disposal whenever you need it. 190 | 191 | To use it replace the first line of your `Dockerfile` with 192 | 193 | ```diff 194 | - FROM foliant/foliant 195 | + FROM foliant/foliant:full 196 | ``` 197 | 198 | and run the build command 199 | 200 | ``` 201 | $ docker-compose build 202 | ``` 203 | 204 | Now you can for instance make a [Slate](https://github.com/slatedocs/slate) static website with your docs instead of MkDocs. 205 | 206 | The command is 207 | 208 | ```bash 209 | $ docker-compose run --rm foliant make site --with slate 210 | ``` 211 | 212 | We had to add a `--with slate` argument to our command to specify the backend to build `site` target with. `full` Foliant docker image contains all available official backends for Foliant and several of them are capable of building the `site` target. Without the `--with` argument (or `-w` for short) Foliant would prompt you for the specific backend name interactively. 213 | 214 | # Summary 215 | 216 | That's all you need to know to work with Foliant the Docker way. Just remember the steps: 217 | 218 | - put your Python dependencies in the `requirements.txt` file, 219 | - add commands for installing your non-Python dependencies into the `Dockerfile`, preceding them with the `RUN`, 220 | - rebuild your image with `docker-compose build` command every time you edit `Dockerfile` or `requirements.txt`. No need to run it after editing your Markdown sources or Foliant-related configuration files. 221 | 222 | And one last note for the `full` image users. We keep constantly updating Foliant, adding and updating its extensions. To use all the fresh features update the image every once in a while with command 223 | 224 | ```bash 225 | $ docker pull ghcr.io/foliant-docs/foliant/foliant:full 226 | ``` 227 | 228 | And don't forget to rebuild your project's image after updating: 229 | 230 | ```bash 231 | $ docker-compose build 232 | ``` 233 | -------------------------------------------------------------------------------- /src/tutorials/preprocessor/preprocessor.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - tutorial 4 | - preprocessor 5 | --- 6 | 7 | # Formalizing the Preprocessor 8 | 9 | A Foliant preprocessor is a Python package of a certain structure. Here's a list of requirements for a package to be considered by Foliant a preprocessor: 10 | 11 | 1. After installing the preprocessor package should appear inside the Foliant package folder at a path `foliant.preprocessors.your_preprocessor`. 12 | 2. It must be possible to import a class named `Preprocessor` from your package: 13 | 14 | ```python 15 | from foliant.preprocessor.your_preprocessor import Preprocessor 16 | ``` 17 | 18 | 3. The `Preprocessor` class should (but is not required to) be a subclass of a `foliant.preprocessors.BasePreprocessor` class. 19 | * in any case the `Preprocessor` class must accept the same `__init__` arguments as the `BasePreprocessor` class. 20 | 4. The `Preprocessor` class must define at least the `apply` method. 21 | 22 | 23 | Let's take our `gibberish` module which we've created in the previous chapter and make it work with Foliant. We will be adding the code into the same module. 24 | 25 | According to the requirements above, we first need to create a proper directory structure. It should look like this: 26 | 27 | ```bash 28 | $ tree 29 | . 30 | └── foliant 31 | └── preprocessors 32 | └── gibberish.py 33 | 34 | 2 directories, 1 file 35 | ``` 36 | 37 | This is the first requirement satisfied. Now to the rest of them. 38 | 39 | We should define a `Preprocessor` class and ideally subclass it from `BasePreprocessor`. 40 | 41 | Usually, we start out a new preprocessor from a template containing the boilerplate code. You can find the full template [here](https://github.com/foliant-docs/foliantcontrib.templates.preprocessor/blob/develop/foliant/cli/init/templates/preprocessor/foliant/preprocessors/%24slug.py). 42 | 43 | But to understand the boilerplate code you have to write it at least once, so let's start from scratch. 44 | 45 | We start by defining the `Preprocessor` class. 46 | 47 | ```python 48 | from foliant.preprocessors.base import BasePreprocessor 49 | 50 | 51 | class Preprocessor(BasePreprocessor): 52 | ``` 53 | 54 | The `BasePreprocessor` parent class offers some useful attributes and methods, go ahead and take a look at its [source code](https://github.com/foliant-docs/foliant/blob/develop/foliant/preprocessors/base.py). 55 | 56 | Let's start writing the class by adding the `__init__` method and several class attributes. 57 | 58 | 59 | ```python 60 | class Preprocessor(BasePreprocessor): 61 | tags = ('gibberish', ) # [1] 62 | defaults = {'default_size': 10} # [2] 63 | 64 | def __init__(self, *args, **kwargs): 65 | super().__init__(*args, **kwargs) # [3] 66 | 67 | self.logger = self.logger.getChild('gibberish') # [4] 68 | 69 | self.logger.debug(f'Preprocessor inited: {self.__dict__}') # [5] 70 | ``` 71 | 72 | 1. First, we define the tags which will be captured in the Markdown source. As we've decided in the beginning, we want to process tags that look like ``, so our tag name is `gibberish`. We put that into the `tags` class attribute which must be a sequence. `tuple` or `list` are equally good choices. 73 | 1. We will allow the user to define the default size of the generated text in the preprocessor options. Here we provide the default value of `10` to this option, in case the user hasn't supplied it. 74 | 1. Running the parent's `__init__` method first. It will populate our class with useful attributes. 75 | 1. Using the `logger` attribute to set up a logger. This line embeds our preprocessor into the main log file under the name of `gibberish`. 76 | 1. Posting our first log message, which will contain all preprocessor's attributes for inspection. 77 | 78 | Now let's write the `apply` method. As mentioned above, this method must be present in all preprocessors. This is the method that Foliant will call to apply the preprocessor. Usually, it subsequently opens each file from the temporary directory and calls the main processing method to transform their content in the desired way. It's a good practice to start and end this method with log messages. 79 | 80 | ```python 81 | def apply(self): 82 | self.logger.info('Applying preprocessor Gibberish') 83 | for markdown_file_path in self.working_dir.rglob('*.md'): # [1] 84 | with open(markdown_file_path, encoding='utf8') as markdown_file: 85 | content = markdown_file.read() # [2] 86 | 87 | processed_content = self._process_tags(content) # [3] 88 | 89 | if processed_content: # [4] 90 | with open(markdown_file_path, 'w') as markdown_file: 91 | markdown_file.write(processed_content) # [5] 92 | self.logger.info('Preprocessor Gibberish applied') 93 | ``` 94 | 95 | 1. Scan the temporary directory (the `working_dir` attribute, which is a `pathlib.Path` object, created for us by the parent class) and find all Markdown files in it. 96 | 1. Get the source content of each Markdown file. 97 | 1. Process the content with the `_process_tags` method which we are about to write next. 98 | 1. This step is important. We check if the main processing method actually returned any content. If the string is empty, it usually means that something went wrong. Foliant won't interrupt the build process if one of the preprocessors fails to run. We don't want to write empty or broken content into Markdown files, because other preprocessors still may run after ours even if ours failed. 99 | 1. If everything is OK, and our preprocessing function returned some content, we overwrite the original Markdown file with it. 100 | 101 | The `apply` method defers the actual preprocessing work to the `_process_tags` method, so now let's write it. 102 | 103 | ```python 104 | def _process_tags(self, content): 105 | def sub_tag(match): # [2] 106 | tag_options = self.get_options(match.group('options')) # [3] 107 | default_size = self.options['default_size'] # [4] 108 | size = tag_options.get('size', default_size) # [5] 109 | return gen_text(size) # [6] 110 | 111 | return self.pattern.sub(sub_tag, content) # [1] 112 | ``` 113 | 114 | Note the order of the bullet points: we start with the last line of the code above: 115 | 116 | 1. The `pattern` is another attribute created by the base class. It is a RegEx pattern object which will capture the XML tags in the Markdown source. Remember the `tags` class attribute we've defined in the beginning? `pattern` will use it to capture the appropriate tags for our preprocessor. We use the [`re.sub`](https://docs.python.org/3/library/re.html#re.sub) method of the pattern which will replace our tag definitions (``) in the `content` with whatever string returns the `sub_tag` local function. 117 | 1. Next, we define the `sub_tag` local function. This function accepts one argument: the [`Match`](https://docs.python.org/3/library/re.html#match-objects) object which was captured by the pattern. 118 | 1. We use the handy `get_options` method of the base class, which takes the options string of the tag found in the source, and turns it into a dictionary of options. For example, if the captured tag was ``, the options string is `size="15"`. It will be turned into `{'size': 15}` by the `get_options` method. 119 | 1. Getting the value of the `default_size` parameter from the preprocessor options. The options are stored in `self.options` dictionary by the base class. The dictionary is first prepopulated by values from the `defaults` attribute that we've defined earlier. According to the `defaults`, if the user hasn't stated any options, the `default_size` will have the value of `10`. 120 | 1. Getting the `size` option from the tag options. If options were not stated, we are using the `default_size` value as a fallback. 121 | 1. Finally, we are using the `get_text` function from our gibberish generator, which we've written in the previous part of the tutorial. We are returning the string returned from the `gen_text` function as the result of our `sub_tag` local function. This is the text which will replace the `` tag in the processed Markdown file. 122 | 123 | And that's it! We have all the code required for the preprocessor to work. All is left to do is to make our package installable and test its work. 124 | 125 | 126 | 127 | ??? example "Complete source of the preprocessor module" 128 | ```python 129 | ''' 130 | Gibberish preprocessor for Foliant documenation authoring tool. 131 | ''' 132 | 133 | import re 134 | 135 | from random import choice 136 | from random import randint 137 | from random import random 138 | 139 | from foliant.preprocessors.base import BasePreprocessor 140 | 141 | 142 | def pick_letter() -> str: 143 | """ 144 | Pick a random letter. 145 | Vowels have a higher chance of picking. 146 | Letters q, w, x and z have the lowest chance of picking. 147 | """ 148 | 149 | rare_letters = 'qwxz' 150 | vowels = 'aeiouy' 151 | consonants = 'cdfghjklmnpqrstv' 152 | 153 | pick = random() 154 | if pick > 0.9: 155 | return choice(rare_letters) 156 | elif pick > 0.3: 157 | return choice(vowels) 158 | else: 159 | return choice(consonants) 160 | 161 | def gen_word() -> str: 162 | """Return a word consisting of 2 to 9 letters.""" 163 | word_len = randint(2, 9) 164 | return ''.join(pick_letter() for _ in range(word_len)) 165 | 166 | 167 | def gen_sentence(num_words: int = 7) -> str: 168 | """Generate a sentence consisting of `num_words` words.""" 169 | words = (gen_word() for _ in range(num_words)) 170 | return ' '.join(words).capitalize() 171 | 172 | 173 | def gen_text(num_sentences: int = 10) -> str: 174 | """ 175 | Generate a paragraph of gibberish consisting of `num_sentences` 176 | senteces, each consisting of 3 to 12 words. 177 | """ 178 | 179 | sizes = (randint(3, 12) for _ in range(num_sentences)) 180 | sentences = (gen_sentence(size) for size in sizes) 181 | return '. '.join(sentences) + '.' 182 | 183 | 184 | class Preprocessor(BasePreprocessor): 185 | defaults = { 186 | 'default_size': 10 187 | } 188 | tags = ('gibberish',) 189 | 190 | def __init__(self, *args, **kwargs): 191 | super().__init__(*args, **kwargs) 192 | 193 | self.logger = self.logger.getChild('gibberish') 194 | 195 | self.logger.debug(f'Preprocessor inited: {self.__dict__}') 196 | 197 | def _process_tags(self, content): 198 | def sub_tag(match): 199 | tag_options = self.get_options(match.group('options')) 200 | default_size = self.options['default_size'] 201 | size = tag_options.get('size', default_size) 202 | return gen_text(size) 203 | 204 | return self.pattern.sub(sub_tag, content) 205 | 206 | def apply(self): 207 | self.logger.info('Applying preprocessor Gibberish') 208 | for markdown_file_path in self.working_dir.rglob('*.md'): 209 | with open(markdown_file_path, encoding='utf8') as markdown_file: 210 | content = markdown_file.read() 211 | 212 | processed_content = self._process_tags(content) 213 | 214 | if processed_content: 215 | with open(markdown_file_path, 'w') as markdown_file: 216 | markdown_file.write(processed_content) 217 | self.logger.info('Preprocessor Gibberish applied') 218 | ``` 219 | 220 | 221 | Next: 222 | 223 | Previous: 224 | -------------------------------------------------------------------------------- /src/dev_reference.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - overview 4 | - developing 5 | --- 6 | 7 | # Developer’s Reference 8 | 9 | The power of Foliant is in its extensions. Foliant's ecosystem consists of many beautiful tools for technical writers, but there is still a lot to be done. You are welcome to contribute to Foliant and its extensions. 10 | 11 | This article contains the reference of the main classes and functions available in Foliant Core. As an extension developer, you will be using them to write your own preprocessors, backends, CLI- and config-extensions. 12 | 13 | If you are new to extending Foliant, we suggest you to take a look at the Creating a Preprocessor tutorial first. 14 | 15 | Official Foliant extensions live in Git repositories inside the [foliant-docs](https://github.com/foliant-docs/) GitHub group. Check out their source code to find out different approaches to solving techwriters' problems. 16 | 17 | The repo of Foliant Core is called [foliant](https://github.com/foliant-docs/foliant/). The names of Foliant extensions' repositories start with the `foliantcontrib.` prefix. The repo of this documentation project is called [docs](https://github.com/foliant-docs/docs/). 18 | 19 | ## Core Modules 20 | 21 | Core modules live in the [foliant](https://github.com/foliant-docs/foliant) GitHub repository. Foliant Core itself does not build documentation projects, this job is delegated to extensions. But it defines the base classes for all types of extensions. Each base class offers useful attributes and methods which are described later in this article. For more info on how Foliant works check the article. 22 | 23 | This section lists all modules in the Foliant Core package. 24 | 25 | * `foliant`: 26 | * `backends`: 27 | * [`base`](https://github.com/foliant-docs/foliant/blob/develop/foliant/backends/base.py) — defines the base class for all backends; 28 | * [`pre`](https://github.com/foliant-docs/foliant/blob/develop/foliant/backends/pre.py) — simplest backend that returns Markdown content processed by specified preprocessors as a build result; 29 | * `preprocessors`: 30 | * [`base`](https://github.com/foliant-docs/foliant/blob/develop/foliant/preprocessors/base.py) — defines the base class for all preprocessors; 31 | * [`_unescape`](https://github.com/foliant-docs/foliant/blob/develop/foliant/preprocessors/_unescape.py) — simple preprocessor that escapes pseudo-XML tags (which are normally recognized by other preprocessors as control sequences) in code examples. If you want an opening tag to be ignored by any preprocessor, precede this tag with the `<` character. The `_unescape` preprocessor removes these characters before build. Instead of the `_unescape` preprocessor, you may use more flexible [EscapeCode and UnescapeCode](https://foliant-docs.github.io/docs/preprocessors/escapecode/) preprocessors; 32 | * [`cli`](https://github.com/foliant-docs/foliant/blob/develop/foliant/cli/__init__.py) — defines the Foliant’s root class `Foliant()` and the `entry_point()` method that is used as a starting point for calling Foliant. Nested modules: 33 | * [`base`](https://github.com/foliant-docs/foliant/blob/develop/foliant/cli/base.py) — defines the base class for all CLI extensions; 34 | * [`make`](https://github.com/foliant-docs/foliant/blob/develop/foliant/cli/make.py) — provides the main Foliant’s `make` command; 35 | * `config`: 36 | * [`base`](https://github.com/foliant-docs/foliant/blob/develop/foliant/config/base.py) — defines the base class for all config extensions; 37 | * [`include`](https://github.com/foliant-docs/foliant/blob/develop/foliant/config/include.py) — resolves the `!include` YAML tag that allows to include the content of additional YAML-files in Foliant config. More info in the Project Configuration article; 38 | * [`path`](https://github.com/foliant-docs/foliant/blob/develop/foliant/config/path.py) — resolves the `!path`, `!project_path` and `!rep_path` YAML tags. These tags are useful for specifying file paths in Foliant config or tag attributes. More info in the Project Configuration article; 39 | * [`utils`](https://github.com/foliant-docs/foliant/blob/develop/foliant/utils.py) — defines basic methods that may be used in different types of extensions. 40 | 41 | ### The `make()` Method Arguments 42 | 43 | The `make()` method is defined in the [`foliant.cli.make`](https://github.com/foliant-docs/foliant/blob/develop/foliant/cli/make.py) module. This method is called when the user runs `foliant make ...` command. For more info on how `make` command works check the article. 44 | 45 | The `make()` method accepts a number of arguments; some of them are then passed to the backends and preprocessors in the build *context*: 46 | 47 | * `target` (string) — required resulting target of the current build; 48 | * `backend` (string, defaults to an empty string) — the name of the backend that is used for the current build; 49 | * `project_path` (path, defaults to the current directory path) — the path of top-level, “root” directory of the current Foliant project; 50 | * `config_file_name` (string, defaults to `foliant.yml`) — the file name of the Foliant project’s config; 51 | * `quiet` (boolean, default to `False`) — a flag that prohibits writing to `STDOUT`; 52 | * `keep_tmp` (boolean, defaults to `False`) — a flag that tells Foliant and its extensions to preserve the temporary working directory, which is used during the build; 53 | * `debug` (boolean, defaults to `False`) — a flag that tells Foliant and its extensions to log events of `info` and `debug` levels in addition to messages of `warning`, `error`, and `critical` levels. 54 | 55 | ## Base Classes 56 | 57 | Foliant Core provides 4 base classes—one per each type of extension. 58 | 59 | * `BaseBackend()` is defined in the [`foliant.backends.base`](https://github.com/foliant-docs/foliant/blob/develop/foliant/backends/base.py) module. It is the base class for all backends. Each newly developed backend should: 60 | * be a module or a package `foliant.backends.`; 61 | * import the class `BaseBackend()` from the `foliant.backends.base` module; 62 | * define its own class called `Backend()` that is inherited from `BaseBackend()`; 63 | * define the method called `make()` within the `Backend` class. 64 | * `BasePreprocessor()` is defined in the [`foliant.preprocessors.base`](https://github.com/foliant-docs/foliant/blob/develop/foliant/preprocessors/base.py) module. It is the base class for all preprocessors. Each newly developed preprocessor should: 65 | * be a module or a package `foliant.preprocessors.`; 66 | * import the class `BasePreprocessor()` from the `foliant.preprocessors.base` module; 67 | * define its own class called `Preprocessor()` that is inherited from `BasePreprocessor()`; 68 | * define the method called `apply()` within the class `Preprocessor()`. 69 | * `BaseCli()` is defined in the [`foliant.cli.base`](https://github.com/foliant-docs/foliant/blob/develop/foliant/cli/base.py) module. It is the base class for all CLI extensions. Each newly developed CLI extension should: 70 | * be a module or a package `foliant.cli.`; 71 | * import the class `BaseCli()` from the `foliant.cli.base` module; 72 | * define its own class called `Cli()` that is inherited from `BaseCli()`. 73 | * `BaseParser()` is defined in the [`foliant.config.base`](https://github.com/foliant-docs/foliant/blob/develop/foliant/config/base.py) module. It is the base class for all config extensions. Each newly developed config extension should: 74 | * be a module or a package `foliant.config.`; 75 | * import the class `BaseParser()` from the `foliant.config.base` module; 76 | * define its own class called `Parser()` that is inherited from `BaseParser()`. 77 | 78 | ### The `BaseBackend()` Attributes 79 | 80 | * Class attributes: 81 | * `targets` (tuple of strings) — names of the targets that the backend can build; 82 | * `required_preprocessors_before` (tuple of strings) — names of the preprocessors that should be applied before all other preprocessors when this backend is used; 83 | * `required_preprocessors_after` (tuple of strings) — names of preprocessors that should be applied after all other preprocessors when this backend is used; 84 | * instance variables: 85 | * `context` — a dictionary that contains the build context: 86 | * `project_path` (path) — path to the currently built Foliant project; 87 | * `config` (dictionary) — full config of the currently built Foliant project; 88 | * `target` (string) — the name of the resulting target; 89 | * `backend` (string) — the name of the backend that is used in the current build; 90 | * `config` — full config of the currently built Foliant project. The same as `context['config']`; 91 | * `project_path` — path to the currently built Foliant project. The same as `context['project_path']`; 92 | * `working_dir` (path) — the path to the temporary working directory that is used during the build. It is defined as `self.project_path / self.config['tmp_dir']`; 93 | * `logger` — the [Logger](https://docs.python.org/3/library/logging.html#logging.Logger) instance of the current build; 94 | * `quiet` (boolean) — if `True`, the backend should not write anything to stdout; 95 | * `debug` (boolean) — if `True`, the backend should log the messages of `info` and `debug` levels. 96 | 97 | ### The `BasePreprocessor()` Attributes 98 | 99 | * Class attributes: 100 | * `defaults` (dictionary) — default values of options that may be overridden in config; 101 | * `tags` (tuple of strings) — names of pseudo-XML tags that are recognized by the preprocessor, without `<` and `>` characters; 102 | * instance variables: 103 | * `context` — a dictionary that contains the build context: 104 | * `project_path` (path) — path to the currently built Foliant project; 105 | * `config` (dictionary) — full config of the currently built Foliant project; 106 | * `target` (string) — the name of the resulting target; 107 | * `backend` (string) — the name of the backend that is used in the current build; 108 | * `config` — full config of the currently built Foliant project. The same as `self.context['config']`; 109 | * `project_path` — path to the currently built Foliant project. The same as `self.context['project_path']`; 110 | * `working_dir` (path) — the path to the temporary working directory that is used during the build. It is defined as `self.project_path / self.config['tmp_dir']`; 111 | * `logger` — the [Logger](https://docs.python.org/3/library/logging.html#logging.Logger) instance of the current build; 112 | * `quiet` (boolean) — if `True`, the backend should not write anything to stdout; 113 | * `debug` (boolean) — if `True`, the backend should log the messages of `info` and `debug` levels. 114 | * `options` (dictionary) — the preprocessor’s options. Is defined as `{**self.defaults, **options}`, where `options` is the data that is read from the preprocessor's config in foliant.yml; 115 | * `pattern` — the regular expression [pattern](https://github.com/foliant-docs/foliant/blob/develop/foliant/preprocessors/base.py#L53) that is used to get components of a pseudo-XML tag in an easy way. Defined if `self.tags` is not empty. Provides the RegEx groups with the following names: 116 | * `tag` — captured tag name; 117 | * `options` — captured tag attributes (options) as a string; this string may be converted into a dictionary by using the [`self.get_options()` method](https://github.com/foliant-docs/foliant/blob/develop/foliant/preprocessors/base.py#L17), which is provided by the base class; 118 | * `body` — captured tag body, i.e. the content between the opening and closing tags. 119 | 120 | ### `BaseCli()` Attributes 121 | 122 | * Instance attributes: 123 | * `logger` — the [Logger](https://docs.python.org/3/library/logging.html#logging.Logger) instance of the current build. 124 | 125 | ### `BaseConfig()` Attributes 126 | 127 | * Instance attributes: 128 | * `project_path` (path) — the path to the currently built Foliant project; 129 | * `config_path` (path) — the path to the config file of the currently built Foliant project; 130 | * `logger` — the [Logger](https://docs.python.org/3/library/logging.html#logging.Logger) instance of the current build; 131 | * `quiet` (boolean) — if `True`, the config extension should not write anything to stdout. 132 | -------------------------------------------------------------------------------- /src/config.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - overview 4 | - config 5 | - yaml 6 | --- 7 | 8 | # Project Configuration 9 | 10 | Configuration for Foliant is kept in a [YAML](https://yaml.org/) file in the project root. The default filename is `foliant.yml` but you can pick a different name by specifying the `--config` option: 11 | 12 | ```bash 13 | $ foliant make pdf --config myconf.yml 14 | ``` 15 | 16 | ## Config Sections 17 | 18 | * 19 | * 20 | * 21 | * 22 | 23 | ### Root Options 24 | 25 | These are the options that are placed at the root of the config file. There are several built-in options, which are described below, but extensions may introduce their own root options (for example, or ). Refer to each extension’s respective docs for details. 26 | 27 | Here are all built-in root options: 28 | 29 | ```yaml 30 | title: My Awesome Project 31 | slug: myproj 32 | src_dir: src 33 | tmp_dir: __folianttmp__ 34 | multithread: false 35 | ``` 36 | 37 | `title` *(string)* 38 | : Project title. It will be used to generate the resulting file name, if `slug` option is not defined. 39 | 40 | `slug` *(string)* 41 | : Slug is a string which will be used to name the output file or folder after build. For example, if slug is `myproj`, the output PDF will be saved into `myproj.pdf`. If not defined — `title` will be used to generate filename. 42 | 43 | `src_dir` *(string)* 44 | : Name of the directory with your project’s Markdown source files. Default: `src`. 45 | 46 | `tmp_dir` *(string)* 47 | : Name of the directory where the intermediate files will be stored during preprocessor pipeline execution. Default: `__folianttmp__`. 48 | 49 | `multithread` *(bool)* 50 | : The option enables multithreaded processing of files and tags by preprocessors using the `BasePreprocessorExt` class from [foliantcontrib.utils](https://github.com/foliant-docs/foliantcontrib.utils). Default: `false`. 51 | 52 | ### chapters 53 | 54 | *(list)* 55 | 56 | `chapters` is a list of paths to the Markdown sources which you want to be used in the project. The paths are specified relative to your `src` dir. 57 | 58 | Here’s a basic chapters list: 59 | 60 | ```yaml 61 | chapters: 62 | - intro.md 63 | - definitions.md 64 | - tutorial.md 65 | ``` 66 | 67 | Chapters may be nested with mappings and sublists. These complex structures may be treated differently by different backends: some may ignore nesting, some may use it to alter the resulting build. But usually, these two ideas are shared between all backends: 68 | 69 | - only those Markdown files which are mentioned in the chapters list will appear in the resulting build; 70 | - the order in which chapters are mentioned in the list will be preserved in the resulting build. 71 | 72 | Consider this example chapters list: 73 | 74 | ```yaml 75 | chapters: 76 | - intro.md # list item 77 | - definitions.md # list item 78 | - How To Use This Tutorial: tutorial_help.md # mapping with one element 79 | - Creating Documentation With Foliant: # mapping with nested list 80 | - preprequisites.md 81 | - Preparing Config: 82 | - root options.md 83 | - chapters.md 84 | - preprocessors.md 85 | - backend_config.md 86 | - create_sources.md 87 | - building_project.md 88 | ``` 89 | 90 | In this example first two chapters are defined as simple list items, the third chapter is a mapping with one element, and after that, we see several mappings with nested lists. 91 | 92 | If we were building a PDF document with Pandoc backend or a static site with Slate backend, this complex chapter structure will be ignored, as if we have supplied a simple flat list: 93 | 94 | ```yaml 95 | chapters: 96 | - intro.md 97 | - definitions.md 98 | - tutorial_help.md 99 | - preprequisites.md 100 | - root options.md 101 | - chapters.md 102 | - preprocessors.md 103 | - backend_config.md 104 | - create_sources.md 105 | - building_project.md 106 | ``` 107 | 108 | In any case, we would get a one-file PDF or a one-page site with data from listed Markdown files in the provided order. 109 | 110 | But if we were building a site with MkDocs backend, mappings would become meaningful. 111 | 112 | For example, this element: 113 | 114 | ```yaml 115 | - How To Use This Tutorial: tutorial_help.md 116 | ``` 117 | 118 | means "take the source from `tutorial_help.md` but change its title to `How To Use This Tutorial`" in the sidebar. 119 | 120 | And this element: 121 | 122 | ```yaml 123 | - Creating Documentation With Foliant: 124 | - preprequisites.md 125 | - Preparing Config: 126 | - root options.md 127 | - chapters.md 128 | - preprocessors.md 129 | - backend_config.md 130 | ``` 131 | 132 | means "create a subsection **Creating Documentation With Foliant** in the sidebar and nest the `preprequisites.md` chapter inside. Then nest another subsection **Preparing Config** within the first one, and nest four other chapters inside of it". 133 | 134 | Refer to each backend’s respective docs for details on how they work with chapters. 135 | 136 | ### preprocessors 137 | 138 | *(list)* 139 | 140 | All preprocessors which you want to be used in your project, should be listed under the `preprocessors` section: 141 | 142 | ```yaml 143 | preprocessors: 144 | - macros: # options are adjusted 145 | macros: 146 | ref: {pandoc}{mkdocs} 147 | - flags # all options are set to defaults 148 | - includes 149 | - blockdiag 150 | - plantuml: 151 | params: 152 | config: !path configs/plantuml.cfg 153 | - graphviz: 154 | format: svg 155 | as_image: false 156 | params: 157 | Gdpi: 0 158 | ``` 159 | 160 | Each preprocessor has to be put in a separate list item. If you don’t need to set any options, just put the preprocessor’s name in the item (`flags`, `includes`, and `blockdiag` in the example above). If you are setting preprocessor options, then make it a mapping, with key being the preprocessor name, and value — another mapping, with preprocessor options. (`macros`, `plantuml`, and `graphviz` in the example above). 161 | 162 | Refer to each preprocessor’s respective docs for details on which options they have and how to set them. 163 | 164 | There are several things you have to keep in mind when building the preprocessors section: 165 | 166 | **The order matters** 167 | 168 | The order, in which the preprocessors are defined in the list, is the order they are run during the build. For example, if you are using Includes preprocessor to get source code for a PlantUML scheme like this: 169 | 170 | ```html 171 | 172 | 173 | 174 | ``` 175 | 176 | then `includes` must be defined before `plantuml` in the preprocessor list. Otherwise, you will get an error from PlantUML when it tries to process `` tag instead of the scheme code. 177 | 178 | Some preprocessors are especially sensitive to their position in the list (for example, SuperLinks) and there may even be situations when you will have to put the same preprocessor in the list twice. 179 | 180 | **Preprocessors are applied to all files** 181 | 182 | Generally, preprocessors just ignore the chapters list and apply to *all Markdown files* in the src dir. Usually, this is not an issue, but sometimes preprocessor may spend a long time on the files, which may not even get into the resulting build. 183 | 184 | We suggest you keep your src dir tidy and only put there files that are actually getting into the project. The other solution is to use RemoveExcess preprocessor, which removes all Markdown files, which are not mentioned in the chapters list, from the temporary directory. 185 | 186 | ### backend_config 187 | 188 | *(mapping)* 189 | 190 | Keep all your backend settings in `backend_config` section: 191 | 192 | ```yaml 193 | backend_config: 194 | pandoc: 195 | template: !path template/docs.tex 196 | vars: 197 | title: *title 198 | subtitle: User’s Manual 199 | logo: !path template/octopus-black-512.png 200 | params: 201 | pdf_engine: xelatex 202 | listings: true 203 | mkdocs: 204 | use_title: true 205 | use_chapters: true 206 | use_headings: true 207 | mkdocs.yml: 208 | repo_name: foliant-docs/docs 209 | theme: 210 | name: material 211 | custom_dir: !path ./theme/ 212 | ``` 213 | 214 | Unlike `preprocessors` section, `backend_config` is not a list but a mapping. Hence, the order in which you define backends is not important. 215 | 216 | Moreover, you can even skip adding a backend into `backend_config` and still be able to build a project with it. It will just mean that you are using default settings. 217 | 218 | ## Modifiers 219 | 220 | Foliant defines several custom YAML-modifiers, some of which you have already met in the examples above. 221 | 222 | ### !include 223 | 224 | The `!include` modifier allows inserting content from another YAML-file. 225 | 226 | For example, if your chapters list has grown so big, that you want to keep it separately from the main config, you can put it into `chapters.yml` file and include it in `foliant.yml`: 227 | 228 | ```yaml 229 | chapters: !include chapters.yml 230 | ``` 231 | 232 | ### !path, !project_path, !rel_path 233 | 234 | When used in foliant.yml, `!path`, `!project_path`, `!rel_path` all do the same thing: they resolve the path to an absolute path to make sure the preprocessor or backend processes this file properly. 235 | 236 | It is recommended, that whenever you supply a path to any file in options, to precede it with the `!path` modifier: 237 | 238 | ```yaml 239 | preprocessors: 240 | - swaggerdoc: 241 | spec_path: !path swagger.yml 242 | environment: 243 | user_templates: !path widdershins_templates 244 | - plantuml: 245 | params: 246 | config: !path configs/plantuml.cfg 247 | 248 | backend_config: 249 | pandoc: 250 | template: !path pandoc/tex_templates/main.tex 251 | reference_docx: !path pandoc/docx_references/basic.docx 252 | ``` 253 | 254 | Why there are three of them then, would you ask? The reason is that all *foliant tag options* in Markdown source files are in fact also YAML-strings, which means that you can supply a list in tag option like this: 255 | 256 | ```html 257 | 258 | Received the variables! 259 | 260 | {% for var in vars %} 261 | I’ve got a var {{ var }} 262 | {% endfor %} 263 | 264 | ``` 265 | 266 | And that’s where `!project_path`, `!rel_path` modifiers come in really handy. Now you can refer to a file that is sitting in the project root, no matter where inside the src dir your current file is: 267 | 268 | ```html 269 | Here are the contents of this project’s config: 270 | 271 | 272 | ``` 273 | 274 | By convention, all tag parameters, which accept paths to external files, are considered to be paths relative to the current file. But if you want to make things more explicit, you may add the `!rel_path` tag, which ensures that the path the preprocessor will get, will be relative to the current file: 275 | 276 | ```html 277 | Here are the contents of the adjacent chapter: 278 | 279 | 280 | ``` 281 | 282 | `!path` modifier, if used in tag parameters, works the same as `!project_path` modifier: it returns the absolute path to the file, relative to the project root. 283 | 284 | ### `!env` 285 | 286 | The `!env` modifier allows you to access environment variables in the config, as well as in tag options. 287 | 288 | It is useful if you don’t want to keep credentials in your config files, for example: 289 | 290 | ```yaml 291 | # foliant.yml 292 | 293 | preprocessors: 294 | dbdoc: 295 | host: localhost 296 | user: admin 297 | password: !env DBA_PASSWORD 298 | ``` 299 | 300 | Now to build this project add the variable to your command: 301 | 302 | ```bash 303 | DBA_PASSWORD=WQHsaio901SY foliant make pdf 304 | ``` 305 | 306 | Or, if you are using docker: 307 | 308 | ```bash 309 | docker-compose run --rm -e DBA_PASSWORD=WQHsaio901SY foliant make pdf 310 | ``` 311 | -------------------------------------------------------------------------------- /theme/assets/images/octopus-white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /src/tutorials/first_project.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - tutorial 4 | --- 5 | 6 | # Your First Foliant Project 7 | 8 | In this tutorial, you’ll learn how to use Foliant to build websites and pdf documents from a single Markdown source. You’ll also learn how to use Foliant preprocessors. 9 | 10 | > It is recommended to run Foliant through Docker to get consistent results on different machines, but it's also perfectly fine to run it natively (e.g. as a pure CLI tool without virtualization). In this tutorial, we will show the example commands for both native way (these will go first) and the Docker way (these will follow). 11 | 12 | 13 | ## Create New Project 14 | 15 | All Foliant projects must adhere to a certain structure. Luckily, you don’t have to memorize it thanks to the Init extension. 16 | 17 | You should have installed it during Foliant installation and it’s included in Foliant’s default Docker image. 18 | 19 | To use it, run `foliant init` command 20 | 21 | ```bash 22 | $ foliant init 23 | Enter the project name: Hello Foliant 24 | Generating Foliant project 25 | ───────────────────── 26 | Project "Hello Foliant" created in hello-foliant 27 | ``` 28 | 29 | To do the same with Docker, run 30 | 31 | ```bash 32 | $ docker run --rm -it --user $(id -u):$(id -g) -v $(pwd):/usr/src/app -w /usr/src/app foliant/foliant init 33 | Enter the project name: Hello Foliant 34 | Generating project... Done 35 | ───────────────────── 36 | Project "Hello Foliant" created in hello-foliant 37 | ``` 38 | 39 | The `init` command created a structure for the Foliant project in `hello-foliant` subfolder. 40 | 41 | ```bash 42 | $ cd hello-foliant 43 | $ tree 44 | . 45 | ├── docker-compose.yml 46 | ├── Dockerfile 47 | ├── foliant.yml 48 | ├── README.md 49 | ├── requirements.txt 50 | └── src 51 | └── index.md 52 | 53 | 1 directory, 6 files 54 | ``` 55 | 56 | `foliant.yml` is your Project Configuration file. 57 | 58 | `src` is the directory for your Markdown documents. Currently, there’s just one file there called `index.md`. 59 | 60 | `requirements.txt` lists the Python packages required for the project: Foliant backends and preprocessors, MkDocs themes, and whatnot. When the Docker image for the project is built, these requirements will be installed in it. 61 | 62 | `Dockerfile` and `docker-compose.yml` are necessary to build the project in a Docker container. 63 | 64 | 65 | ## Build Site 66 | 67 | To build a site you will first need a suitable *backend*. To catch up with the terminology, check this article, but in short, backends are Foliant modules responsible for converting Markdown sources into the final documentation format. 68 | 69 | Let’s start with **MkDocs** backend. First, install it using the following command 70 | 71 | ```bash 72 | pip3 install foliantcontrib.mkdocs 73 | ``` 74 | 75 | Docker users would normally need to add this package to the `requirements.txt` file instead, but mkdocs is already there by default if you used `init` to generate project structure. 76 | 77 | To build a site, in the project directory, run 78 | 79 | ```bash 80 | $ foliant make site 81 | Parsing config... Done 82 | Applying preprocessor mkdocs... Done 83 | Applying preprocessor _unescape... Done 84 | Making site with MkDocs... Done 85 | ──────────────────── 86 | Result: Hello_Foliant-2020-05-25.mkdocs 87 | ``` 88 | 89 | Or, with Docker Compose 90 | 91 | ```bash 92 | $ docker-compose run --rm foliant make site 93 | Parsing config... Done 94 | Applying preprocessor mkdocs... Done 95 | Applying preprocessor _unescape... Done 96 | Making site with MkDocs... Done 97 | ──────────────────── 98 | Result: Hello_Foliant-2020-05-25.mkdocs 99 | ``` 100 | 101 | That’s it! Your static, MkDocs-powered website is ready. To look at it, use any web server, for example, Python’s built-in one. 102 | 103 | ```bash 104 | $ python3 -m http.server -d Hello_Foliant-2020-05-25.mkdocs 105 | Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ... 106 | ``` 107 | 108 | Open [localhost:8000](http://localhost:8000/) in your web browser. You should see something like this 109 | 110 | ![Basic Foliant project built with MkDocs](../images/basic-mkdocs.png) 111 | 112 | 113 | ## Build PDF 114 | 115 | To build PDF with Pandoc natively, first you will need to install Pandoc itself and TexLive, check Foliant installation page for instructions. 116 | 117 | Then, in the project directory, run 118 | 119 | ```bash 120 | $ foliant make pdf 121 | Parsing config... Done 122 | Applying preprocessor flatten... Done 123 | Applying preprocessor _unescape... Done 124 | Making pdf with Pandoc... Done 125 | ──────────────────── 126 | Result: Hello_Foliant-2020-05-25.pdf 127 | ``` 128 | 129 | To build pdf in Docker container, first uncomment `foliant/foliant:pandoc` in your project’s `Dockerfile` 130 | 131 | ```diff 132 | - FROM foliant/foliant 133 | + # FROM foliant/foliant 134 | # If you plan to bake PDFs, uncomment this line and comment the line above: 135 | - # FROM foliant/foliant:pandoc 136 | + FROM foliant/foliant:pandoc 137 | 138 | COPY requirements.txt . 139 | 140 | RUN pip3 install -r requirements.txt 141 | ``` 142 | 143 | > **Note** 144 | > 145 | > Run `docker-compose build` to rebuild the image from the new base image if you have previously run `docker-compose run` with the old one. Also, run it whenever you need to update the versions of the required packages from `requirements.txt`. 146 | 147 | Then, run this command in the project directory 148 | 149 | ```bash 150 | $ docker-compose run --rm foliant make pdf 151 | Parsing config... Done 152 | Applying preprocessor flatten... Done 153 | Applying preprocessor _unescape... Done 154 | Making pdf with Pandoc... Done 155 | ──────────────────── 156 | Result: Hello_Foliant-2020-05-25.pdf 157 | ``` 158 | 159 | Your standalone pdf documentation is ready! It should look something like this 160 | 161 | ![Basic Foliant project built with Pandoc](../images/basic-pdf.png) 162 | 163 | 164 | ## Edit Content 165 | 166 | Your project’s content lives in `.md` files inside the `src` folder. You can organize it into multiple files and subfolders inside the `src` as you please. 167 | 168 | Foliant encourages [pure Markdown](https://daringfireball.net/projects/markdown/) syntax as described by John Gruber. Pandoc, MkDocs, and other backend-specific additions are allowed, but we strongly recommend putting them in `...`. 169 | 170 | Let's create a file `hello.md` inside `src` folder 171 | 172 | ```bash 173 | $ touch src/hello.md 174 | ``` 175 | 176 | And fill it with some content. For example 177 | 178 | ```markdown 179 | # Hello Again 180 | 181 | This is regular text generated from regular Markdown. 182 | 183 | Foliant doesn’t force any *special* Markdown flavor. 184 | ``` 185 | 186 | Now you have two files (or *chapters*) inside `src`, but Foliant knows only about one of them. To add `hello.md` to the project, open `foliant.yml` and add the new chapter to the `chapters` list 187 | 188 | ```diff 189 | title: Hello Foliant 190 | 191 | chapters: 192 | - index.md 193 | + - hello.md 194 | ``` 195 | 196 | Let's rebuild the project to see the new page. 197 | 198 | The native command 199 | 200 | ```bash 201 | foliant make pdf && foliant make site 202 | Parsing config... Done 203 | Applying preprocessor flatten... Done 204 | Applying preprocessor _unescape... Done 205 | Making pdf with Pandoc... Done 206 | ──────────────────── 207 | Result: 208 | Hello_Foliant-2020-05-25.pdf 209 | Parsing config... Done 210 | Applying preprocessor mkdocs... Done 211 | Applying preprocessor _unescape... Done 212 | Making site with MkDocs... Done 213 | ──────────────────── 214 | Result: Hello_Foliant-2020-05-25.mkdocs 215 | ``` 216 | 217 | The command for Docker 218 | 219 | ```bash 220 | $ docker-compose run --rm foliant make site && docker-compose run --rm foliant make pdf 221 | Parsing config... Done 222 | Applying preprocessor mkdocs... Done 223 | Applying preprocessor _unescape... Done 224 | Making site with MkDocs... Done 225 | ──────────────────── 226 | Result: Hello_Foliant-2020-05-25.mkdocs 227 | Parsing config... Done 228 | Applying preprocessor flatten... Done 229 | Applying preprocessor _unescape... Done 230 | Making pdf with Pandoc... Done 231 | ──────────────────── 232 | Result: Hello_Foliant-2020-05-25.pdf 233 | ``` 234 | 235 | And see the new page appear on the site and in the pdf document 236 | 237 | ![New page on the site](../images/basic-mkdocs-hello.png) 238 | 239 | ![New page in the pdf document](../images/basic-pdf-hello.png) 240 | 241 | ## Use Preprocessors 242 | 243 | Preprocessors are additional Foliant packages that transform your Markdown chapters in different ways. You can do all kinds of stuff with them: 244 | 245 | - include remote Markdown files or their parts in the source files, 246 | - perform auto-replace, 247 | - render diagrams from their textual description on the build, 248 | - restructure the project source or compile it into a single file for a particular backend. 249 | 250 | Preprocessors don't touch your sources in the `src` folder. Instead, they copy them into a temporary directory and transform the fresh copies on each build. 251 | 252 | In fact, you have already used two preprocessors! Look at the output of the `foliant make` commands and note the lines `Applying preprocessor mkdocs` and `Applying preprocessor flatten`. The `mkdocs` preprocessor made your files compatible with MkDocs’ requirements, and the `flatten` preprocessor was used to squash the project source into one file to produce a single PDF with Pandoc. These preprocessors were called by MkDocs and Pandoc backends implicitly. 253 | 254 | Now let's add a preprocessor into the pipeline ourselves. We've chosen Blockdiag preprocessor for this tutorial. 255 | 256 | ### Embed Diagrams with Blockdiag 257 | 258 | [Blockdiag](http://blockdiag.com/) is a Python app for generating diagrams. Blockdiag preprocessor extracts diagram descriptions from the project source and replaces them with the generated images. 259 | 260 | First, we need to install the blockdiag preprocessor 261 | 262 | ```bash 263 | $ pip3 install foliantcontrib.blockdiag 264 | ``` 265 | 266 | Or, if you are building with docker, add `foliantcontrib.blockdiag` to requirements.txt and rebuild the image with `docker-compose build` command. 267 | 268 | Next, we need to switch on the `blockdiag` preprocessor in project config. Open `foliant.yml` and add the following lines 269 | 270 | ```diff 271 | title: Hello Foliant 272 | + 273 | + preprocessors: 274 | + - blockdiag 275 | 276 | chapters: 277 | - index.md 278 | - hello.md 279 | 280 | ``` 281 | 282 | Then, in `hello.md`, add the following 283 | 284 | ```diff 285 | Foliant doesn’t force any *special* Markdown flavor. 286 | 287 | + 288 | + seqdiag { 289 | + "foliant make site" -> "blockdiag preprocessor" -> "mkdocs preprocessor" -> "mkdocs backend" -> site; 290 | + } 291 | + 292 | ``` 293 | 294 | Blockdiag preprocessor extends the Markdown syntax of your documentation by adding several *tags*. Each tag produces a different diagram type. Sequence diagrams are defined with `` tag. This is what we used in the sample above. The diagram definition sits in the tag body and the diagram properties such as caption or format are defined as tag attributes. 295 | 296 | Rebuild the site with `foliant make site` or `docker-compose run --rm foliant make site` and open it in the browser 297 | 298 | ![Sequence diagram drawn with seqdiag on the site](../images/basic-mkdocs-seqdiag.png) 299 | 300 | Rebuild the pdf and see that the diagram is there too 301 | 302 | ![Sequence diagram drawn with seqdiag in the pdf](../images/basic-pdf-seqdiag.png) 303 | 304 | Let’s customize the look of the diagrams in our project by setting their properties in the config file. For example, let’s use a custom font for labels. I’m using the ever-popular Comic Sans font, but you can pick any font that’s available in `.ttf` format. 305 | 306 | Put the font file in the project directory and add the following lines to `foliant.yml` 307 | 308 | ```diff 309 | preprocessors: 310 | - - blockdiag 311 | + - blockdiag: 312 | + params: 313 | + font: !path comic.ttf 314 | ``` 315 | 316 | After a rebuild, the diagram on the site and in the pdf should look like this 317 | 318 | ![Sequence diagram with Comic Sans in labels, site](../images/basic-mkdocs-seqdiag-comic.png) 319 | 320 | ![Sequence diagram with Comic Sans in labels, pdf](../images/basic-pdf-seqdiag-comic.png) 321 | 322 | There are many more params you can define for your diagrams. You can override global params for particular diagrams in their tags. And by combining this preprocessor with Flags you can even set different params for different backends, for example, build vector diagrams for pdf output and bitmap for site 323 | 324 | ```markdown 325 | This is a diagram that is rendered to `.png` in HTML and to `.pdf` in pdf: 326 | 327 | pngpdf"> 328 | ... 329 | 330 | ``` 331 | 332 | The possibilities acquired by combining different preprocessors are endless! 333 | 334 | > **Why Foliant Uses XML syntax for Preprocessor Tags** 335 | > 336 | > It’s common for Markdown-based tools to extend Markdown with custom syntax for additional functions. There’s no standard for custom syntax in the Markdown spec, so every developer uses whatever syntax is available for them, a different one for every new extension. 337 | > 338 | > In Foliant, we tried our best not to dive into this mess. Foliant aims to be an extensible platform, with many available preprocessors. So we needed one syntax for all preprocessors, but the one that was flexible enough to support them all. 339 | > 340 | > After trying many options, we settled with XML. Yes, normally you’d have a nervous tick when you hear XML, and so would we, but this is one rare case where XML syntax belongs just right: 341 | 342 | > - it allows to provide tag body and named parameters, 343 | > - it’s familiar to every techwriter out there, 344 | > - it’s close enough to HTML, and HTML tags are actually allowed by the Markdown spec, so we’re not even breaking the vanilla Markdown spec (almost), 345 | > - it’s nicely highlighted in IDEs and text editors. 346 | -------------------------------------------------------------------------------- /src/tutorials/api.md: -------------------------------------------------------------------------------- 1 | --- 2 | tags: 3 | - tutorial 4 | - API 5 | --- 6 | 7 | # Documenting API with Foliant 8 | 9 | In this tutorial we will learn how to use Foliant to generate documentation from API specification formats [OpenAPI (Swagger)](https://swagger.io/specification/), [RAML](https://raml.org/) and [API Blueprint](https://apiblueprint.org/). 10 | 11 | The general idea is that you supply a specification file path (`json` or `yaml` for OpenAPI, `raml` for RAML) to a preprocessor which will generate a Markdown document out of it. Markdown is what Foliant is good at, so after that you can do anything with it: convert to PDF, partially include in other documents, etc. In this guide we will concentrate on building a static website for your API documentation. 12 | 13 | > Please note that in this article we cover only the basic usage of the tools. For detailed information on features and customizing output refer to each component’s doc page. 14 | 15 | ## OpenAPI 16 | 17 | ### Installing prerequisites 18 | 19 | Besides Foliant you will need to install some additional packages on your system. If you are using our full docker image `foliant/foliant:full`, you can skip this chapter. 20 | 21 | First, install the SwaggerDoc preprocessor which will convert spec file to Markdown. 22 | 23 | ```shell 24 | pip3 install foliantcontrib.swaggerdoc 25 | ``` 26 | 27 | SwaggerDoc preprocessor uses [Widdershins](https://github.com/Mermade/widdershins/) under the hood, so you will need to install that too. 28 | 29 | ```shell 30 | npm install -g widdershins 31 | ``` 32 | 33 | Finally, to build the static website we will be using Slate backend: 34 | 35 | ```shell 36 | pip3 install foliantcontrib.slate 37 | ``` 38 | 39 | Also note that Slate requires [Ruby](https://www.ruby-lang.org/en/) and [Bundler](https://bundler.io/) to work (that’s a lot of dependencies, I know). 40 | 41 | ### Creating project 42 | 43 | Let’s create Foliant project. The easiest way is to use `foliant init` command. After running the command Foliant will ask you about your project name. We’ve chosen "OpenAPI docs", but it may be anything: 44 | 45 | ```shell 46 | cd ~/projects 47 | foliant init 48 | Enter the project name: OpenAPI docs 49 | Generating project... Done 50 | ──────────────────── 51 | Project "OpenAPI docs" created in openapi-docs 52 | ``` 53 | 54 | In the output Foliant informs us that the project was created in a new folder `openapi-docs`. Let’s copy your OpenAPI spec file into this folder: 55 | 56 | ```shell 57 | cp ~/Downloads/my_api.yaml ~/projects/openapi-docs 58 | ``` 59 | 60 | In the end you should get the following directory structure: 61 | 62 | ``` 63 | └── openapi-docs 64 | ├── Dockerfile 65 | ├── README.md 66 | ├── docker-compose.yml 67 | ├── foliant.yml 68 | ├── my_api.yaml 69 | ├── requirements.txt 70 | └── src 71 | └── index.md 72 | ``` 73 | 74 | If you wish to use Docker with full Foliant image, which is the recommended way to build Foliant projects, then open generated `Dockerfile` and replace its contents with the following line: 75 | 76 | ```Dockerfile 77 | FROM foliant/foliant:full 78 | ``` 79 | 80 | ### Configuring project 81 | 82 | Now let’s set up `foliant.yml`. Right now it looks like this: 83 | 84 | ```yaml 85 | title: OpenAPI docs 86 | 87 | chapters: 88 | - index.md 89 | 90 | ``` 91 | 92 | First add and fill up the `preprocessors` section at the bottom: 93 | 94 | ```yaml 95 | preprocessors: 96 | - swaggerdoc: 97 | spec_path: !path my_api.yaml # path to your API spec file, relative to project root 98 | ``` 99 | 100 | At this stage you may also specify path to custom templates dir in `environment: {user_templates: path/to/custom/templates}` parameter. Templates describe the exact way of how to convert structured specification file into a Markdown document. For this tutorial we will be using default templates because they are perfect for our static site. Check [Widdershins docs](https://github.com/Mermade/widdershins#templates) for detailed info on templates. 101 | 102 | The last thing we need to do is point Foliant where to insert the generated Markdown from the spec file. We already have a source file created for us by `init` command, called `index.md`, so let’s use it to store our API docs. 103 | 104 | Open `openapi-docs/src/index.md` with text editor and replace its contents with the following: 105 | 106 | ```html 107 | 108 | ``` 109 | 110 | Foliant will insert generated markdown on the place of this tag during build. You may even add some kind of introduction for the API docs before the tag, if you don’t have such inside your spec file. 111 | 112 | That’s it! All is left to do is run `make` command to build your site. 113 | 114 | ```shell 115 | foliant make site --with slate 116 | Parsing config... Done 117 | Applying preprocessor swaggerdoc... Done 118 | Applying preprocessor slate... Done 119 | Applying preprocessor _unescape... Done 120 | Making site... 121 | ... 122 | Done 123 | ──────────────────── 124 | Result: OpenAPI_docs-2019-11-29.slate/ 125 | ``` 126 | 127 | If you use docker, the command is: 128 | 129 | ```shell 130 | docker-compose run --rm foliant make site --with slate 131 | ``` 132 | 133 | Now if you open the `index.html` from just created `OpenAPI_docs-2019-11-29.slate` folder, you should see something like this: 134 | 135 | ![Slate static site](img/slate.png) 136 | 137 | You can customize the page styles, add or remove language example tabs and tune other options. Check the Slate backend documentation for details. 138 | 139 | ## RAML 140 | 141 | Building API docs from RAML specification is quite similar to that of OpenAPI, the difference is that instead of `swaggerdoc` preprocessor you use `ramldoc`. We will go through all the steps anyway. 142 | 143 | ### Installing prerequisites 144 | 145 | Besides Foliant you will need to install some additional packages on your system. If you are using our full docker image `foliant/foliant:full`, you can skip this chapter. 146 | 147 | First, install the RAMLDoc preprocessor which will convert spec file to Markdown. 148 | 149 | ```shell 150 | pip3 install foliantcontrib.ramldoc 151 | ``` 152 | 153 | RAMLdoc preprocessor uses [raml2html](https://github.com/raml2html/raml2html/) with [full-markdown-theme](https://github.com/Vanderhoof/raml2html-full-markdown-theme/) under the hood, so you will need to install those too. 154 | 155 | ```shell 156 | npm install -g raml2html raml2html-full-markdown-theme 157 | ``` 158 | 159 | Finally, to build the static website we will be using Slate backend. If you don’t have it, run: 160 | 161 | ```shell 162 | pip3 install foliantcontrib.slate 163 | ``` 164 | 165 | Also note that Slate requires [Ruby](https://www.ruby-lang.org/en/) and [Bundler](https://bundler.io/) to work. 166 | 167 | ### Creating project 168 | 169 | Let’s create Foliant project. The easiest way is to use `foliant init` command. After running the command Foliant will ask you about your project name. We’ve chosen "API docs", but it may be anything: 170 | 171 | ```shell 172 | cd ~/projects 173 | foliant init 174 | Enter the project name: API docs 175 | Generating project... Done 176 | ──────────────────── 177 | Project "API docs" created in api-docs 178 | ``` 179 | 180 | In the output Foliant informs us that the project was created in a new folder `api-docs`. Now let’s copy your RAML spec file to this folder: 181 | 182 | ```shell 183 | cp ~/Downloads/my_api.raml ~/projects/api-docs 184 | ``` 185 | 186 | In the end you should get the following directory structure: 187 | 188 | ``` 189 | └── api-docs 190 | ├── Dockerfile 191 | ├── README.md 192 | ├── docker-compose.yml 193 | ├── foliant.yml 194 | ├── my_api.raml 195 | ├── requirements.txt 196 | └── src 197 | └── index.md 198 | ``` 199 | 200 | If you wish to use Docker with full Foliant image, which is the recommended way to build Foliant projects, then open generated `Dockerfile` and replace its contents with the following line: 201 | 202 | ```Dockerfile 203 | FROM foliant/foliant:full 204 | ``` 205 | 206 | ### Configuring project 207 | 208 | Now let’s set up `foliant.yml`. Right now it looks like this: 209 | 210 | ```yaml 211 | title: API docs 212 | 213 | chapters: 214 | - index.md 215 | 216 | ``` 217 | 218 | First add and fill up the `preprocessors` section at the bottom: 219 | 220 | ```yaml 221 | preprocessors: 222 | - ramldoc: 223 | spec_path: !path my_api.yaml # path to your API spec file, relative to project root 224 | ``` 225 | 226 | At this stage you may also specify path to custom templates dir in the `template_dir` parameter. Templates describe the exact way of how to convert structured specification file into a Markdown document. raml2html uses [Nunjucks](https://mozilla.github.io/nunjucks/) templates, which are stored in the theme. So the easiest way to create your own templates is to copy [default](https://github.com/Vanderhoof/raml2html-full-markdown-theme/tree/master/templates/) ones and adjust them to your needs. But we will use the default template which works great with Slate. 227 | 228 | The last thing we need to do is point Foliant where to insert the generated Markdown from the spec file. We already have a source file created for us by `init` command, called `index.md`, so let’s use it to store our API docs. 229 | 230 | Open `api-docs/src/index.md` with text editor and replace its contents with the following: 231 | 232 | ```html 233 | 234 | ``` 235 | 236 | Foliant will insert generated markdown on the place of this tag during build. You may even add some kind of introduction for the API docs before the tag, if you don’t have such in your spec file. 237 | 238 | That’s it! All is left to do is run `make` command to build your site. 239 | 240 | ```shell 241 | foliant make site --with slate 242 | Parsing config... Done 243 | Applying preprocessor ramldoc... Done 244 | Applying preprocessor slate... Done 245 | Applying preprocessor _unescape... Done 246 | Making site... 247 | ... 248 | Project built successfully. 249 | 250 | Done 251 | ──────────────────── 252 | Result: API_docs-2019-11-29.slate/ 253 | ``` 254 | 255 | If you use docker, the command is: 256 | 257 | ```shell 258 | docker-compose run --rm foliant make site --with slate 259 | ``` 260 | 261 | Now if you open the `index.html` from just created `API_docs-2019-11-29.slate` folder, you should see something like this: 262 | 263 | ![Slate static site](img/slate_raml.png) 264 | 265 | You can customize the page styles, add or remove language example tabs and tune other options. Check the Slate backend documentation for details. 266 | 267 | ## Blueprint 268 | 269 | API Blueprint is a Markdown-based API specification format. That’s why the build process differs from that of OpenAPI or RAML: we skip the converting step and just add the specification file as a source. 270 | 271 | ### Installing prerequisites 272 | 273 | To build a static site we will use Aglio backend which is designed specifically for rendering API Blueprint. So first install the backend and [Aglio renderer](https://github.com/danielgtaylor/aglio/) itself: 274 | 275 | ```shell 276 | pip3 install foliantcontrib.aglio 277 | npm install -g aglio 278 | ``` 279 | 280 | ### Creating project 281 | 282 | Let’s create a Foliant project. The easiest way is to use `foliant init` command. After running the command Foliant will ask you about your project name. We’ve chosen "API docs", but it may be anything: 283 | 284 | ```shell 285 | cd ~/projects 286 | foliant init 287 | Enter the project name: API docs 288 | Generating project... Done 289 | ──────────────────── 290 | Project "API docs" created in api-docs 291 | ``` 292 | 293 | In the output Foliant informs us that the project was created in a new folder `api-docs`. Now copy your Blueprint spec file into the `src` subfolder (it’s better to change the extension to `.md` too), replacing "index.md": 294 | 295 | ```shell 296 | cp ~/Downloads/spec.abip ~/projects/api-docs/src/index.md 297 | ``` 298 | 299 | In the end you should get the following directory structure: 300 | 301 | ``` 302 | └── openapi-docs 303 | ├── Dockerfile 304 | ├── README.md 305 | ├── docker-compose.yml 306 | ├── foliant.yml 307 | ├── requirements.txt 308 | └── src 309 | └── index.md 310 | ``` 311 | 312 | If you wish to use Docker with full Foliant image, which is the recommended way to build Foliant projects, then open generated `Dockerfile` and replace its contents with the following line: 313 | 314 | ```Dockerfile 315 | FROM foliant/foliant:full 316 | ``` 317 | 318 | ### Configuring project 319 | 320 | Now check your `foliant.yml`. Right now it looks like this: 321 | 322 | ```yaml 323 | title: API docs 324 | 325 | chapters: 326 | - index.md # this should be your API Blueprint specification 327 | 328 | ``` 329 | 330 | It may be hard to believe, but no other configuration is required! Let’s build our project: 331 | 332 | ```shell 333 | foliant make site --with aglio 334 | Parsing config... Done 335 | Applying preprocessor flatten... Done 336 | Applying preprocessor _unescape... Done 337 | Making site... Done 338 | ──────────────────── 339 | Result: OpenAPI_docs-2019-11-29.aglio 340 | ``` 341 | 342 | If you use docker, the command is: 343 | 344 | ```shell 345 | docker-compose run --rm foliant make site --with aglio 346 | ``` 347 | 348 | Now if you open the `index.html` from just created `API_docs-2019-11-29.aglio` folder, you should see something like this: 349 | 350 | ![Aglio static site](img/aglio1.png) 351 | 352 | It’s not near as attractive as the Slate site we had in previous examples. But don’t worry, Aglio supports styling with CSS and layout control with [Jade](http://jade-lang.com/) templates. It also has several built-in themes, which look much better than the default one. 353 | 354 | Open your `foliant.yml` again and add following lines at the end: 355 | 356 | ```yaml 357 | backend_config: 358 | aglio: 359 | params: 360 | theme-variables: streak 361 | theme-template: triple 362 | ``` 363 | 364 | Now run the same build command: 365 | 366 | ```shell 367 | foliant make site --with aglio 368 | ``` 369 | 370 | And look at the result: 371 | 372 | ![Aglio more beautiful static site](img/aglio2.png) 373 | 374 | Much better! 375 | -------------------------------------------------------------------------------- /template/docs.tex: -------------------------------------------------------------------------------- 1 | \documentclass[a4paper,11pt]{article} 2 | \usepackage[T2A]{fontenc} 3 | \usepackage[utf8]{inputenc} 4 | \usepackage{cmap} % для кодировки шрифтов в pdf 5 | 6 | $if(listings)$ 7 | \usepackage{listings} 8 | \newcommand{\passthrough}[1]{#1} 9 | $endif$ 10 | 11 | \providecommand{\tightlist}{% 12 | \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}} 13 | 14 | \usepackage{epstopdf} 15 | 16 | \usepackage{moresize} 17 | 18 | \newcommand{\HRule}{\rule{\linewidth}{0.5mm}} % для заголовка 19 | 20 | \usepackage[paper=A4,pagesize]{typearea} % для приложения в А3 21 | \usepackage[left=1.6in,top=1.3in,right=1.2in,bottom=2in, nohead]{geometry} 22 | 23 | \setlength{\parindent}{0cm} % убать остступы в начале параграфа 24 | \setlength{\parskip}{5pt} % расстояние между параграфами 25 | 26 | \usepackage{booktabs} 27 | 28 | \renewcommand{\baselinestretch}{1.2} % интерлиньяж 29 | 30 | \pagenumbering{arabic} 31 | 32 | \usepackage{longtable} % таблицы 33 | 34 | \usepackage{lastpage} 35 | 36 | \usepackage{csquotes} % кавычки 37 | 38 | \usepackage{color, framed} % линии на полях 39 | 40 | \usepackage[usenames,dvipsnames]{xcolor} 41 | 42 | \usepackage[bottom,hang,flushmargin]{footmisc} % сноски 43 | \interfootnotelinepenalty=100000 44 | % \renewcommand*\footnoterule{} 45 | \setlength{\skip\footins}{1.2cm} 46 | \setlength{\footnotesep}{0.5cm} 47 | 48 | \usepackage{ulem} 49 | \usepackage[colorlinks=true, linkcolor=darkgray, linktoc=all, anchorcolor=black, urlcolor=cyan, pdfborder={0 0 1}, pdfborderstyle={/S/U/W 1}, linkbordercolor=black, urlbordercolor=cyan, unicode=true, linkbordercolor={1 0 0}]{hyperref} % ссылки 50 | 51 | %\usepackage{fancyvrb} 52 | %\usepackage{spverbatim} % потому что листингс не работает с кириллицей (ну и ладно) 53 | 54 | \colorlet{punct}{red!60!black} 55 | \definecolor{background}{HTML}{d6d6d6} 56 | \definecolor{delim}{RGB}{20,105,176} 57 | \definecolor{gray}{RGB}{247,247,247} 58 | \definecolor{default}{RGB}{0,0,0} 59 | \definecolor{darkblue}{rgb}{0.0,0.0,0.6} 60 | \definecolor{cyan}{rgb}{0.0,0.6,0.6} 61 | \colorlet{numb}{magenta!60!black} 62 | 63 | \usepackage{zref-base} 64 | \usepackage{listings} 65 | %Не выводить номер строки в однострочных листингах 66 | \makeatletter 67 | \newcounter{mylstlisting} 68 | \newcounter{mylstlines} 69 | \lst@AddToHook{PreSet}{% 70 | \stepcounter{mylstlisting}% 71 | \ifnum\mylstlines=1\relax 72 | \lstset{numbers=none} 73 | \else 74 | \lstset{numbers=left} 75 | \fi 76 | \setcounter{mylstlines}{0}% 77 | } 78 | \lst@AddToHook{EveryPar}{% 79 | \stepcounter{mylstlines}% 80 | } 81 | \lst@AddToHook{ExitVars}{% 82 | \begingroup 83 | \zref@wrapper@immediate{% 84 | \zref@setcurrent{default}{\the\value{mylstlines}}% 85 | \zref@labelbyprops{mylstlines\the\value{mylstlisting}}{default}% 86 | }% 87 | \endgroup 88 | } 89 | % \mylstlines print number of lines inside listing caption 90 | \newcommand*{\mylstlines}{% 91 | \zref@extractdefault{mylstlines\the\value{mylstlisting}}{default}{0}% 92 | } 93 | \makeatother 94 | 95 | \newcommand\JSONnumbervaluestyle{\color{OrangeRed}} 96 | \newcommand\JSONstringvaluestyle{\color{OrangeRed}} 97 | 98 | % switch used as state variable 99 | \newif\ifcolonfoundonthisline 100 | 101 | \makeatletter 102 | 103 | 104 | \lstdefinelanguage{XML} 105 | { 106 | basicstyle=\ttfamily\footnotesize, 107 | morestring=[b]", 108 | moredelim=[s][\color{OrangeRed}]{<}{\ }, 109 | moredelim=[s][\color{OrangeRed}]{}, 110 | moredelim=[l][\color{OrangeRed}]{/>}, 111 | moredelim=[l][\color{OrangeRed}]{>}, 112 | morecomment=[s]{}, 113 | morecomment=[s]{}, 114 | commentstyle=\color{gray}, 115 | stringstyle=\color{RoyalBlue}, 116 | identifierstyle=\color{RoyalBlue}, 117 | escapebegin=\begin{russiantext}, 118 | escapeend=\end{russiantext}, 119 | } 120 | 121 | \newenvironment{russiantext}{\color{OrangeRed}}{\ignorespacesafterend} 122 | 123 | \lstdefinelanguage{json}{ 124 | numbers=left, 125 | numberstyle=\tiny, 126 | stepnumber=1, 127 | numbersep=4pt, 128 | showstringspaces=false, 129 | breaklines=true, 130 | escapeinside=ææ, 131 | } 132 | 133 | \lstdefinestyle{json} 134 | { 135 | %basicstyle=\color{maroon}, 136 | showstringspaces = false, 137 | %keywords = {false,true}, 138 | alsoletter = 0123456789., 139 | morestring = [s]{"}{"}, 140 | stringstyle = \ifcolonfoundonthisline\JSONstringvaluestyle\else\color{RoyalBlue}\fi, 141 | MoreSelectCharTable =% 142 | \lst@DefSaveDef{`:}\colon@json{\processColon@json}, 143 | basicstyle = \ttfamily, 144 | keywordstyle = \ttfamily\bfseries, 145 | numbers=left, 146 | numberstyle=\tiny, 147 | stepnumber=1, 148 | numbersep=4pt, 149 | showstringspaces=false, 150 | breaklines=true, 151 | escapeinside=@@, 152 | escapebegin=\begin{russiantext}, 153 | escapeend=\end{russiantext}, 154 | } 155 | 156 | 157 | \lstset{ 158 | upquote=true, 159 | language=json, 160 | aboveskip=10pt, 161 | belowskip=5pt, 162 | extendedchars=true, 163 | basicstyle=\normalsize\ttfamily, 164 | breaklines=true, 165 | showtabs=false, 166 | backgroundcolor=\color{gray}, 167 | breakindent=0pt, 168 | keepspaces=true, 169 | %костыль для кириллицы 170 | literate={а}{{\selectfont\char224}}1 171 | {б}{{\selectfont\char225}}1 172 | {в}{{\selectfont\char226}}1 173 | {г}{{\selectfont\char227}}1 174 | {д}{{\selectfont\char228}}1 175 | {е}{{\selectfont\char229}}1 176 | {ё}{{\"e}}1 177 | {ж}{{\selectfont\char230}}1 178 | {з}{{\selectfont\char231}}1 179 | {и}{{\selectfont\char232}}1 180 | {й}{{\selectfont\char233}}1 181 | {к}{{\selectfont\char234}}1 182 | {л}{{\selectfont\char235}}1 183 | {м}{{\selectfont\char236}}1 184 | {н}{{\selectfont\char237}}1 185 | {о}{{\selectfont\char238}}1 186 | {п}{{\selectfont\char239}}1 187 | {р}{{\selectfont\char240}}1 188 | {с}{{\selectfont\char241}}1 189 | {т}{{\selectfont\char242}}1 190 | {у}{{\selectfont\char243}}1 191 | {ф}{{\selectfont\char244}}1 192 | {х}{{\selectfont\char245}}1 193 | {ц}{{\selectfont\char246}}1 194 | {ч}{{\selectfont\char247}}1 195 | {ш}{{\selectfont\char248}}1 196 | {щ}{{\selectfont\char249}}1 197 | {ъ}{{\selectfont\char250}}1 198 | {ы}{{\selectfont\char251}}1 199 | {ь}{{\selectfont\char252}}1 200 | {э}{{\selectfont\char253}}1 201 | {ю}{{\selectfont\char254}}1 202 | {я}{{\selectfont\char255}}1 203 | {А}{{\selectfont\char192}}1 204 | {Б}{{\selectfont\char193}}1 205 | {В}{{\selectfont\char194}}1 206 | {Г}{{\selectfont\char195}}1 207 | {Д}{{\selectfont\char196}}1 208 | {Е}{{\selectfont\char197}}1 209 | {Ё}{{\"E}}1 210 | {Ж}{{\selectfont\char198}}1 211 | {З}{{\selectfont\char199}}1 212 | {И}{{\selectfont\char200}}1 213 | {Й}{{\selectfont\char201}}1 214 | {К}{{\selectfont\char202}}1 215 | {Л}{{\selectfont\char203}}1 216 | {М}{{\selectfont\char204}}1 217 | {Н}{{\selectfont\char205}}1 218 | {О}{{\selectfont\char206}}1 219 | {П}{{\selectfont\char207}}1 220 | {Р}{{\selectfont\char208}}1 221 | {С}{{\selectfont\char209}}1 222 | {Т}{{\selectfont\char210}}1 223 | {У}{{\selectfont\char211}}1 224 | {Ф}{{\selectfont\char212}}1 225 | {Х}{{\selectfont\char213}}1 226 | {Ц}{{\selectfont\char214}}1 227 | {Ч}{{\selectfont\char215}}1 228 | {Ш}{{\selectfont\char216}}1 229 | {Щ}{{\selectfont\char217}}1 230 | {Ъ}{{\selectfont\char218}}1 231 | {Ы}{{\selectfont\char219}}1 232 | {Ь}{{\selectfont\char220}}1 233 | {Э}{{\selectfont\char221}}1 234 | {Ю}{{\selectfont\char222}}1 235 | {Я}{{\selectfont\char223}}1 236 | } 237 | 238 | % flip the switch if a colon is found in Pmode 239 | \newcommand\processColon@json{% 240 | \colon@json% 241 | \ifnum\lst@mode=\lst@Pmode% 242 | \global\colonfoundonthislinetrue% 243 | \fi 244 | } 245 | 246 | \lst@AddToHook{Output}{% 247 | \ifcolonfoundonthisline% 248 | \ifnum\lst@mode=\lst@Pmode% 249 | \def\lst@thestyle{\JSONnumbervaluestyle}% 250 | \fi 251 | \fi 252 | %override by keyword style if a keyword is detected! 253 | \lsthk@DetectKeywords% 254 | } 255 | 256 | % reset the switch at the end of line 257 | \lst@AddToHook{EOL}% 258 | {\global\colonfoundonthislinefalse} 259 | 260 | \makeatother 261 | 262 | % \lstdefinelanguage{XML} 263 | % { 264 | % morestring=[b]", 265 | % morestring=[s]{>}{<}, 266 | % morecomment=[s]{}, 267 | % stringstyle=\color{black}, 268 | % showstringspaces=false, 269 | % identifierstyle=\color{OrangeRed}, 270 | % keywordstyle=\color{RoyalBlue}, 271 | % morekeywords={xmlns,",type}% list your attributes here 272 | % } 273 | 274 | 275 | % \makeatletter 276 | % \def\verbatim{\small\@verbatim \frenchspacing\@vobeyspaces \@xverbatim} 277 | % \makeatother 278 | 279 | % \makeatletter 280 | % \def\@xobeysp{\mbox{}\space} 281 | % \def\verbatim@font{\normalfont\ttfamily\raggedright} 282 | % \makeatother 283 | 284 | 285 | \usepackage{enumitem} % убираем пустую строку перед списком 286 | \setitemize{noitemsep,topsep=-4.5pt,parsep=4.5pt,partopsep=2pt,leftmargin=*} 287 | \setenumerate{noitemsep,topsep=-4.5pt,parsep=4.5pt,partopsep=2pt,leftmargin=*} 288 | 289 | \usepackage{textcomp} % меняем буллиты 290 | \renewcommand{\labelitemi}{\textemdash} 291 | \renewcommand{\labelitemii}{\textemdash} 292 | \renewcommand{\labelitemiii}{\textemdash} 293 | \renewcommand{\labelitemiv}{\textemdash} 294 | \renewcommand\labelenumi{\theenumi)} 295 | \renewcommand\labelenumii{\theenumi.\arabic{enumii})} 296 | \renewcommand\labelenumiii{\theenumi.\arabic{enumii}.\arabic{enumiii})} 297 | 298 | 299 | %\usepackage[skip=-5pt,margin=-30pt,format=hang,indention=-5.5cm,labelfont={small,bf,sc},textfont=small,justification=justified,singlelinecheck=false]{caption} 300 | \usepackage[labelsep=period, justification=raggedleft, labelfont={small,bf,sc},textfont=small,singlelinecheck=false, skip=15pt]{caption} 301 | 302 | \usepackage{graphicx} % вернул в ширину текста 303 | \makeatletter 304 | \def\maxwidth{\ifdim\Gin@nat@width>1\linewidth 305 | 1\linewidth 306 | \else\Gin@nat@width\fi} 307 | \makeatother 308 | \let\oldincludegraphics\includegraphics % TODO: убрать хак с \, внести его сюда 309 | \renewcommand\includegraphics[2][]{% 310 | \vspace{8mm} 311 | \centerline{ 312 | \oldincludegraphics[width=\maxwidth]{#2} 313 | %\centering 314 | } 315 | %\vspace{-8mm} 316 | } 317 | 318 | %\let\oldincludegraphics\includegraphics 319 | %\renewcommand\includegraphics[2][]{% 320 | % \oldincludegraphics[width=1.2\linewidth]{#2} 321 | % \centering 322 | %} 323 | 324 | \usepackage{tocstyle}% добавляем расстояние между номером и названием в оглавлении 325 | \usetocstyle{allwithdot} 326 | \settocstylefeature[1]{entryhook}{\bfseries} 327 | 328 | \usepackage{amsthm,amsfonts,amsmath,amssymb,amscd} % математика от AMS 329 | \usepackage[warn]{mathtext} 330 | 331 | $if(russian)$ 332 | \usepackage[main=russian, english]{babel} 333 | $endif$ 334 | $if(english)$ 335 | \usepackage[main=english,russian]{babel} 336 | $endif$ 337 | 338 | \let\zz\[\let\zzz\] % лечит баг amsthm 339 | \usepackage[cm-default]{fontspec} % задаем шрифт документа 340 | \setromanfont{PT Sans} 341 | \setmonofont[Mapping=]{PT Mono} 342 | \newfontfamily\monospace[Mapping=]{PT Mono} 343 | \defaultfontfeatures{Ligatures=TeX} 344 | \newfontfamily\headingfont[]{PT Sans} 345 | \newfontfamily\headingfontlight[]{PT Sans} 346 | \newfontfamily\symbolsfont[]{DejaVu Sans} 347 | 348 | \usepackage[Latin, Cyrillics, Symbols]{ucharclasses} 349 | \setTransitionsForSymbols{\begingroup\symbolsfont}{\endgroup} 350 | 351 | 352 | \let\[\zz\let\]\zzz 353 | 354 | 355 | \makeatletter 356 | \def\Sbox#1#2{% 357 | \setbox\z@\vbox{\hsize\maxdimen% 358 | #2\par 359 | \global\setbox#1\box\voidb@x 360 | \loop 361 | \setbox\z@\lastbox 362 | \global\setbox#1\hbox{% 363 | \ifvoid#1\else\unhbox#1\hfill\break\fi 364 | \unhbox\z@ 365 | \unskip\unskip\unpenalty}% 366 | \unskip\unskip\unpenalty 367 | \ifnum\lastnodetype=\@ne 368 | \repeat 369 | }} 370 | % 371 | \def\ttlh@runin#1#2#3#4#5#6#7#8{% 372 | \global\@noskipsectrue 373 | \gdef\ttl@makeline##1{##1}% 374 | \ttl@changecentercr 375 | #1{\ifhmode\ttl@hmode@error\fi 376 | \Sbox%\global\sbox 377 | \ttl@box{% 378 | \ttl@calc\hspace{#6}% 379 | \ifttl@label{\strut#2}\ttl@calc\hspace{#3}\fi 380 | #4{#8}#5\unskip}}% 381 | \gdef\@svsechd{\unhbox\ttl@box}} 382 | \makeatother 383 | 384 | 385 | \usepackage[explicit]{titlesec} % выравниваем названия глав и разделов 386 | 387 | 388 | 389 | \titleformat{name=\chapter,numberless}[display] 390 | {\normalfont\Huge\headingfont}% format 391 | {\llap{% label 392 | \chaptertitlename\thechapter\hskip 9pt}#1}% 393 | {0pt}% horizontal sep 394 | {}% before 395 | 396 | 397 | \titleformat{\section} 398 | {\fontsize{28}{24}\headingfont}%format 399 | {\makebox[0pt][r]{% 400 | \headingfontlight\thesection\hskip 9pt}}% 401 | {0pt} 402 | {\makebox[\dimexpr\linewidth][l]{% 403 | \parbox[t]{\dimexpr\textwidth+\marginparwidth+\marginparsep\relax} 404 | {\raggedright #1}}} 405 | 406 | \titleformat{\subsection}% 407 | {\fontsize{20}{20}\headingfont}%format 408 | {\makebox[0pt][r]{% 409 | \headingfontlight\thesubsection\hskip 9pt}}% 410 | {0pt} 411 | {\makebox[\dimexpr\linewidth][l]{% 412 | \parbox[t]{\dimexpr\textwidth+\marginparwidth+\marginparsep\relax} 413 | {\raggedright #1}}} 414 | 415 | \titleformat{\subsubsection}% 416 | {\fontsize{16}{16}\headingfont}%format 417 | {\makebox[0pt][r]{% 418 | \headingfontlight\thesubsubsection\hskip 9pt}}% 419 | {0pt} 420 | {\makebox[\dimexpr\linewidth][l]{% 421 | \parbox[t]{\dimexpr\textwidth+\marginparwidth+\marginparsep\relax} 422 | {\raggedright #1}}} 423 | 424 | \titleformat{\paragraph}% 425 | {\fontsize{14}{14}\headingfont}%format 426 | {\makebox[0pt][r]{% 427 | \headingfontlight\theparagraph\hskip 9pt}}% 428 | {0pt} 429 | {\makebox[\dimexpr\linewidth][l]{% 430 | \parbox[t]{\dimexpr\textwidth+\marginparwidth+\marginparsep\relax} 431 | {\raggedright #1}}} 432 | 433 | \titleformat{\subparagraph}% 434 | {\headingfont}%format 435 | {\makebox[0pt][r]{% 436 | \headingfontlight\thesubparagraph\hskip 9pt}}% 437 | {0pt} 438 | {\makebox[\dimexpr\linewidth][l]{% 439 | \parbox[t]{\dimexpr\textwidth+\marginparwidth+\marginparsep\relax} 440 | {\raggedright #1}}} 441 | 442 | 443 | % \titleformat{\subparagraph}% 444 | % {\headingfontlight}%format 445 | % {\makebox[0pt][r]{% 446 | % \headingfontlight\thesubparagraph\hskip 9pt}}% 447 | % {0pt} 448 | % {\makebox[\dimexpr\linewidth][l]{% 449 | % \parbox[t]{\dimexpr\textwidth+\marginparwidth+\marginparsep\relax} 450 | % {\raggedright\underline{\textbf{#1}}} 451 | 452 | $if(russian)$ 453 | \renewcommand{\thesection}{\arabic{section}.} % хак, добавляющий точки к заголовкам 454 | \renewcommand{\thesubsection}{\thesection\arabic{subsection}.} 455 | \renewcommand{\thesubsubsection}{\thesubsection 456 | \arabic{subsubsection}.} 457 | \renewcommand{\theparagraph}{\thesubsubsection\arabic{paragraph}.} 458 | \renewcommand{\thesubparagraph}{\theparagraph\arabic{subparagraph}.} 459 | $endif$ 460 | 461 | \titlespacing*{\chapter}{0pt}{2pt}{0.5em} % отступы заголовков 462 | \titlespacing*{\section}{0pt}{2em}{1em} 463 | \titlespacing*{\subsection}{0pt}{1em}{0.1em} 464 | \titlespacing*{\subsubsection}{0pt}{1em}{0.1em} 465 | \titlespacing*{\paragraph}{0pt}{1em}{0em} 466 | \titlespacing*{\subparagraph}{0pt}{1em}{0em} 467 | 468 | 469 | \let\stdsection\section 470 | \renewcommand\section{\newpage\stdsection} % главы с новой страницы 471 | 472 | % \let\stdsubsection\subsection 473 | % \renewcommand\subsection{\newpage\stdsubsection} % разделы с новой страницы 474 | 475 | %\usepackage[final]{microtype} % не работает с xelatex 476 | 477 | $if(date)$ 478 | $if(english)$ 479 | \usepackage[mmddyyyy]{datetime} 480 | $endif$ 481 | $if(russian)$ 482 | \usepackage[ddmmyyyy]{datetime} 483 | $endif$ 484 | %\renewcommand{\dateseparator}{.} 485 | \renewcommand{\dateseparator}{-} % TODO: для auto отдельно 486 | $endif$ 487 | 488 | \usepackage{fancyhdr} % колонтитулы 489 | \fancyhf{} 490 | \pagestyle{fancy} 491 | \fancypagestyle{plain}{% 492 | \fancyfoot[R]{\footnotesize \thepage} 493 | \fancyfoot[L]{\footnotesize \nouppercase{\textit{\rightorleftmark\phantom{.}\textbar\phantom{.}$version$.\today}}}} 494 | \fancyfoot[R]{\footnotesize \thepage} 495 | \fancyfoot[L]{\footnotesize \nouppercase{\textit{\rightorleftmark\phantom{.}\textbar\phantom{.}$version$.\today}}} 496 | \renewcommand{\headrulewidth}{0pt} 497 | \renewcommand{\footrulewidth}{0pt} 498 | \setlength{\footskip}{80.99991pt} 499 | %\renewcommand{\subsubsectionmark}[1]{\markright{\thesubsubsection\ #1}} 500 | \fancypagestyle{titlefooter}{% 501 | \fancyhf{} 502 | $if(russian)$ 503 | $if(restream)$ 504 | \fancyfoot[L]{\textsc{\fontsize{12}{15}\headingfontlight\nohyphens{\pageref{LastPage} страниц, АО «Рестрим» 505 | $if(date)$ 506 | \\[0.1cm] Версия документа $version$-\today 507 | $else$ 508 | , $year$ год 509 | $endif$ 510 | }}} 511 | $endif$ 512 | $endif$ 513 | } 514 | \makeatletter 515 | \newcommand{\rightorleftmark}{% 516 | \begingroup\protected@edef\x{\rightmark}% 517 | \ifx\x\@empty 518 | \endgroup\leftmark 519 | \else 520 | \endgroup\rightmark 521 | \fi} 522 | \makeatother 523 | 524 | \setcounter{secnumdepth}{0} % уровень заголовков 525 | \setcounter{tocdepth}{5} % вывод заголовков всех уровней в оглавление 526 | 527 | \usepackage{newunicodechar} 528 | \newunicodechar{©}{\copyright} 529 | \newunicodechar{™}{\texttrademark} 530 | \newunicodechar{®}{\textregistered} 531 | \newunicodechar{«}{\guillemotleft} 532 | \newunicodechar{»}{\guillemotright} 533 | 534 | \usepackage[protrusion=true]{microtype} % остальные свойства не поддерживаются в XeLaTeX 535 | 536 | \usepackage{hyphenat} 537 | 538 | \usepackage{float} % чтобы таблицы были на месте 539 | \restylefloat{table} 540 | \let\origfigure=\figure % переопределение float-параметра изображений 541 | \let\endorigfigure=\endfigure 542 | \renewenvironment{figure}[1][]{% 543 | \origfigure[H] 544 | }{% 545 | \endorigfigure 546 | } 547 | 548 | \usepackage{longtable} 549 | 550 | \usepackage{changepage} 551 | 552 | \providecommand{\tightlist}{% 553 | \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}} 554 | 555 | \usepackage{etoolbox} 556 | \AtBeginEnvironment{longtable}{\small} %все таблицы меньшим шрифтом 557 | 558 | \usepackage{afterpage} 559 | 560 | \usepackage{mdframed} 561 | 562 | \usepackage{rotating} 563 | 564 | \usepackage{adjustbox} 565 | 566 | \mdfdefinestyle{redbar}{% 567 | linewidth=1pt, 568 | topline=false, 569 | rightline=false, 570 | bottomline=false, 571 | linecolor=red, 572 | % innertopmargin=1.2\baselineskip, 573 | % skipabove={\dimexpr0.5\baselineskip+\topskip\relax}, 574 | % needspace=2\baselineskip, 575 | leftmargin=-1em 576 | rightmargin=1em 577 | } 578 | 579 | \usepackage{ragged2e} 580 | 581 | %orphan control 582 | \widowpenalty10000 583 | \clubpenalty10000 584 | 585 | 586 | \begin{document} 587 | \righthyphenmin=2 588 | \lefthyphenmin=2 589 | \sloppy % плохо для типографики 590 | 591 | \begin{titlepage} 592 | \includegraphics[scale=0.15]{$logo$} 593 | \vspace*{\fill} 594 | \vspace{-5cm} 595 | $if(subtitle)$ 596 | \textsc{\fontsize{28}{30}\headingfont\RaggedRight\nohyphens{$title$}}\\[0.5cm] 597 | $endif$ 598 | \fontsize{22}{30}\headingfontlight\RaggedRight\nohyphens{$subtitle$}\\ 599 | \vfill 600 | \thispagestyle{titlefooter} 601 | \end{titlepage} 602 | 603 | $if(toc)$ 604 | \tableofcontents 605 | \newpage 606 | $endif$ 607 | $body$ 608 | $if(tof)$ 609 | \newpage 610 | \listoffigures 611 | $endif$ 612 | \end{document} 613 | --------------------------------------------------------------------------------