
The RascalTutor can be used to create, maintain and follow interactive courses.
The RascalTutor is an interactive Authoring and learning environment intended to create and follow interactive courses related to the Rascal language. It is based on the following principles and ideas:
-
The basic notion is a Concept. Each concept has a name and contains a fixed set of subsections that describe it.
-
A course is a concept tree: The central subject of the course is the root of the concept tree, and all subtrees further explain their parent concept.
A student using a course can:
-
Browse through the table of contents of the concept tree of the course.
-
Search for concepts and specific terms using a search box.
-
Read individual concepts.
-
Follow links to other concepts.
An author of a course can:
-
Create a new course.
-
Create a new concept in a course.
-
Edit a concept directly using a standard text editor.
-
Add code examples that are actually executed when the concept is turned into an HTML page.
-
Recompile the course.
-
Inspect the warnings that are generated for the whole course in order to control the quality of the concept descriptions.
The actual markup used is an extension of AsciiDoc, see http://asciidoctor.org and in most cases we directly refer to
The folling topics will be described here:
-
Architecture: The global architeture of the Rascal Tutor.
-
Authoring: Creating and writing a course for the Rascal Tutor.
-
Concept: A concept is the basic building block of a course.
-
Benefits: Briefly lists known advantages of the concept.
-
Description: Gives a concise explanation of a concept.
-
Details: Explcitly order the subconcepts of the current concept.
-
Examples: Examples to illustrate the concept.
-
Function: Part of the synopsis that describes function signatures introduced by this concept.
-
Name: The display (presentation) name of a concept.
-
Pitfalls: Comprehensive list of known shortcomings or usage problems of the concept.
-
Synopsis: One-line summary of the concept that is usable as a tool tip or table of contents entry.
-
Syntax: Part of the synopsis that summarizes syntax introduced by this concept.
-
Types: Part of the synopsis that describes any types or typing rules introduced by this concept.
-
-
Maintenance: How to maintain a course.
-
Markup: Markup directives for creating concept pages.
-
-
Bold: Create bold text.
-
Callout: Create a numeric callout for the digits 1—9.
-
Code: Create inline code fragments.
-
ExternalURL: Refer to an external URL.
-
Image: Include an image.
-
Italic: Create italic text.
-
Reference to Concept: Refer to a concept in this course or another course.
-
Variable: Markup for a variable.
-
-
QuestionMarkup: Mark up for interactive questions.
-
Choice: Multiple-choice question.
-
Text: A text question with a free-format answer.
-
Type: A question about a Rascal type.
-
TypeDescriptor: Description of a Rascal type used in type and value questions.
-
Value: Question about the value of a Rascal expression or program.
-
-
Source Code Markup: Mark up in Rascal source code.
-
Doc Annotations: A doc annotation attaches an inline concept description to a Rascal declaration.
-
Remote Concept Mapping: Include the concepts in a Rascal source module in a course.
-
-
-
Admonition: Mark up for admonitions.
-
Bullet Lists: A (possible nested) list of bullet points.
-
NamedParagraph: Mark up for a named paragraph.
-
NewParagraph: Introduce a new paragraph.
-
Numbered Lists: A (possibly nested) list of numbered points.
-
Table: Mark up for a table.
-
Table of Contents: Generate a local table of contents of current concept.
-
-
1. Architecture
The global architeture of the Rascal Tutor
At the highest level, a course consists of concept files, which are translated to intermediate AsciiDoc files, which in their turn, can be translated to html, pdf, epub and other output formats:

The compilation and runtime use of a single course are organized as follows:

A course is a directory with concept files. Each concept file yields:
-
An AsciiDoc file for further processing
-
Onthology: the hierarchical structure of the concepts.
-
Lucene-based Index-data extracted from the various sections of the concept.
External concepts refer to Rascal source code that contains embedded concepts in @doc{ … }
. Similar information is extracted from them as for a standard concept.
Once all concepts have been processed their extracted information is combined:
-
All AsciiDoc files are included in a single AsciiDoc file for the whole course. This will be converted to the desired output format.
-
The index-data are included in a single index.
The end results of processing a complete course are:
-
A single html (or other) file for the whole course.
-
A single index file for the whole course.
At runtime, the generated Hhtml can be viewed via a browser and search queries can be answered using Lucene and the single index.
Another way to use a compiled course is directly from the REPL.
-
Index creation is modular: an index is created per course and these indices are combined at runtime.
-
Courses are compiled on a per-course basis. Support for incremental courses compilation is not yet available.
2. Authoring
Creating and writing a course for the Rascal Tutor.
The life cycle of a course consists of the following steps:
-
A new course, say
MyCourse
, is created. This is achieved by:-
Creating a subdirectory named
MyCourse
in thecourses
directory of the current Rascal project. -
Creating a file
MyCourse/MyCourse.concept
. This is the root concept of the new course.
-
-
The contents of the course are created by populating the course with subconcepts of the root concept.
-
A subconcept, say
CoolIdea
is created by:-
Creating a subdirectory
CoolIdea
of its parent concept. -
Creating a file
CoolIdea/CoolIdea.concept
that describes the concept.
-
-
Renaming/moving/deleting concepts is done at the directory/file level.
Concepts are represented as directories for the following reasons:
-
To represent subconcepts as subdirectories.
-
To contain all figures and other files that are included in the concept. In this way:
-
A complete concept can be easily moved or renamed as a single unit.
-
Name clashes between included files per concept are avoided.
-
You can use your favourite editor and standard system command to author a course.
There is no editing support or incremental course compilation available (yet).
3. Concept
A concept is the basic building block of a course.
# ConceptName
.Synopsis
MarkedText
.Syntax
MarkedText
.Types
MarkedText
.Function
MarkedText
.Details
ConceptNames
.Description
MarkedText
.Examples
MarkedText
.Benefits
MarkedText
.Pitfalls
MarkedText
The first two sections (Name and Synopsis) are mandatory, the others are optional. It is recommended to give examples.
A concept describes a separate entity (idea, artefact, function, rule) that is relevant in the scope of the course in which it appears. It consists of 11 named sections that are described separately. Each section starts with a keyword that should appear at the begin of a line. The first two sections (Name and Synopsis) are mandatory,
Here is a brief summary of the sections of a concept:
-
Name: The display (presentation) name of a concept.
-
Synopsis: One-line summary of the concept that is usable as a tool tip or table of contents entry.
-
Syntax: Part of the synopsis that summarizes syntax introduced by this concept.
-
Types: Part of the synopsis that describes any types or typing rules introduced by this concept.
-
Function: Part of the synopsis that describes function signatures introduced by this concept.
-
Details: Explcitly order the subconcepts of the current concept.
-
Description: Gives a concise explanation of a concept.
-
Examples: Examples to illustrate the concept.
-
Benefits: Briefly lists known advantages of the concept.
-
Pitfalls: Comprehensive list of known shortcomings or usage problems of the concept.
-
Note that all section names start with a period, e.g.,
.Examples
. -
No space is allowed before the section name.
3.1. Name
The display (presentation) name of a concept.
# ConceptName
A concept has actually three names:
-
Its file name, i.e., the name of the
.concept
file in which the concept is described. -
Its full name, the path name from the root concept to the current concept file.
-
Its displayed name, its name as its appears as section heading and in the table of contents.
Name defines the presentation name of a concept and may be an arbitrary text. Concept names are used to refer to other concepts: when unambiguous its file name or display name can be used to refer to another concept, otherwise a sufficient part of its full name has to be given to make it unambiguous.
Name is mandatory.
The first line of this concept is:
.Name
Name
3.2. Synopsis
One-line summary of the concept that is usable as a tool tip or table of contents entry
.Synopsis
MarkedText
The full summary of a concept consists of the Synopsis and the optional elements Syntax, Types and Function.
Synopsis is mandatory (this is not yet enforced).
3.3. Syntax
Part of the synopsis that summarizes syntax introduced by this concept.
.Syntax
MarkedText
The syntax section is intended to describe syntactic aspects of language constructs. The contents of this section are arbitrary text.
The syntax section for an if-then statement can be written as:
.Syntax
`if ( _Exp_ ) _Statement_;`
3.4. Types
Part of the synopsis that describes any types or typing rules introduced by this concept.
.Types
MarkedText
The Types
section describes any types that are involved in the concept that is described. The description can be just text, but in many cases a table is useful to describe types.
Here is a type description of an if-then-else statement:
.Types
|====
| Exp
| if ( Exp ) Statement;
| bool
| void
|====
[cols="20,20,20,40"]
|====
| Exp
| Statement1
| Statement2
| if ( Exp ) Statement1 else Statement2;
| bool
| T1 | T2 | lub(T1, T2)
|====
The result will be displayed as:
Exp |
if ( Exp ) Statement; |
---|---|
|
|
Exp |
Statement1 |
Statement2 |
if ( Exp ) Statement1 else Statement2; |
---|---|---|---|
|
T1 |
T2 |
|
3.5. Function
Part of the synopsis that describes function signatures introduced by this concept.
.Function
MarkedText
Here is an example for the readFile
function:
.Function
str readFile(loc file) throws UnsupportedScheme(loc file), PathNotFound(loc file), IOError(str msg)
3.6. Details
Explcitly order the subconcepts of the current concept.
.Details
ConceptNames
To fully describe a concept, subconcepts (or details) are needed. When the Details
section is empty, subconcepts will be listed alphabetically in the details section of the generated HTML file.
This alphabetical order can be influenced by explicitly stating concepts in the details sections. The effect is that the concepts listed there will be shown first, followed by the unmentioned subconcepts in alphabetical order.
In Concept we want to order the details in the order as they appear in the concept description. Its Details
section is therefore:
.Details
Name Details Syntax Types Function Synopsis Description Examples Benefits Pitfalls Questions
3.7. Description
Gives a concise explanation of a concept.
.Description
MarkedText
The Description
section gives a concise explanation of a concept.
The Description
section of the concept Description
(= the previous section) reads as follows:
.Description
The Description
section gives a concise explanation of a concept.
-
Avoid giving examples in the
Description
section but reserve these for theExamples
section. -
Do not give explicit lists of subconcepts (details) since they are already included automatically in the
Details
section in the generated page.
3.8. Examples
Examples to illustrate the concept.
.Examples
MarkedText
Gives a number of simple but complete examples to illustrate the concepts and its variations. Running examples (using [Screen]) are preferred.
3.9. Benefits
Briefly lists known advantages of the concept.
.Benefits
MarkedText
3.10. Pitfalls
Comprehensive list of known shortcomings or usage problems of the concept.
.Pitfalls
MarkedText
4. Maintenance
How to maintain a course.
The following topics are discussed:
4.1. Adding
Add a concept to a course
There are basically two scenarios for adding a new concept, depending on where its contents come from. If the concept is part of the course (i.e. it is now a remote concept, see below):
-
Select a concept that is suitable as parent for the new concept.
-
Create a subdirectory, say
SubConcept
for the new subconcept. -
Create the file
SubConcept/SubConcept.concept
using your favourite editor. -
Add the name and other information about the new concept.
-
Save the file.
If the concept involves remote content (i.e., the concepts are described in rascallibrary files), then a Remote Concept Mapping has to be added as explained in Source Code Markup.
4.2. Removing
Remove a concept from a course.
To remove a concept C:
-
Remove subdirectory C (and its subdirectories) using standard commands.
-
Recompile the course.
4.3. Renaming
How to rename a concept.
To rename a concept C to D:
-
Rename C to D using the commands of the version control system.
-
Rename
D/C.concept
toD/D.concept
using the version control system. -
Open
D/D.concept
in a text editor and change the display name on the first line# Old Display Name
to# New Display Name
. -
Recompile the course.
5. Markup
Markup directives for creating concept pages.
The MarkedText in each section of a concept is plain text. Some characters or text strings are used to influence the markup of the text and follow the conventions of http://asciidoctor.org. We distinguish:
-
Structure markup influences the structure of the text.
-
Inline markup influences the markup for characters or words.
-
Source code markup to define concepts in Rascal source code.
5.1. Inline Markup
Markup directives used in input lines.
For convenience we summarize the most commonn inline markup elements. See http://asciidoctor.org/docs/asciidoc-syntax-quick-reference/ for more details.
-
Bold: Create bold text.
-
Callout: Create a numeric callout for the digits 1—9.
-
Code: Create inline code fragments.
-
ExternalURL: Refer to an external URL.
-
Image: Include an image.
-
Italic: Create italic text.
-
Reference to Concept: Refer to a concept in this course or another course.
-
Variable: Markup for a variable.
5.1.1. Bold
Create bold text.
*Text*
*bold*
gives bold.
5.1.2. Callout
Create a numeric callout for the digits 1—9.
< Digit >
Callouts are used to attach numeric labels to a source code [Listing] for later discussion in the text.
[source]
----
This code contains the callout <1>
----
will produce
This code contains the callout (1)
By including <1>
in an enumeration or text, for instance,
<1> refers to the callout.
will give:
1 | refers to the callout. |
Callout are most usefull to place markers in code fragments for later reference in explanatory text.
5.1.3. Code
Create inline code fragments.
`MarkedText`
Creates inline fragments of text that represent code. Inside the MarkedText, other markup can be used.
` if
` --- that is ` followed by if
followed by ` --- gives if
.
5.1.4. ExternalURL
Refer to an external URL.
-
URL
-
URL[MarkedText]
Creates a link to an external url URL. When MarkedText is present, a clickable hyperlink is included with the text Name. Otherwise URL itself is included as clickable hyperlink.
http://www.rascal-mpl.org
gives http://www.rascal-mpl.org and
http://www.rascal-mpl.org[Rascal]
gives Rascal. Try it!
5.1.5. Image
Include an image.
image::_File_[]
image::_File_[AlternateName, Width, Height, link=URI]
Describes an image to be included:
-
File is the name of the image file.
-
AlternateName is the alternate name of the image.
-
Width is the required width (in pixels) of the image.
-
Height is the rewuired height of the image in pixels.
-
When
link
is present, it turns the image in a link to the given URI.
For further styling of images, see http://asciidoctor.org/docs/user-manual/#images.
Example 1
image::dandelion.jpg[]
will produce:

Example 2
image::dandelion.jpg[Dandelion, 200, 300, float="right"]

produces a reduced image floating at the right.
5.1.6. Italic
Create italic text.
_ Text _
_italic_
gives: italic.
5.1.7. Reference to Concept
Refer to a concept in this course or another course.
-
<< DisplayName >>
-
<< ParentConceptName-ConceptName >>
-
link:/Course[LinkText]
-
link:/Course#ParentConceptName-ConceptName[LinkText]
Recall that a concept is known under two names, its concept name (the file name of the concept) and its display name (the name as displayed in the text).
The first two forms create a link to a concept in the current course.
The remaining two forms create a link to a concept in another course.
The first creates a link to a complete course, the second to a specific concept in an external course.
The concept name of this concept is ReferenceToConcept
while its display name is Reference to Concept
(note the spaces).
We can create a reference to the InlineMarkup
concept in the current course in the following ways:
-
<<Inline Markup>>
(using the display name) gives Inline Markup. -
<<Markup-InlineMarkup>>
(using its parent concept name and concept name) gives Inline Markup. -
link:/Tutor#Markup-InlineMarkup[see inline markup]
gives see inline markup
Here is a reference to another course:
-
link:/Rascal#Statements-If[If statement]
gives If statement.
Note the /
before the course name in refernces to another course.
5.1.8. Variable
Markup for a variable.
-
_VarName_
-
_VarName_~Index~
-
_VarName_^Index^
Variables in text and code are represented by Italic markup. They may be followed by one or more subscripts (enclosed by ~
and ~
) or superscripts (enclosed by ^
and ^
)
-
_Var_
gives Var. -
_Var_~1~
gives Var1. -
_Var_^1^
gives Var1. -
_Var_^1^~2~
gives Var12.
5.2. QuestionMarkup
Mark up for interactive questions.
Description
The specification of questions is being redesigned; The information provided here is outdated.
|
The following types of questions are supported:
-
Text: a text question with a free format answer.
-
Choice: a multiple choice question.
-
Type: question about the type of a Rascal expression.
-
Value: question about the value of a Rascal expression.
Text gives the question text and lists all possible good answers.
Choice is a straightforward listing of good and bad answers.
Type and Value questions are based on a template that consists of an optional listing and an equality:

There should be exactly one hole (indicated by <?>
) in this template that is to be filled in by the student; it may occur in the listing or in one of the sides of the equality. The general structure is therefore: fill in the hole such that the equality holds. Given that the listing is optional, this template represents 5 different question styles.
Type and Value questions use TypeDescriptors to describe desired values and share certain common steps (QSteps):
-
prep: RascalCommand
describes preparatory steps needed to execute the question. Typically, required imports can be listed here. -
make: Var = TypeDescriptor
: makes a new value generated according to TypeDescriptor and assigns it to a new variable Var. Var can be used in later steps in the same question. -
expr: Var = Expr
: introduces a new variable Var and assigns to it the result of evaluating Expr. Expr may contain references to previously introduced variables using<`Var
>`. -
type: TypeDescriptor
-
hint: Text
: a hint to be given to the student in response to a wrong answer. Text may contain references to previously introduced variables. -
test: Expr1 == Expr2
: the equality that should hold. The expressions may contain references to variables. One side may contain a hole (<?>
). -
list: Text
: a listing that runs until the next question or the end of the concept. It may contain a hole.
-
prep: import List;
imports the List module before executing the following steps. -
make: A = set[arb[int,str]]
introducesA
and assigns it a value of the indicated type. -
make: B = same[A]
introducesB
and assigns it a value of the same type asA
. -
expr: C = <A> + <B>
: inserts the values ofA
andB
, performs the addition, and assigns the result toC
. -
type: set[int]
: the required type isset[int]
. -
hint: One or more integers separated by comma’s
. -
test: <A> + <?> == <C>
: the student has to replace<?>
by an answwer that makes the equality true.
5.2.1. Choice
Multiple-choice question.
QChoice OptName: MarkedText
GoodOrBad1: Choice1
GoodOrBad2: Choice2
...
Asks a multiple-choice questions described by MarkedText.
OptName is an optional name of the question (enclosed between [
and ]
). If OptName is missing, the question gets a unique number as name.
Each possible Choice is preceded by a good (g
) or bad (b
) marker. When generating a question 3 choices (including one good answer) are presented in random order.
Providing more good and bad answers will therefore create more variation in the generated questions.
QChoice[Faster]: Which means of transportation is faster:
b: Apache Helicopter
g: High-speed train
b: Ferrari F430
b: Hovercraft
will produce the question Faster
in the questions section below.
And, by the way, the High-speed train wins with over 570 km/hour compared to Ferrari (315 km/hour), Apache (293 km/hour) and Hovercraft (137 km/hour).
5.2.2. Text
A text question with a free-format answer.
QText OptName: Text
a: Answer1
a: Answer2
...
Presents a text questions consisting of Text.
OptName is an optional name of the question (enclosed between [
and ]
). If OptName is missing, the question gets a unique number as name.
The user can give a free format answer, and that is accepted if it contains one of the given answers answer1, Answer2 as substring.
The markup
QText[Taller]: Which is taller, the Eiffel Tower or the Empire State Building?
a: Empire
Will generate question Tall
in the questions section below. The answer is obvious: the Empire State Building is 443.2 meters tall while the Eifel Tower is 324 meters tall. Any answer that contains Empire
will be accepted.
5.2.3. Type
A question about a Rascal type.
-
QType OptName : TypeDescriptor
-
QType OptName : QSteps Test Listing
A type question presents a Rascal expressions and poses a question about its type.
OptName is an optional name of the question (enclosed between [
and ]
). If OptName is missing, the question gets a unique number as name.
The desired type is given by a TypeDescriptor.
The first form presents the value generated for the TypeDescriptor and asks about its type.
The second form allows more preparatory steps and also allows adding a listing to the question.
See the effect of the following type questions in the Questions section below.
Question 1
The following question can be paraphrased as: I give you an arbitrary set of integers, what is its type?
QType: <A:set[int]>
Question 2
The following question can be paraphrased as: I give you an addition of a set of integers, strings or reals and another set of the same type; what is the type of the result?
QType: <A:set[arb[int,str,real]]> + <B:same[A]>
5.2.4. TypeDescriptor
Description of a Rascal type used in type and value questions.
A TypeDescriptor is one of
-
bool
-
int
-
int[Max]
-
int[Min,Max]
-
real
-
real[Max]
-
real[Min,Max]
-
num
-
num[Max]
-
num[Min,Max]
-
str
-
loc
-
datetime
-
list[TypeDescriptor]
-
set[TypeDescriptor]
-
map[TypeDescriptor,TypeDescriptor]
-
tuple[TypeDescriptor1, TypeDescriptor2, …]
-
void
-
value
-
arb
-
arb[Int]
-
arb[Int, TypeDescriptor1, TypeDescriptor2]
-
arb[TypeDescriptor1, TypeDescriptor2]
-
same[TypeName]
A TypeDescriptor is used to describe Rascal types and values in questions and are used to automatically generate values of the described type. TypeDescriptors largely follow the types as available in Rascal, with the following extensions that are helpfull when generating values:
-
int
,real
andnum
may specify a minimal and maximal value for the values to be generated. -
arb
describes an arbitrary type. The choice can be restricted by:-
given an integer that defines the maximal depth of the type.
-
given an explicit list of types to choose from.
-
-
same[Name]
refers back to a type that was used earlier on in the same question.
TypeDescriptor | Generated value |
---|---|
|
Arbitrary integer |
|
An integer between -5 and 10 |
|
An arbitrary integer, boolean or string |
|
A list of integers |
|
A set of integers between 0 and 10 |
-
There is currently an arbitrary built-in limit that restricts generated lists, sets, maps and relations to at most 5 elements.
-
There is no support for labeled tuples.
5.2.5. Value
Question about the value of a Rascal expression or program.
-
QValue OptName: TypeDescriptor
-
QValue OptName: QSteps Test Listing
A value question presents a Rascal expression and poses a question about its value.
OptName is an optional name of the question (enclosed between [
and ]
). If OptName is missing, the question gets a unique number as name.
The desired type of the expression is given by a TypeDescriptor.
The first form presents the value generated for the TypeDescriptor and asks about its value.
The second form allows more preparatory steps and also allows adding a listing to the question. The following steps are defined:
-
prep: Cmd
: execute Cmd as preparatory step. Mostly used to import necessary libraries. -
make: Var = TypeDescriptor
: create a new variable and use TypeDescriptor to generate its value. -
expr: Var = Exp
: evaluate the Rascal expression Exp and assign its value to the new variable Var. -
list: Lines
: lines that will be displayed as a listing. The listing may contain a placeholder in the form of<?>
and ends where a new step begins. -
test: Exp1 == Exp2
: the equality is evaluated as Rascal expression. The outcome determines the success or failure to answer this question. -
hint: Text
: a hint that will be shown when the user enters a wrong answer.
The following restrictions apply:
-
Each step starts at the beginning of a new line.
-
Every Exp or Cmd or listing may contain one or more variable references of the form
<
Var>
. -
Each variable reference
<
Var>
is first replaced by the value of Var. Var should have received a value in a preceedingmake
orexpr
step. -
The listing, and the expressions in the test may contain at most one placeholder
<?>
.
See the effect of the following value questions in the Questions section below.
Question 1
The following question can be paraphrased as: I give you a union of two sets of integers, what is its value?
QValue: <A:set[int]> + <B:same[A]>
Question 2
The following question can be paraphrased as: What is the size of a given list of integers?
QValue:
prep: import List;
test: size(<A:list[int]>) == <?>
Note that the List
module is imported as a preparatory step.
Question 3
The following question can be paraphrased as: I give you a union of integers or strings and an unknown set and the result of the union; what is the value of the unknown set?
QValue:
make: A = set[arb[int,str]]
make: B = same[A]
expr: C = <A> + <B>
hint: <B>
test: <A> + <?> == <C>
Observe that we generate values for A
and B
and compute the value of C
. The value of B
is the answer we are looking for, and we replace it by <?>
in the posed test. When the student gives a wrong answer, we show the value of B
as hint.
Question 4
The following question can be paraphrased as: Fill in the hole in the definition of funcion find to ensure that it returns all strings that contain "o".
QValue:
desc: Return the strings that contain "o".
list:
text = ["andra", "moi", "ennepe", "Mousa", "polutropon"];
public list[str] find(list[str] text){
return
for(s <- text)
if(/o/ := s)
<?>;
}
test: find(text) == ["moi", "Mousa", "polutropon"];
5.3. Source Code Markup
Mark up in Rascal source code.
The mark up of concepts inside Rascal source code requires two steps:
-
Remote Concept Mapping: Include the concepts in a Rascal source module in a course.
-
Doc Annotations: A doc annotation attaches an inline concept description to a Rascal declaration.
5.3.1. Remote Concept Mapping
Include the concepts in a Rascal source module in a course.
Each Rascal source file defines a module M
that may declare concepts M/c1
, M/c2
, …. as indicated by embedded @doc
annotations. How are these concepts included in a Tutor course?
The answer is a remote concept file.
Where an ordinary concept C
is defined by a subdirectory C
and a concept file C/C.concept
a remote concept is defined by C/C.remote
that contains the location of the source file, say CLoc
.
Cloc
will be parsed, all its concepts will be extracted and all these concepts become subconcepts of C
.
Moving the documentation for a library file is as simple as moving C
to another position in the concept hierarchy.
The DateTime
library module is defined in the Libraries course by the subdirectory Libraries/Prelude/DateTime
and the file DateTime/DateTime.remote
. The latter contains a single line with the location of the DateTime module:
|std:///DateTime.rsc|
This establishes, for instance, that the function now
that is declared in the DateTime.rsc
library file will become the concept Libraries/Prelude/DateTime/now
.
-
Be carefull to avoid spaces, since the value reader does not like them.
5.3.2. Doc Annotations
A doc annotation attaches an inline concept description to a Rascal declaration.
All Rascal declarations can be preceeded by an annotation of the form @doc{ … }
where … may be arbitrary text, provided that {
and }
characters are balanced and that unbalanced braces are escaped like \{
or \}
. This text is expanded to a full concept definition when the concept is processed.
The Tutor supports and expands inline concept descriptions for the following declarations types.
Module Declaration
The name of this module is extracted. The header of the concept definition is automatically generated and consists of:
# Module name
.Usage
Import declaration needed to use this module
Function Declaration
The signatures of this function and of all directly following functions with the same name are collected. The signatures are placed in an itemized list (unless there is only one). The header of the concept definition is automatically generated and consists of:
# Function name
.Function
Function signature
.Usage
Import declaration needed to use this module
Data Declaration
The signatures of this data declaration and of all directly following data declarations without their own @doc
annotation are collected. The header of the concept definition is automatically generated and consists of:
# Data declaration name
.Type
Data declarations
.Usage
Import declaration needed to use this module
Annotation Declaration
The signature of this annotation declaration is collected. The header of the concept definition is automatically generated and consists of:
# Annotation declaration name
.Type
Annotation declarations
.Usage
Import declaration needed to use this module
We only give an example of documenting a simple function. Read the source code of Rascal library files for other ones.
Consider the source code of the now function in the DateTime
library.
@doc{
.Synopsis
Get the current datetime.
.Examples
[source,rascal-shell]
----
import DateTime;
now();
----
}
@javaClass{org.rascalmpl.library.DateTime}
public java datetime now();
This will be expanded to
# now
.Function
`datetime now()`
.Usage
`import DateTime;`
.Synopsis
Get the current datetime.
.Examples
[source,rascal-shell]
----
import DateTime;
now();
----
and the final result is now.
A (small) part of documentation writing is automated. The information about the name of a function, data or annotation declaration, or its signature is always consistent.
-
This approach requires that functions with the same name are grouped together in the source file.
-
We do not (yet) provide direct editing of
@doc{ … }
in Rascal source files. We should!
5.4. Structure Markup
Markup for structured text entities.
The follwing structured markup is supported:
-
Admonition: Mark up for admonitions.
-
Bullet Lists: A (possible nested) list of bullet points.
-
NamedParagraph: Mark up for a named paragraph.
-
NewParagraph: Introduce a new paragraph.
-
Numbered Lists: A (possibly nested) list of numbered points.
-
Table: Mark up for a table.
-
Table of Contents: Generate a local table of contents of current concept.
5.4.1. Admonition
Mark up for admonitions.
-
NOTE: MarkedText
-
TIP: MarkedText
-
IMPORTANT: MarkedText
-
CAUTION: MarkedText
-
WARNING: MarkedText
An admonition is remark that should draw the reader’s attention.
The input
NOTE: This is a note.
gives
This is a note. |
The input:
WARNING: Use warnings sparingly.
will give:
Use warnings sparingly. |
An admonition should start at the begin of a line and the :
should be followed by a single space.
5.4.2. Bullet Lists
A (possible nested) list of bullet points.
-
* MarkedText
-
** MarkedText
-
*** MarkedText
-
…
Bullet lists create, possibly nested, lists of points. The number of *
characters determines the nesting level of a (sub)list.
A list item ends with:
-
the start of a new list item.
-
an empty line.
Bullet Lists and Numbered Lists can be mixed. See http://asciidoctor.org/docs/user-manual/#unordered-lists for the precise rules.
The input
* First item.
* Second item.
will produce:
-
First item.
-
Second item.
The input
* First item.
** First subitem.
** Second subitem.
* Second item.
will produce:
-
First item.
-
First subitem.
-
Second subitem.
-
-
Second item.
An empty line is required before and after a BulletList.
5.4.3. NamedParagraph
Mark up for a named paragraph.
-
## ParagraphName
-
### ParagraphName
-
…
A NamedParagraph produces a named paragraph of a level that is determined by the number of #
characters preceding the ParagraphName.
The input:
## Paragraph
will give
Paragraph
-
NamedParagraphs have at least two hash signs (
##
). A single hash is reserved for the Concept level. -
A NamedParagraph should start at the start of a line.
5.4.4. NewParagraph
Introduce a new paragraph.
A new paragraph is created by a single empty line.
The input:
line1
line2
line3
line4
will produce:
line1 line2
line3 line4
5.4.5. Numbered Lists
A (possibly nested) list of numbered points.
-
Number MarkedText
-
. MarkedText
-
.. MarkedText
-
... MarkedText
-
…
Numbered Lists create, possibly nested, lists of numbered points. They either start with a period (.
) or a number. The number of periods indicates the nesting level.
A list item ends with:
-
the start of a new list item.
-
an empty line.
Bullet Lists and Numbered Lists can be mixed. See http://asciidoctor.org/docs/user-manual/#ordered-lists for the precise rules.
The input
. First item.
. Second item.
will produce:
-
First item.
-
Second item.
The input
. First item.
.. First subitem.
.. Second subitem.
. Second item
will produce:
-
First item.
-
First subitem.
-
Second subitem.
-
-
Second item
An empty line is required before and after a NumberedList.
5.4.6. Table
Mark up for a table.
|===
| Header1 | Header2 | ...
| Entry11 | Entry12 | ...
| Entry21 | Entry22 | ...
|===
The simplest table starts and ends with |===
, each row is separetd by an empty line and each column starts with |
. There are, hwoever, other formats and options to specify the formatting of cells and columns. See http://asciidoctor.org/docs/user-manual/#tables for details.
Example 1
|===
| A | B | C
| 11 | 12 | 13
| 21 | 22 | 23
|===
gives:
A | B | C |
---|---|---|
11 |
12 |
13 |
21 |
22 |
23 |
Example 2
A column specification may precede the table and specifies the number of columns with default alignment (left) and with specified alignment: left (<
), centered (^
) or right (>
).
[cols="1*,^,1*"]
|===
| A | B | C
| 11 | 12 | 13
| 21 | 22 | 23
|===
gives (with column B centered):
A | B | C |
---|---|---|
11 |
12 |
13 |
21 |
22 |
23 |
Example 3
[cols="2*,>"]
|===
| A | B | C
| 11 | 12 | 13
| 21 | 22 | 23
|===
gives (with column C right-aligned):
A | B | C |
---|---|---|
11 |
12 |
13 |
21 |
22 |
23 |
Example 4
|===
| Operator | Description
| `_A_ \| _B_` | Or operator
|===
gives (note the escaped |
character in one table entry):
Operator | Description |
---|---|
|
Or operator |
Table formatting are versatile and include, sizing, subtables, column spans, and more, see http://asciidoctor.org/docs/user-manual/#tables.
5.4.7. Table of Contents
Generate a local table of contents of current concept.
loctoc::[Depth]
Generate a local table of contents for all subconcepts of the current concept to a depth of Depth. When OptDepth is missing, 1 will be used as default depth.
This is useful for summary pages.
A table of contents of 1 level deep is generated by loctoc::[1]
. The local table of contents for this course is generated by loctoc[3]
, see Tutor.