docs: Initial Sphinx setup
Signed-off-by: Filip Kokosinski <fkokosinski@antmicro.com>
|
@ -0,0 +1,3 @@
|
|||
*.png binary
|
||||
*.gif binary
|
||||
*.jpg binary
|
|
@ -0,0 +1 @@
|
|||
_build
|
|
@ -0,0 +1,20 @@
|
|||
# Minimal makefile for Sphinx documentation
|
||||
#
|
||||
|
||||
# You can set these variables from the command line, and also
|
||||
# from the environment for the first two.
|
||||
SPHINXOPTS ?=
|
||||
SPHINXBUILD ?= sphinx-build
|
||||
SOURCEDIR = .
|
||||
BUILDDIR = _build
|
||||
|
||||
# Put it first so that "make" without argument is like "make help".
|
||||
help:
|
||||
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
||||
|
||||
.PHONY: help Makefile
|
||||
|
||||
# Catch-all target: route all unknown targets to Sphinx using the new
|
||||
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
|
||||
%: Makefile
|
||||
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
|
@ -0,0 +1,82 @@
|
|||
Building example designs
|
||||
========================
|
||||
|
||||
Before building any example, set the installation directory to match what you
|
||||
set it to earlier, for example:
|
||||
|
||||
.. code-block:: bash
|
||||
:name: export-install-dir
|
||||
|
||||
export INSTALL_DIR=~/opt/symbiflow
|
||||
|
||||
Select your fpga family:
|
||||
|
||||
.. tabs::
|
||||
|
||||
.. group-tab:: Artix-7
|
||||
|
||||
.. code-block:: bash
|
||||
:name: fpga-fam-xc7
|
||||
|
||||
FPGA_FAM="xc7"
|
||||
|
||||
.. group-tab:: EOS S3
|
||||
|
||||
.. code-block:: bash
|
||||
:name: fpga-fam-eos-s3
|
||||
|
||||
FPGA_FAM="eos-s3"
|
||||
|
||||
Next, prepare the enviroment:
|
||||
|
||||
.. code-block:: bash
|
||||
:name: conda-prep-env
|
||||
|
||||
export PATH="$INSTALL_DIR/$FPGA_FAM/install/bin:$PATH";
|
||||
source "$INSTALL_DIR/$FPGA_FAM/conda/etc/profile.d/conda.sh"
|
||||
|
||||
Finally, enter your working Conda enviroment:
|
||||
|
||||
.. code-block:: bash
|
||||
:name: conda-act-env
|
||||
|
||||
conda activate $FPGA_FAM
|
||||
|
||||
.. note::
|
||||
|
||||
If you don't know how to upload any of the following examples onto your
|
||||
development board, please refer to the Running examples section.
|
||||
|
||||
|
||||
Xilinx 7-Series
|
||||
---------------
|
||||
|
||||
Enter the directory that contains examples for Xilinx 7-Series FPGAs:
|
||||
|
||||
.. code-block:: bash
|
||||
:name: enter-dir-xc7
|
||||
|
||||
cd xc7
|
||||
|
||||
.. jinja:: xc7_counter_test
|
||||
:file: templates/example.jinja
|
||||
|
||||
.. jinja:: xc7_picosoc_demo
|
||||
:file: templates/example.jinja
|
||||
|
||||
.. jinja:: xc7_linux_litex_demo
|
||||
:file: templates/example.jinja
|
||||
|
||||
|
||||
QuickLogic EOS S3
|
||||
-----------------
|
||||
|
||||
Enter the directory that contains examples for QuickLogic EOS S3:
|
||||
|
||||
.. code-block:: bash
|
||||
:name: enter-dir-eos-s3
|
||||
|
||||
cd eos-s3
|
||||
|
||||
.. jinja:: eos-s3_btn_counter
|
||||
:file: templates/example.jinja
|
|
@ -0,0 +1,247 @@
|
|||
# Configuration file for the Sphinx documentation builder.
|
||||
#
|
||||
# This file only contains a selection of the most common options. For a full
|
||||
# list see the documentation:
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html
|
||||
|
||||
# -- Path setup --------------------------------------------------------------
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
#
|
||||
# import os
|
||||
# import sys
|
||||
# sys.path.insert(0, os.path.abspath('.'))
|
||||
|
||||
|
||||
# -- Project information -----------------------------------------------------
|
||||
|
||||
project = u'SymbiFlow examples'
|
||||
authors = u'SymbiFlow'
|
||||
copyright = authors + u', 2020'
|
||||
|
||||
# -- General configuration ---------------------------------------------------
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
# ones.
|
||||
extensions = [
|
||||
'sphinx_tabs.tabs',
|
||||
'sphinxcontrib.jinja',
|
||||
]
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
# This pattern also affects html_static_path and html_extra_path.
|
||||
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
|
||||
|
||||
|
||||
# -- Options for HTML output -------------------------------------------------
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
#
|
||||
|
||||
html_show_sourcelink = True
|
||||
html_sidebars = {
|
||||
"**": ["logo-text.html", "globaltoc.html", "localtoc.html", "searchbox.html"]
|
||||
}
|
||||
|
||||
html_theme = 'sphinx_material'
|
||||
html_theme_options = {
|
||||
'nav_title': project,
|
||||
'color_primary': 'deep-purple',
|
||||
'color_accent': 'purple',
|
||||
'repo_name': "antmicro/symbiflow-examples",
|
||||
'repo_url': 'https://github.com/antmicro/symbiflow-examples',
|
||||
'globaltoc_depth': 2,
|
||||
'globaltoc_collapse': True
|
||||
}
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
# html_static_path = ['_static']
|
||||
|
||||
import os
|
||||
from docutils.core import publish_doctree
|
||||
|
||||
|
||||
full_name_lut = {
|
||||
'a35t': 'Arty 35T',
|
||||
'a100t': 'Arty 100T',
|
||||
'basys3': 'Basys 3',
|
||||
'eos_s3': 'EOS S3',
|
||||
}
|
||||
families = ('xc7', 'eos-s3')
|
||||
|
||||
|
||||
def handle_default_with_literals(block):
|
||||
text = ""
|
||||
|
||||
for node in block.traverse(include_self=False, condition=lambda x:
|
||||
x.parent.tagname.strip() != 'literal'):
|
||||
tagname = node.tagname.strip()
|
||||
if tagname in ('paragraph',):
|
||||
continue
|
||||
|
||||
if tagname == 'literal':
|
||||
text = text + '``' + node.astext() + '``'
|
||||
else:
|
||||
text = text + node.astext()
|
||||
|
||||
ret = {}
|
||||
ret['type'] = block.tagname.strip()
|
||||
ret['text'] = text
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
def subtree_has_tag(block, tagname):
|
||||
for node in block.traverse(include_self=False):
|
||||
if node.tagname.strip() == tagname:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def handle_title(block):
|
||||
ret = {
|
||||
'type': 'title',
|
||||
'text': '\n'.join((block.astext(), '~' * 20)),
|
||||
}
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
def handle_img(block):
|
||||
ret = {}
|
||||
ret['type'] = 'image'
|
||||
ret['uri'] = os.path.join(*block['uri'].split('/')[3:])
|
||||
ret['align'] = block.get('align', 'center')
|
||||
ret['width'] = block.get('width', '100%')
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
def handle_literal_block(block):
|
||||
ret = {}
|
||||
ret['type'] = 'literal_block'
|
||||
ret['text'] = block.astext().split('\n')
|
||||
ret['classes'] = block['classes']
|
||||
|
||||
try:
|
||||
ret['name'] = full_name_lut[''.join(block['names']).split('-')[2]]
|
||||
except:
|
||||
ret['name'] = ''
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
def handle_note(block):
|
||||
ret = {}
|
||||
ret['type'] = block.tagname.strip()
|
||||
|
||||
if subtree_has_tag(block, 'literal'):
|
||||
for node in block.traverse(condition=lambda x:
|
||||
x.tagname.strip() == 'paragraph'):
|
||||
ret['text'] = handle_default_with_literals(node)['text']
|
||||
else:
|
||||
ret['text'] = block.astext()
|
||||
|
||||
ret['text'] = ret['text'].split('\n')
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
def handle_default(block):
|
||||
if subtree_has_tag(block, 'literal'):
|
||||
return handle_default_with_literals(block)
|
||||
|
||||
ret = {}
|
||||
ret['type'] = block.tagname.strip()
|
||||
ret['text'] = block.astext()
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
handle_block_funcs = {
|
||||
'title': handle_title,
|
||||
'image': handle_img,
|
||||
'literal_block': handle_literal_block,
|
||||
'note': handle_note,
|
||||
'default': handle_default,
|
||||
}
|
||||
|
||||
|
||||
def get_blocks(text):
|
||||
doctree = publish_doctree(text)
|
||||
|
||||
return doctree.traverse(condition=lambda x: x.tagname.strip() != 'document'
|
||||
and x.parent.tagname.strip() != 'note')
|
||||
|
||||
|
||||
def fill_context(text):
|
||||
ret = []
|
||||
|
||||
start_group = False
|
||||
in_group = False
|
||||
for block in get_blocks(text):
|
||||
tagname = block.tagname.strip()
|
||||
|
||||
# do not process those
|
||||
if tagname in ('#text', 'inline', 'literal'):
|
||||
continue
|
||||
|
||||
# try do get handler; if not found, use the default one
|
||||
if tagname not in handle_block_funcs.keys():
|
||||
handler = 'default'
|
||||
else:
|
||||
handler = tagname
|
||||
|
||||
entry = handle_block_funcs[handler](block)
|
||||
|
||||
# internal logic for grouping code blocks into tab groups
|
||||
if tagname == 'literal_block' and 'group' in ''.join(block['names']):
|
||||
if not in_group:
|
||||
start_group = True
|
||||
in_group = True
|
||||
else:
|
||||
start_group = False
|
||||
in_group = True
|
||||
else:
|
||||
in_group = False
|
||||
start_group = False
|
||||
|
||||
entry['start_group'] = start_group
|
||||
entry['in_group'] = in_group
|
||||
|
||||
ret.append(entry)
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
# register examples
|
||||
jinja_contexts = {}
|
||||
top_dir = os.path.join(os.path.dirname(__file__), '..')
|
||||
for family in families:
|
||||
examples = os.scandir(os.path.join(top_dir, family))
|
||||
for example in examples:
|
||||
if example.is_dir():
|
||||
|
||||
# get README
|
||||
path = os.path.join(top_dir, family, example, 'README.rst')
|
||||
|
||||
# skip if file does not exist
|
||||
if not os.path.isfile(path):
|
||||
continue
|
||||
|
||||
with open(path) as f:
|
||||
text = f.read()
|
||||
|
||||
key = '_'.join((family, example.name))
|
||||
jinja_contexts[key] = {'blocks': fill_context(text)}
|
|
@ -0,0 +1,137 @@
|
|||
Getting SymbiFlow
|
||||
=================
|
||||
|
||||
This section describe how to install SymbiFlow and setup a fully working
|
||||
enviroment to later build example desings.
|
||||
|
||||
Prerequisites
|
||||
-------------
|
||||
|
||||
To be able to follow through this tutorial, install the following software:
|
||||
|
||||
.. tabs::
|
||||
|
||||
.. group-tab:: Ubuntu
|
||||
|
||||
.. code-block:: bash
|
||||
:name: install-reqs-ubuntu
|
||||
|
||||
apt install -y git wget picocom
|
||||
|
||||
.. group-tab:: CentOS
|
||||
|
||||
.. code-block:: bash
|
||||
:name: install-reqs-centos
|
||||
|
||||
yum install -y git wget picocom
|
||||
|
||||
.. group-tab:: Arch
|
||||
|
||||
.. code-block:: bash
|
||||
:name: install-reqs-arch
|
||||
|
||||
pacman -Sy git wget picocom
|
||||
|
||||
Next, clone the SymbiFlow examples repository and enter it:
|
||||
|
||||
.. code-block:: bash
|
||||
:name: get-symbiflow
|
||||
|
||||
git clone https://github.com/SymbiFlow/symbiflow-examples
|
||||
cd symbiflow-examples
|
||||
|
||||
Toolchain installation
|
||||
----------------------
|
||||
|
||||
Now we are able to install the SymbiFlow toolchain. This procedure is divided
|
||||
into three steps:
|
||||
|
||||
- installing the Conda package manager,
|
||||
- choosing an installation directory,
|
||||
- downloading the architecture definitions and installing the toolchain.
|
||||
|
||||
Conda
|
||||
~~~~~
|
||||
|
||||
Download Conda installer script:
|
||||
|
||||
.. code-block:: bash
|
||||
:name: wget-conda
|
||||
|
||||
wget https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -O conda_installer.sh
|
||||
|
||||
Choose the install directory
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The install directory can either be in your home directory
|
||||
such as ``~/opt/symbiflow`` or in a system directory such as ``/opt/symbiflow``.
|
||||
If you choose a system directory, you will need root permission to perform the installation,
|
||||
and so you will need to add some ``sudo`` commands to the instructions below.
|
||||
|
||||
.. code-block:: bash
|
||||
:name: conda-install-dir
|
||||
|
||||
export INSTALL_DIR=~/opt/symbiflow
|
||||
|
||||
Toolchain
|
||||
~~~~~~~~~
|
||||
|
||||
Select your target FPGA family:
|
||||
|
||||
.. tabs::
|
||||
|
||||
.. group-tab:: Artix-7
|
||||
|
||||
.. code-block:: bash
|
||||
:name: fpga-fam-xc7
|
||||
|
||||
export FPGA_FAM=xc7
|
||||
|
||||
.. group-tab:: EOS S3
|
||||
|
||||
.. code-block:: bash
|
||||
:name: fpga-fam-eos-s3
|
||||
|
||||
export FPGA_FAM=eos-s3
|
||||
|
||||
Next, setup Conda and your system's enviroment:
|
||||
|
||||
.. code-block:: bash
|
||||
:name: conda-setup
|
||||
|
||||
bash conda_installer.sh -u -b -p $INSTALL_DIR/$FPGA_FAM/conda;
|
||||
source "$INSTALL_DIR/$FPGA_FAM/conda/etc/profile.d/conda.sh";
|
||||
conda env create -f $FPGA_FAM/environment.yml
|
||||
|
||||
Download architecture definitions:
|
||||
|
||||
.. tabs::
|
||||
|
||||
.. group-tab:: Artix-7
|
||||
|
||||
.. code-block:: bash
|
||||
:name: download-arch-def-xc7
|
||||
|
||||
mkdir -p $INSTALL_DIR/xc7/install;
|
||||
wget -qO- https://storage.googleapis.com/symbiflow-arch-defs/artifacts/prod/foss-fpga-tools/symbiflow-arch-defs/presubmit/install/1049/20201123-030526/symbiflow-arch-defs-install-05bd35c7.tar.xz | tar -xJC $INSTALL_DIR/xc7/install;
|
||||
mkdir -p $INSTALL_DIR/xc7/install/share/symbiflow/arch;
|
||||
wget -qO- https://storage.googleapis.com/symbiflow-arch-defs/artifacts/prod/foss-fpga-tools/symbiflow-arch-defs/presubmit/install/1049/20201123-030526/symbiflow-xc7a50t_test.tar.xz | tar -xJC $INSTALL_DIR/xc7/install/share/symbiflow/arch;
|
||||
wget -qO- https://storage.googleapis.com/symbiflow-arch-defs/artifacts/prod/foss-fpga-tools/symbiflow-arch-defs/presubmit/install/1049/20201123-030526/symbiflow-xc7a100t_test.tar.xz | tar -xJC $INSTALL_DIR/xc7/install/share/symbiflow/arch
|
||||
|
||||
.. group-tab:: EOS-S3
|
||||
|
||||
.. code-block:: bash
|
||||
:name: download-arch-def-eos-s3
|
||||
|
||||
wget -qO- https://quicklogic-my.sharepoint.com/:u:/p/kkumar/EWuqtXJmalROpI2L5XeewMIBRYVCY8H4yc10nlli-Xq79g?download=1 | tar -xJ -C $INSTALL_DIR/eos-s3/
|
||||
|
||||
If the above commands exited without errors, you have successfuly installed and configured your working enviroment.
|
||||
|
||||
Build Example Designs
|
||||
---------------------
|
||||
|
||||
With the toolchain installed, you can build the example designs.
|
||||
The example designs are provided in separate directories:
|
||||
|
||||
* ``xc7`` directory for the Artix-7 devices
|
||||
* ``eos-s3`` directory for the EOS S3 devices
|
After Width: | Height: | Size: 391 KiB |
After Width: | Height: | Size: 401 KiB |
After Width: | Height: | Size: 369 KiB |
After Width: | Height: | Size: 371 KiB |
After Width: | Height: | Size: 1.1 MiB |
After Width: | Height: | Size: 6.2 MiB |
After Width: | Height: | Size: 103 KiB |
After Width: | Height: | Size: 58 KiB |
After Width: | Height: | Size: 3.7 MiB |
After Width: | Height: | Size: 5.4 MiB |
After Width: | Height: | Size: 58 KiB |
After Width: | Height: | Size: 54 KiB |
|
@ -0,0 +1,30 @@
|
|||
Welcome to SymbiFlow examples!
|
||||
==============================
|
||||
|
||||
This guide explains how to get started with SymbiFlow and build example designs from the `SymbiFlow Examples <https://github.com/antmicro/symbiflow-examples>`_ GitHub repository. It currently focuses on two FPGA families:
|
||||
|
||||
- Artix-7 from Xilinx,
|
||||
- EOS S3 from QuickLogic.
|
||||
|
||||
Follow this guide to:
|
||||
|
||||
- :doc:`install SymbiFlow <getting-symbiflow>` and all of its dependencies,
|
||||
- :doc:`build <building-examples>` and :doc:`upload <running-examples>` example designs onto the devboard of your choice.
|
||||
|
||||
About SymbiFlow
|
||||
---------------
|
||||
|
||||
SymbiFlow is a fully open source toolchain for the development of FPGAs, currently targeting chips from multiple vendors, e.g.:
|
||||
|
||||
- Xilinx 7-Series
|
||||
- Lattice iCE40
|
||||
- Lattice ECP5 FPGAs
|
||||
- QuickLogic EOS S3
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:caption: Sections
|
||||
|
||||
getting-symbiflow
|
||||
building-examples
|
||||
running-examples
|
|
@ -0,0 +1,4 @@
|
|||
Sphinx==3.3.0
|
||||
sphinx-material==0.0.32
|
||||
sphinx-tabs==1.3.0
|
||||
sphinx-jinja==1.1.1
|
|
@ -0,0 +1,123 @@
|
|||
Running example designs
|
||||
========================
|
||||
|
||||
This section desribes how to properly connect your board.
|
||||
It also helps you configure and run any other software that is necessary to observe results.
|
||||
|
||||
Connecting development boards
|
||||
-----------------------------
|
||||
|
||||
Arty board
|
||||
~~~~~~~~~~
|
||||
|
||||
#. Connect the board to your computer using the USB cable:
|
||||
#. Connect the board to your computer using the Ethernet cable
|
||||
(only if you want to test the LiteX Linux Example)
|
||||
|
||||
.. image:: images/arty-usb-ethernet.png
|
||||
:width: 49%
|
||||
:align: center
|
||||
|
||||
Basys 3 board
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
Connect the Basys3 Board to your computer using the USB cable:
|
||||
|
||||
.. image:: images/basys3-usb.png
|
||||
:width: 49%
|
||||
:align: center
|
||||
|
||||
Connecting to UART
|
||||
------------------
|
||||
|
||||
First check available teletypes with:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
ls -l /dev | grep ttyUSB
|
||||
|
||||
You should see at least one, e.g.:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
crw-rw----+ 1 root plugdev 188, 0 11-06 13:58 ttyUSB0
|
||||
crw-rw----+ 1 root plugdev 188, 1 11-06 13:58 ttyUSB1
|
||||
|
||||
Simply use ``picocom`` to connect:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
picocom -b 115200 --imap lfcrlf /dev/ttyUSB1
|
||||
|
||||
.. warning::
|
||||
|
||||
Substitute ``115200`` with the baud rate that your design uses!
|
||||
|
||||
.. warning::
|
||||
|
||||
Please note that ``/dev/ttyUSB1`` is just an example. The number appearing may change!
|
||||
|
||||
.. note::
|
||||
|
||||
If the picocom is unable to connect to any ``ttyUSBx`` device, you probably don't have appropriate user permissions.
|
||||
On Debian distributions, type the command below to add the user to the ``dialout`` group.
|
||||
This should resolve the missing permissions problem:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
sudo usermod -a -G dialout `whoami`
|
||||
|
||||
Setting up TFTP
|
||||
---------------
|
||||
|
||||
It is assumed that the server is running on port ``6069`` and uses ``/tftp`` directory.
|
||||
|
||||
#. Install tftp with (Ubuntu example):
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
sudo apt install tftpd-hpa
|
||||
|
||||
#. Create a directory for the server:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
sudo mkdir -p /tftp
|
||||
sudo chmod 777 -R /tftp
|
||||
sudo chown tftp -R /tftp
|
||||
|
||||
#. Set up your TFTP configuration with:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
cat << EOF | sudo tee /etc/default/tftpd-hpa
|
||||
TFTP_USERNAME="tftp"
|
||||
TFTP_DIRECTORY="/tftp"
|
||||
TFTP_ADDRESS=":6069"
|
||||
TFTP_OPTIONS="--secure"
|
||||
EOF
|
||||
|
||||
#. Restart the TFTP server:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
sudo systemctl restart tftpd-hpa
|
||||
|
||||
Configuring your network interfaces
|
||||
-----------------------------------
|
||||
|
||||
Check your network interfaces with:
|
||||
|
||||
.. code-block::
|
||||
|
||||
ip link
|
||||
|
||||
Add IPv4 address to you interface:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
ip addr add 192.168.100.100/24 dev eth0
|
||||
|
||||
.. warning::
|
||||
|
||||
``192.169.100.100/24`` and ``eth0`` are just examples!
|
|
@ -0,0 +1,51 @@
|
|||
{% for block in blocks -%}
|
||||
|
||||
{% if block.type == 'literal_block' %}
|
||||
|
||||
{% if not block.start_group and not block.in_group %}
|
||||
.. code-block:: {% if 'bash' in block.classes %}bash{% endif %}
|
||||
|
||||
{% for line in block.text -%}
|
||||
{{ line }}
|
||||
{% endfor %}
|
||||
|
||||
{% elif block.start_group %}
|
||||
.. tabs::
|
||||
|
||||
.. group-tab:: {{ block.name }}
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
{% for line in block.text -%}
|
||||
{{ line }}
|
||||
{% endfor %}
|
||||
{% elif block.in_group %}
|
||||
.. group-tab:: {{ block.name }}
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
{% for line in block.text -%}
|
||||
{{ line }}
|
||||
{% endfor %}
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% elif block.type == 'image' %}
|
||||
.. image:: {{ block.uri }}
|
||||
:align: {{ block.align }}
|
||||
:width: {{ block.width }}
|
||||
|
||||
{% elif block.type == 'note' %}
|
||||
.. note::
|
||||
|
||||
{% for line in block.text -%}
|
||||
{{ line }}
|
||||
{% endfor %}
|
||||
|
||||
|
||||
{% else %}
|
||||
{{ block.text }}
|
||||
|
||||
{% endif %}
|
||||
|
||||
{% endfor %}
|