Getting Started with Development

Alessandro Marin
Center for Computation in Science Education (CCSE), Department of Physics, University of Oslo

Nov 27, 2021


DocOnce is an open source project. The aim of this guide is to help getting started with development. It describes the program's structure and how to set up a script that runs DocOnce from a Python IDE.

Program Structure

The entry point bin/doconce

The entry point of the doconce program is the file bin/doconce. In fact, the setup.py file contains this line invoking the scripts option to run commands from terminal:

setup(...,
  scripts = ['bin/doconce'],
)

Read more about setup.py on this page: setuptools

The main function in /bin/doconce starts processing the doconce command and sends it to different scripts.

Any doconce format command is passed to the format() function, which in turn calls format_driver() in lib/doconce/doconce.py.

The doconce format --help command is passed help_format(). Other commands including undefined ones are handled locally.

Most of the commands are handled by the eval function:

retval = eval(command + '()')

which passes execution to specific function that are imported in the beginning of the script.

Python scripts in lib/doconce/

The lib/doconce/ directory contains the scripts to run DocOnce. The name of the files give a clue about their purpose, e.g. html.py contains code that is run by doconce format html. The doconce.py file contains important formatting functions such as doconce_format(), preprocess(), doconce2format(), file2file().

I suggest navigating through the scripts by using an IDE with debugger. See the the section Running DocOnce in a IDE.

Synching the docs and test folders

The documentation and tests for DocOnce are stored in their own GitHub repositories: doconce_doc and doconce_tests, respectively. These two repositories are git-submodules, i.e. they are included in the main doconce repository as subdirectories. The subdirectories for doconce_doc and doconce_tests are the doc and test folders, respectively. This structure was chosen to improve modularization and the disk footprint of the main doconce repository.

The content of the doc and test folders can be downloaded by running this command after cloning the doconce repository:

git submodule update --init

Running Tests

Tests are implemented in the doconce_tests git-submodule, which can be downloaded as explained above to the test folder.

See the instructions in the test/README.md file to install additional requirements for the tests and how to run them.

Running DocOnce in a IDE

The following code can be used in a IDE such as PyCharm, Eclipse, Microsoft Visual Studio, or others.

import sys, os
# Add the doconce installation directory to the path
HOME = os.getenv("HOME")
sys.path.insert(0, os.path.join(HOME, 'doconce/lib'))
# Load the doconce.py file
from doconce import doconce

# Format to html
os.chdir(os.path.join(HOME, 'doconce/test'))
sys.argv = ['doconce format', 'html', 'testdoc.do.txt','--html_output=temp','--execute']
doconce.format_driver()
sys.exit()  #stop execution here

# Create a jupyterbook
from doconce.jupyterbook import jupyterbook
os.chdir(os.path.join(HOME, 'doconce/test/mybook'))
sys.argv = ['doconce jupyterbook', 'jupyterbook.do.txt',
            '--sep=section', '--sep_section=subsection',
            '--dest=content','--dest_toc=.',
            '--titles=titles.txt', 
            '--allow_refs_to_external_docs']
jupyterbook()
print(os.system('jupyter-book build .'));
sys.exit()  #stop execution here

# Format to latex
os.chdir(os.path.join(HOME, 'doconce/test'))
sys.argv = ['doconce format', 'latex', 'execute.do.txt', 
            '--execute', 
            '--latex_font=helvetica', '--latex_code_style=pyg']
doconce.format_driver()
# Run a function in a py script
from doconce.misc import ptex2tex;
ptex2tex()
os.system('pdflatex -shell-escape execute.tex');
os.system('dvipdf execute.dvi');
os.system('xreader execute.pdf');

As an example for PyCharm, see the guide Create and edit run/debug configurations to set up create and edit run/debug configurations. I suggest using a virtual environment as Python interpreter. Also install DocOnce in development mode so that the doconce command will get updated when you edit its code:

# Create a virtual environment
python -m venv venv
source venv/bin/activate
# Install dependencies and DocOnce in development mode
(venv) pip install -r requirements.txt
(venv) pip install -e .

Compiling the Documentation

The documentation is implemented in the doconce_doc git-submodule, which can be downloaded as explained above to the doc folder.

The documentation is written as DocOnce .do.txt files in different folder inside doc/src/, for example doc/src/manual/, doc/src/quickref/, doc/src/tutorial/. These folders contains a make.sh file that can be run in bash to create documentation in different formats:

bash make.sh

All relevant output files are copied to doc/pub for publication on the github website.

Add a New Language

The translations are defined in the lib/doconce/globals.py file, and test files are in the locale directory. Also read the Support for non-English section of the manual.

Push your code using git

I suggest the following procedure

git remote add upstream https://github.com/doconce/doconce.git
git remote -v     # verify, there should be two `origin` and two `upstream`
# Keep some files
git add -f keep_this_file.txt
cd test
git add -f keep_this_file_in_test.txt
cd ..
# This removes all new/untracked files
git submodule foreach git clean -fd
git clean -fd
# First add and commit in submodules ..
cd doc
git add .
git commit -am "commit changes in doc submodule"
cd ..
cd test
git add . 
git commit -am "commit changes in test submodule"
cd ..
# .. then do the same in the superproject
git add -A .
git commit -am "some description"
git push --recurse-submodules=on-demand
git checkout main     # Switch to the main branch
git fetch upstream 
git rebase upstream/main  #Update the code to the remote version (the main DocOnce repository)
git push              #Push the updates to my fork