Questaal Home
Navigation

Site Contribution Guide

Table of Contents

About This Page


This page serves as a reference for how to write documentation and tutorials for the Questaal site. It includes a basic overview of how to use the Kramdown markup language, stylistic guidelines for documentation and tutorials, how to integrate the document in to the site and how to write unit tests for tutorials. This guide is aimed at those who want to write their own content or improve on other content and is not relevant if you only wish to use Questaal.

Generally we do not give out access to the website repository so if you would like to make a contribution please refer to the contact page in order to get in touch with the developers (Note: repository access can be granted on a case-by-case basis if necessary).

Using Kramdown


The website uses the Kramdown markup language (a superset of the Markdown markup language) to write documents which are then parsed by Jekyll to create static HTML files. Jekyll also allows for the use of the Liquid templating language within Kramdown documents. Documentation for Kramdown, Jekyll and Liquid can be found here, here and here respectively and it would be worth reading through each to get an idea of what tools you have access to when writing new documents.

Most documents will not need the advanced functionality provided by Jekyll or Liquid and are essentially text documents with light formatting.

This section will go over some basic Kramdown syntax (all of which can be found in the aforementioned Kramdown documentation) as well as a small amount of custom Liquid syntax.

Headers


A line becomes a header (HTML tags) by prepending one or more # to the start of the line. The number of # determines the level of the header with one # denoting the most important header, ## a subheader, ### a subsubheader and so on. These headers are important for the generation of the table of contents with, for example, ## being a child of the first # header found as you traverse the document in reverse. You can find an example below.

# Header 1
...
## Subheader 1
...
# Header 2
...
## Subheader 2
...
### Subsubheader 2
...

Text Emphasis


Emphasizing text is simply a matter of enclosing the word, or phrase, in one or two asterisks or underlines. Either one can be used, but you must close the emphasis with the same character used to open it as well as with the same number (two asterisks must close two asterisks, one underline must close one underline and so on). One asterisk/underline will italicize text while two will embolden it. _italics_ works, as does **bold**, but _italics* does not.

Colours


Individual words and phrases can be coloured with some Liquid syntax. The general way of colouring a word is to append {: style="color: blue"} to the word, replacing “blue” with any valid CSS color. You must surround the word or phrase with asterisks or underlines (this also applies text emphasis to the word or phrase as detailed previously) before colouring will work. Finally, there is some stylistic guidelines on how to color certain words and phrases and some syntax shortcuts exist to properly format these words (where these are used are detailed below). Here are some examples.

_Foo_{:.exec}
_This is green!_{:.path}
_I am an executable_{:.exec}

Note: the spelling of color in each command is deliberate!

Code Blocks


Code blocks allow you to create a block of text that stands out from the surroundings using a background and mono-space font, while maintaining the formatting of the block (specifically spacing and new lines, which would otherwise be ignored). Both in-line and block code exists. In-line code can be used by surrounding text with back ticks `like so`. Block level code requires either indenting each line of the text by 4 spaces relative to the parent indentation with a blank line before and after the code block, or surround the block with three ~ characters as shown below

~~~
This is block-level code
~~~

Drop down boxes are not included within the standard Kramdown or Liquid syntax and are implemented as a custom Liquid plugin. Below is a syntax example for the dropdown box, where the dropdown shows the syntax for the box itself:

This can simply be used by copying the syntax, replacing Drop Down Boxes with the text to appear on the button, and replacing the Content with whatever you want to show! It is important to note that the button text should not be enclosed in quotation marks.

Math


Mathematical expressions can be added in-line within the markdown files by enclosing the equation in double dollar signs:

inline $$math$$ example

Block level expressions are also enclosed in double dollar signs but instead must be on their own line with a blank line before and after the math expression.

The expression itself is in standard LaTeX syntax. If you are not familiar with LaTeX equation formatting, more information can be found here. Keep in mind the specific renderer used KaTeX is not a complete implementation but it does strive to provide the commands with orthogonal functionality. If a particular command is missing lookup the available equivalent.

Images


Images can be shown by using

![image hover text](/images/image.svg)

Where the hover text is the text you want to appear when a user hovers over the image, and the url is the url that points to the domain hosting your image. While this is not a strict requirement, images should be in *.svg format where possible. It is also possible to host your images, and other files, on the site.

Lists


To format a list in kramdown you must use an asterisk for an unordered list or numbers for an ordered list. The difference being, an ordered list will automatically increment as new elements are added (starting at 1, regardless of what number you started your list at) whereas unordered lists will act as simple bullet points. To initialize an unordered list you do:

* List element 1
* List element 2
...
* List element n

Starting the line with an unordered character, with one space after it, defines the list. The same goes for an ordered list:

1. List element 1
2. List element 2
   1. Indented list element 1
...
n. List element n

With the difference being that for an ordered list, the number must be succeeded by a full stop.

Lists can be at any indentation level, even nested within other lists (as shown above) - the list initializer character (*/number) has to be at the same indentation level of the preceding text.

Tables


Creating a table in kramdown involves first defining the headings. This can be done using the | character between each heading:

Heading 1 | Heading 2 | Heading 3

We follow this by creating an underline to distinguish the header from the rest of the table:

- | - | -

Where the number of - correspond to the number of headings. Finally we have our data lines situated under the underline:

Data 1.1 | Data 1.2 | Data 1.3
Data 2.1 | Data 2.2 | Data 2.3
...

Giving a final table that looks something like:

Heading 1 | Heading 2 | Heading 3
- | - | -
Data 1.1 | Data 1.2 | Data 1.3
Data 2.1 | Data 2.2 | Data 2.3
...

Table Of Contents


Often you’ll want a table of contents. Jekyll/Kramdown has support for auto-generating this ToC. Put the following syntax in the document where you want the ToC to be shown. The ToC is made from the <h> tags (headers) in the document.

### Table of Contents
{:.no_toc}
*  Auto generated table of contents
{:toc}

Adding the

{:.no_toc}

flag directly under a header will exclude that category and its subcategories from the ToC autogeneration.

Document Formatting Guidelines


Documents written for the website follow a set of formatting rules to maintain consistency. These rules are detailed below and do require knowledge of the Kramdown syntax, as detailed above.

Document Structure


The document should be built up of a few specific sections. Documents can contain more sections than this but should at least have these ones as a minimum. Additionally the sections should appear in the order given below.

  • (For Tutorials) Command Summary: For tutorials that contain terminal commands, especially long tutorials, you should include a command summary at the top of the page that lists the commands needed without any explaining text. If the tutorial requires that you do something that cannot be written as a single command then do your best to rework your tutorial or think of a way to do it as a command (editing an entry in a ctrl file can be done with some command line tools, for example).

    Note: This needs to be done whether you include a command summary or not as the testing framework (see below) will only accept a list of commands to be run sequentially.

  • Table Of Contents: An automatically generated table of contents, can be made as explained here.

  • Preliminaries/Prerequisites: This section should detail what prerequisite knowledge and tools are required to properly follow the document - papers, command like tools, other tutorials and documentation. It should also give a very brief overview of what the document contains although this should be evident from the document title.

  • Main Content: The main content of the document, split in to logical sections that make it easy to follow and importantly, are not too dense.

  • Other Resources/Further Reading: Papers, tutorials, documentation and other resources that are relevant to the document but are not prerequisite knowledge (otherwise they would appear above).

  • References: Collection of any external (third-party) references found in the document.

Documents should not be very long unless absolutely necessary. If possible, it is always better to write multiple documents and link between them than one large one. Of course, this only makes sense if there are mostly independent sections that can exist as their own document. This is especially important for tutorials - tutorials should not explain the physics as they exist to explain a specific functionality of Questaal. To that end, the description of the underlying physics or implementation details should be left to an accompanying documentation and the tutorial should detail only that which is required to operate Questaal for the task at hand.

Front Matter


The front matter is a required piece of YAML formatted data at the very top of every file. Your document will simply be ignored by Jekyll if it does not contain it. The front matter defines some data about the document and marks it as a valid document for conversion. Front matter must be the first thing in the document and is declared with an opening --- and closing ---:

---
title: "Document Title"
header: false
---

As you can see, we’ve defined the title and set header to false. There are a few things that can be set in the front matter, some of which are required in every document:

SettingDescriptionRequiredOptions
titleSets the title that automatically appears at the top of the pageYesAny string
headerDefines whether the Questaal banner appears at the top of the pageNofalse (default), true
layoutDefines the page layout, only necessary for postsNopage-fullwidth (default), page, post (default for posts)
floating_tocTurn the table-of-contents element on the right hand side on or off (not the in-page generated one)Notrue (default), false
editShow a description of how to edit the page at the bottom of the documentNotrue (default), false
autoInformation used in the auto generation of functionality pagesNoSee below
numbered_codeShould code boxes have numbered lines (defaults to )Nofalse (default), true
The Auto Setting

The auto setting in the front matter is used by Liquid to generate functionality pages like this one. These are important as they act as a reference for the capabilities of each tool in the suite or equally for the many ways to perform a specific task. Rather than manually add tutorials and maintain these pages, we generate them automatically with some front matter:

auto:
    code: questaal_code
    priority: 0
    info: What does the document show
    physical: Physical application

code tells Liquid which code this tutorial refers to, this could be lm, lmf, gw etc. priority is any integer greater than 0 and defines the order these tutorials appear when Liquid is generating the page (larger values appear first). physical is the physical application that the tutorial/documentation describes and could be DFT, Partial DOS etc. Finally, info is a short descriptive sentence that describes what the document contains.

code and physical should be consistent across documents - if the document is a lmf document then code should be set to lmf, not LMF, l m f, and so on. If ‘density of states’ has already been defined as DOS in other documents then don’t define yours as density of states - be consistent.

Formatting Keywords


Keywords in documents have some specific formatting rules for color and emphasis. Keywords here means files, directories, terminal commands, warnings, etc. These also have specific syntax that allows for automatic formatting of these words.

ItemText EmphasisColourSyntax
Path (directory/file)_italic_green_path/to/the/thing_{:.path}
Source Code**bold**green_bndasa.f_{:.source}
Input File Tags**bold**None**SITE_ATOM_POS**
Editor and Command-line Switches**bold**None**-vnsp=2**
Scripts and Subroutines_italic_blue_script.py_{:.script}
Package Names**bold**blue_lmf_{:.exec}
Terminal Commands**bold**blue_ls_{:.exec}
Note/Warning**bold**red_Warning_{:.warn}

Formatting that uses a shortcut syntax can also be achieved without using it, if you wanted to do it manually or needed to create another formatting category. See here and here for how to do this.

Using Dropdown Boxes


Dropdown boxes (these) can be used to hide non-essential details or to reduce the size of the page, as per the goal of minimizing the size and complexity of each document. A good rule is to run under the assumption that whatever is in the dropdown box will not be read. You should therefore refrain from putting anything important or critical to understanding the document in them and are useful for things like the command summary, the output of certain commands (as long as the output is not necessary for the next command, for example) or physical background that you don’t want to separate in to a new documentation file.

The one exception to this rule is for particularly long things. The output of a command may be necessary but equally if the output is longer than the page itself, it would be best for the user’s scroll wheel to have it hidden behind a dropdown box, as long as enough attention is drawn to the box both from the box’s title and the surrounding text such that it is not missed.

Document Integration


Once you’ve written your document you need to actually include it within the repository. Usually you’ll just send the file to the developers and this section will not be relevant to you but if you have repository access then you should read on.

File Structure


The repository is made up of a set of folders from which documents and posts are loaded. The url structure of each page is a mirror of the file structure on the disk. A file in _pages_tutorials with the directory structure lmf/bandedge.md would have the url questaal.org/tutorial/lmf/bandedge/. Notice, bandedge.md is mapped to /bandedge/ rather than /lmf/bandedge.html as you might expect - this doesn’t actually change anything however. Shown below is what each directory contains and what url root it maps to. Always try to put your file in an already existing directory before creating a new one.

DirectoryURL RootContents
_pages_tutorials/tutorial/Contains all tutorials, appears under the ‘Tutorials’ dropdown on the navigation bar
_pages_docs/docs/Contains all documentation, appears under the ‘Documentation’ dropdown on the navigation bar
_pages_about/about/Contains about information, appears under the ‘About’ dropdown on the navigation bar
_pages_uncategorised/Contains all pages that do not appear in dropdowns in the navigation bar or have no category (like the 404 page)
_postsVariousContains all news articles, appears under the ‘News’ button on the navigation bar

Adding To The Navigation Bar


When you have created a new markdown file you will need to edit the navigation.yml file, which can be found in the _data/ directory, to ensure it appears in the navigation bar.

To do so, take note of the directory your file is contained in - make sure to map the root folder (e.g. _pages_tutorials) to its URL root (e.g. /tutorial/) - we will use this as the navigation link. Open the navigation.yml file and you will see the structure, taking particular note of the indentation. To add a new field, find the category you want your new page to be listed under (tutorial/, docs/, tutorial/lmf/, etc) and add a new entry. Finding this means following the directory structure you noted previously: your directory structure may be _pages_tutorial/lmf/bandedge.md so you’re looking for the tutorial/ section, followed by the lmf/ subsection. You’d then add:

- title: "Page Title"
  url: "file_name"

Where the ‘title’ and ‘url’ text must be aligned as in the example. The page title can be anything you want but ‘url’ must be the name of the file (without the *.md) enclosed in quotation marks. You should also avoid including forward slashes in the url manually as this will be handled automatically in the build. When adding this new entry to the file, ensure that all indentation is preserved (see the file for a proper example) as it will not compile otherwise.

Using Git


The site is currently hosted on GitLab and git is used to manage the site and upload changes. The below text will provide instructions to allow contributions to the site.

Actually making changes, for those of you unfamiliar with git, is fairly simple. It is best achieved with git installed on your machine, more information can be found here. There are two ways to make a change:

First, you can request full write access to the repo, and push your changes as you normally would. Otherwise, you can request fork (read) access and fork a copy, which will allow you to make changes locally and request a merge of your changes with the master branch. This is probably the better idea if you’re worried about breaking something, as whoever approves your merge will be able to see all changes. Before using git locally however, you must first navigate to the repo page, sign in with your GitLab account, and fork the repo. This will create a server-side clone of the repo on your own account, allowing you full edit writes. At this point, if you prefer the command line, you can clone your repo:

git clone https://gitlab.com/youraccount/yourrepo.gitlab.io.git site

With youraccount and yourrepo pointing to the correct names. This will clone the site’s files in to the site folder. You can now make your changes or additions to the site source files. When these are completed, we must add the file to the index for committing. The following commands assume you are working from the repository directory.

git add *

You can also add files individually

git add [filename]

With the files indexed, we can now set up the commit

git commit -m "Commit message"

Where “Commit message” should be a useful message to let other people using the repository know what you are committing.

Finally, we can commit the changes

git push origin master

You may be asked for username and password details, fill these in all should be fine.

With your local repo updated with changes you would like to push to the main repo, you can use GitLab’s pull request function. This will notify the site developers that you wish to merge your changes with the main site, on which they can review the changes and hopefully approve them. You can continue working on your local branch and create pull requests whenever you have changes you think are large enough to require another merge. With this method, however, you will not be able to see your changes on the site until a pull request is made. The next section details how you can locally view the changes to ensure the site compiles properly and you have not made mistakes.

It would be useful to also email the site developers directly with your pull request to let them know who you are and what changes you are making. It also allows us to respond with feedback should the request be denied. Check out the contact page for more information.

Should you instead prefer to get full write access to the master repository, and you are successful doing so, the editing instructions are the same as above except where above you are committing to your own repo, you are instead committing to the master repo, so the urls you use should be changed accordingly.

Local Development


The site can be built and viewed locally. This is a great way to test your additions without causing a failed build after committing to the repository.

To do this, ensure jekyll is installed on your machine, the official guide can be found here, we will however go over some brief instructions.

To install jekyll and related plugins, you need to have Ruby and RubyGems installed (there are many guides for this, dependent on your system, a quick google will surely find you something). With these installed, you can install jekyll with (in the command line):

gem install jekyll

jekyll also needs some plugins that the site uses installed, to get these:

gem install jekyll-paginate

The repo also contains a GemFile which will install these two gems through bundle, we won’t go through this here though.

With jekyll now installed, you can either build the site html for hosting elsewhere, or host with jekyll’s built in webserver. To build without hosting, simply

jekyll build -tVd _site

From within the repository’s directory. This will produce a _site folder which contains the compiled html files for the site. To host the site locally

jekyll serve -tVd _site

(Note: you could run either command as ‘jekyll build/serve’ without the tags, however these tags replicate how the site will be built on GitLab, so this way you ensure compatibility) This will create the same _site folder, but will also host the website locally. Read your terminal output for the address of the site.

You could also use the command

jekyll serve -VItd _site

Which will speed up your build time after each file change quite drastically (it has some drawbacks, but it’s unlikely you will run in to them).

Note: The default .gitignore file will ignore _site files, but if yours for some reason doesn’t work, please make sure, before committing your changes to the repo, you delete the _site folder so as to not clutter the repo unnecessarily.

Hosting Files


Images, input files and whatever other files your tutorial or documentation needs can be hosted on the site, provided they are not too large. Files stored in the assets/download/ directory in the site source will be accessible on the site. Simply upload your file to the relevant folder, be that img, inputfiles etc. If a category does not exist, feel free to create one with a relevant name.

If your file is too large, contact us and we can look at other options. To actually commit the changes to the site, follow the making changes guide above; uploading your extra assets is as simple as committing any other file.

Creating Tutorial Tests


todo

Adding tags to the Questaal input system


This section is concerned not with the Questaal web site, but explains how to modify the source code to read new data from the input file.

Most executables, e.g. lmf, parse data via tags in the main input file, ctrl.ext. This section explains how to modify the source code to parse a new tag and make the data available to executables. All executables reading from the ctrl file call subroutine rdctrl (which resides in v7input/rdctrl.f) which in turn calls readctrl residing in v7input/m_rdctrl.f.

The source code must be modified in three steps:

  1. Modify toksw_init to tell the parser which executables should read this tag
  2. Add a new tag in v7input/m_rdctrl.f
  3. Modify v7input/rdctrl.f to transfer data parsed in m_rdctrl.f to a structure.

For definitiveness, we will add token DELTA to the HAM category, so that the tag is HAM_DELTA.

1. Modify toksw_init

New tags are added in subroutine readctrl, which resides in file v7input/m_rdctrl.f. readctrl will only parse a tag if it is present in a list; the list depends on which executable it is. Lists for all executables are created in an initialization routine, toksw_init, which is also embedded in file m_rdctrl.f.

In our example the tag is HAM_DELTA, and let us suppose we want it to be read by executables lmgf and lmpg. Search within routine toksw_init, for a line like this:

C --- LMGF tags ---

Then search after this line for the first occurence of the following:

      call tkadd(" HAM~")

This call to tkadd (string with a category and no token) marks that a new category (HAM) is to be included in the list for lmgf. The  ~  indicates that the category is optional (the executable does not require it to be present). Immediately after this will follow calls to tkadd with tag names to be parsed by lmgf with HAM as the category. Somewhere in that sequence add a new call

      call tkadd(" HAM_DELTA~")

Omit the  ~  if this tag is to be required.

Inset the same line in the section where the lmpg tags are listed. Look for this comment:

C --- LMPG tags (relative to lmgf) ---

lmpg’s list is very similar to that of lmgf. Rather than repeat a nearly identical list, toksw_init uses a shortcut. It starts from the list for lmgf, and adds new tags unique to lmpg (notably in the PGF category) and subtracts others present in lmgf but not in lmpg. The shriek indicates which tags are to be subtracted:

      call tkadd(" GF!")
      ...
      call tkadd(" HAM_SX! HAM_SXOPTS! HAM_RDSIG! HAM_RSRNGE! HAM_RSSTOL!")

Add a new line just after the calls shown above

      call tkadd(" HAM_DELTA~")

Now the parser knows to look for HAM_DELTA when read by the lmgf and lmpg executables.

2. Add a new tag to the input parser

To parse for tags in the ctrl file, every executable uses subroutine readctrl which resides in file v7input/m_rdctrl.f. To parse a particular tag, readctrl calls interface gtv. This interface offers a very large number of options, so managing it to parse a tag in exactly the way you want can be tricky. Especially if you want to do some complicated, it is simplest to see how other data is transferred, and use it as a template for your purpose.

The interface itself is contained in m_gtv.f: look at the comments at the beginning subroutine gtv_entrance for documentation of how to call it, what inputs are used for and what outputs are returned. You are strongly advised not to tinker with m_gtv.f, as it is very complicated with lots of dependencies.

readctrl parses all tags in one category before moving to another one. In our example we will add a new tag to HAM. Search in readctrl for this line:

      if (tkswp(prgn,express,'HAM') < 2) then

This if then block is closed by the line

      endif ! HAM

All tags that parsed for tokens inside the HAM category inside this block. We can add a new call to gtv for HAM_DELTA. You should use some judgement about where to place the new tag, since the on-line help (e.g. lmgf --input) prints out information in the order they appear. Let’s place the new call to m_gtv.f just before the endif. Insert these lines:

      nm='HAM_DELTA'; call gtv(trim(nm),tksw2(prgn,nm),ham_delta,def_r8=0d0,
     .  note= ' 0 No superconducting gap parameter'//
     .  '%N%2f >0 model superconducting gap parameter')

This will cause readctrl to parse for HAM_DELTA for any calling program that has this tag associated with it. It will read a real scalar into variable ham_delta, and assign a default value of zero if the tag is missing.

You will need to declare variable ham_delta. Do this in the module m_rdctrl at the top of the file, e.g. append it to this line:

      real(8):: lat_gmax,tolft,dqval,kmto(10),rsrnge,vmtz,elind=-0.7d0,ham_delta

By placing it in the module and not in readctrl, the variable is accessible to the calling routine (rctrl), which we modify next.

Before compiling run lmgf --input >old: this will print out the on-line help for tags lmgf knows about before your addition.

Now compile

ninja lmgf

and do lmgf --input >new. Compare to the old help (diff new old) and you should see the following

<  HAM_DELTA              opt    r8       1,  1     default = 0
<     0 No superconducting gap parameter
<    >0 model superconducting gap parameter

This shows that the reader will look for a double precision number following tag HAM_DELTA.

3. Modify v7input/rdctrl.f

If you have successfully completed steps 1 and 2, lmgf will read double precision variable ham_delta from tag HAM_DELTA in the ctrl file. So far, this information is restricted to routines that share module m_rdctrl. For executables to make use of this data, the information must be passed to a global structure. Make this transfer in subroutine rdctrl, which resides in file v7input/rdctrl.f. lmgf calls rdctrl, which performs many kinds of initializations, including calling readctrl to parse the input file. v7input/rdctrl.f and v7input/m_rdctrl.f share contents of module m_rdctrl, so ham_delta is accessible to both.

You must have an element in a global structure (in this instance s_ham) to park this new information. All structures are declared in file subs/structure77.h. If there is an existing element in the structure you you can use, that is optimal, to prevent proliferation of the structure contents. This is often the case: sometimes you can modify one bit in some integer element of a structure (note that many switches are stored as a digit or a bit in one integer element of a structure). In the present case there is no sensible way to make use of the existing s_ham structure, and we need to add an element to it.

structure77.h has many kinds of data in it. It is simplest to see how other data is transferred, and use it as a template for addition. Please make sure to add copious (and readily understandable) comments to any new element you add. Here we add a new element s_ham%delta. Search for the following string in structure77.h:

!r --- str_ham ---

First add a comment in the comment section (note variables are ordered alphabeticallly)

!r  delta    empirical superconducting gap potential

Next insert a new element into the s_ham structure

      real(8)    ::  delta

Now open file v7input/rdctrl.f. With this change to structure77.h you can copy ham_delta to sham%delta. Open that file and search for lines where elements are copied into s_ham, e.g.

      s_ham%udiag = ham_udiag

Insert a new line:

      s_ham%delta = ham_delta

s_ham%delta is now available to any subroutine that contains structure s_ham.

Questions or Comments


If this page has any errors, there is something you think is missing or unclear, or for any other issues, you can create a post here letting us know.