Home (editor)   Video Intro.   Syntax  |   Gallery   GitHub

Syntax & Usage

Not up for a full syntax lesson? Download and print this three-page quick start guide. It has pretty flowcharts.

Quick Start Guide

QnA is a markup language for people with little or no programming experience. It was designed with attorneys in mind and transforms blocks of text into interactive question and answer sessions (QnAs). These QnAs can be used as stand-alone expert systems or in the aid of rule-based document construction. See example below. Plus, they can be fun, and the entire project is open source.

Authors define behavior by placing text after one of ten tags described below. On this page, you'll find everything you need to write your own QnA. Assuming an average reading speed of 180 words per minute, this entire page should only take about 20 minutes to read. Of course, you should probably open a QnA editor and play around as you read. So it might take an hour before you're an expert. ;)

If you're pressed for time, start with the Body Tags section. That's where all the exciting stuff happens, and you can build a very respectable QnA with body tags alone. Alternatively, you could try our quick start guide.


Header Tags

The header is optional text appearing before the first non-header tag (those tags listed under Body below). The header can be empty or contain any of the following five header tags. The values of these tags are defined by the text between tags. The order of tags is unimportant as long as they appear before the first non-header tag. If you use a tag twice, the last value provided will be used to define the tag's value.

Title: text/html

Author: text/html

Description: text/html

Before: text/html

After: text/html

Back to top

Body Tags

The Body is where you define questions and answers along with the text of any would-be documents. This content can be plain text, or it can be formated as HTML. The output of a QnA is an interactive HTML document. Consequently, if you would like to include comments (text that doesn't show up in your output), you can hide them like this: <!-- comment text here -->, just as you would in HTML. To get a good feel for what's possible in QnA, read through the following tag descriptions.

Q(variable_name): text/html


A(variable_value): some text/html, A(variable_value)[href]: some text/html, or A(variable_value):[href] some text/html

X:date_type, X[href]:date_type, or X:[href]date_type

DOC: text/html

Back to top

Predefined Javascript Functions

All interactive QnA documents come preloaded with a set of eight Javascript functions. As described above, these can be called from an A tag using the syntax: A[javascript:function_name();]:. Below we'll explain what each of these functions do.




    This function will cause the QnA to jump to the Q tag associated with the defined variable_name. For example, when selected, the following tag will cause the QnA to jump to the Q(end) tag: A[javascript:goto('end');]: button text.


    This function will return the DOC: content associated with rendered Q tags. For example, when selected, the following tag will display the DOC: content: A[javascript:alert(doc());]: button text.

    You may recall the use of this function in the save conversation example above.


    This function will return a JSON string containg the QnA's variable_name and variable_name as key and value pairs. For example, when selected, the following tag will display the the QnA's variables as a JSON string: A[javascript:alert(json_str());]: button text.


    This function will return a string of comma-separated values containing the variable names in the first row and the values of variables collected by the QnA in the second row. For example, when selected, the following tag will display the the QnA's variables as comma-separated values: A[javascript:alert(csv());]: button text.

mail2(to, subject, body);

    When called, this function will make use of the mailto URI scheme to open a new email in the user's default email program. This email will be addressed to to, with the subject line subject, and the body of the email will be body. For example, when selected, the following tag will email a transcript of the current QnA to jdoe@example.com with the subject line QnA Transcript. A[javascript:mail2('jdoe@example.com','QnA Transcript',transcript());]: button text.

    Note: Due to a common security setting, this function may not work if the QnA is embedded in an iframe.


    This function will save a file to the user's computer with the name filename and content equal to content. For example, when selected, the following tag will save a file named QnA_document.txt with contents equal to the output of the doc() function. A[javascript:save2('QnA_document.txt',doc());]: button text.

    You may recall the use of this function from the save conversation example above.

submit2(action, method, docAs, instructions, transcriptAs, jsonAs, target);

    The entierty of a QnA conversation is wrapped in an HTML FORM tag. This function will set that tag's action to action, its method to method, and its target to target. Note: the target parameter is optional. It's default setting is: target = "_self".

    It will send the QnA's document as a single variable named docAs along with an HTML transcript named transcriptAs and a JSON string named jsonAs.

    It will send all variables defined with their names as defined by the Q tag's variable_name as well as any hidden variables placed inside the document's Before, After, Q and A tags.

    Additionally, it will send a variable named i with a value equal to instructions. This last variable is intended specifically for use with the WYSIWYG document parsers described below.

Back to top

Document Parsers & Editors

My hope is that this section will grow into a list of parsers as people point me to various parsers around the web. The basic idea is that by using the submit2() function in conjunction with a document parser/editor, it is possible to hold up the document created by a QnA for review by a person. Imagine a QnA that used a combination of DOC: and X: tags to craft a custom document for a pro se litigant. At the end of the QnA, that document can be passed to a parser and the user can take some time to edit the text before printing or saving it. The thing is that the DOC: tag doesn't really care what format its content is in. It could be HTML, markdown, or LaTex. By passing that content to a parser, it can be rendered and placed in a form that's easier for a user to digest.

Local WYSIWYG Parsers & Editors

    For now, I've set up local parsers for HTML, Markdown, and jsPDF. They are available at:

    Note: the jsPDF parser doesn't allow users to edit output, and isn't compatible with all browsers.

    The parsers read two variables which you can send them using the submit2() function. The first, t, is the content to be parsed, and the second, i, is a set of instructions to be displayed after parsing. In fact, submit2() takes i as an argument. That is i = instructions as defined above.

    For example, the QnA below can be used to create a letter to Santa. Note: the document is in HTML. So you'll notice that line breaks are indicated by the HTML tag <br>. Also, it is sent to the HTML parser.

    Q(1): Would you like to write a letter to Santa? 
    A: Yes.
    	Q(myname): What is your name?
    		DOC(1.1.1):Dear Santa,<br><br> 
    		Q(naughty): Have you been naughty or nice?
    		A(I am sorry that I have been naughty. I will work hard to be nice in the new year.<br><br>): Naughty
    		A(): Nice
    A: No.
    	Q(1.2): That's cool. Have a good day.
    Q(whatiwant): What would you like for Christmas?
    	DOC(2.1):<x>naughty</x>I would like <x>whatiwant</x> for Christmas. I hope all is well with you up north.<br><br>
    	Q(2.1): Alright, are you ready to see your letter?
    	A[javascript:submit2('https://www.qnamarkup.net/doc/parse/html/', 'POST', 't', 'Proof read your letter. Print it out, and mail it to: Santa Clause, North Pole')]: Yes.
    		Q(2.1.1): Thank you.
      edit this QnA in an new window

Working with .docx & .pdf Files

    Although the above parsers offer a good deal of flexability, sometime you want to control a document's format with greater percision than allowed by HTML et al. For such instances, you can make use of .docx templates such as this one.

    Instead of constructing the document in QnA you can merge your QnA answers with an existing template. Below we'll do this with a standard .docx (Word) file with mail merge feilds. The service below will take in a JSON string, the URL of a .docx file from which to make a merged .docx file, and the name for the output file. The service we'll be using below is a modified instance of docx_webmerge. Here's a brief how to on how to create your own template file.

    However, the tool only accepts .docx files from a whitelist of servers. if you're a non-profit and would like me to add your website to the whitelist, let me know. As long as you aren't expecting wicked crazy volume, I'll probably just add you to the list.

    Your output can be either a .docx file or a .pdf file. To choose a filetype, simpily use the appropriate endpoint (e.g. https://colarusso.pythonanywhere.com/2docx/ or https://colarusso.pythonanywhere.com/2pdf/).

    That being said, let us write another letter to Santa.

    <input type="hidden" name="name" value="Letter to Santa"/>
    <input type="hidden" name="docx_uri" value="http://www.qnamarkup.org/docxmerge/templates/Santa-letter.docx"/>
    Q(1): Would you like to write a letter to Santa? 
    A: Yes.
    	Q(myname): What is your name?
    Q(whatiwant): What would you like for Christmas? 
    	Q(2.1):Alright, are you ready to see your letter?
    	A[javascript:submit2('https://colarusso.pythonanywhere.com/2docx/', 'POST', '', '', '', 'json_doc', '_blank')]:Yes (docx).
    	A[javascript:submit2('https://colarusso.pythonanywhere.com/2pdf/', 'POST', '', '', '', 'json_doc', '_blank')]:Yes (pdf).
    		Q(2.1.1): Thank you.
      edit this QnA in an new window

    Note: if you'd like to include instructions along with your document, consider appending an instructions page to the begining of the document.

Back to top

Loading a Remote QnA

If you have a text file containing QnA Markup at a URL, you can pass that URL to a QnA instance for rendering using the source parameter and the following syntax:

    [QnA rendering instance's URL]/i/?source=[QnA text file's URL]

For example:

    https://www.qnamarkup.net/i/?source=https://colarusso.github.io/QnAMarkup/examples/source/first_q.txt (view link)

Permissible domains, however, are limited to a whitelist established in the configuration file (i.e., config.php) of a QnA instance. The instance running at QnAMarkup.org, for example, accepts pointers to "www.qnamarkup.org" and "colarusso.github.io".

The source parameter is accepted by both the the stand-alone QnA page (e.g., https://www.qnamarkup.net/i/?source=text URL) and the editor page (e.g., https://www.qnamarkup.org/?source=text URL).

You can submit content to "colarusso.github.io" by following the instructions for "Hosting your QnA" found on this project's Gallery page.

Back to top