RascalTutor
Synopsis

The RascalTutor can be used to create, maintain and follow interactive courses.

Description

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.

    • Adding: Add a concept to a course.

    • Removing: Remove a concept from a course.

    • Renaming: How to rename a concept.

  • Markup: Markup directives for creating concept pages.

1. Architecture

Synopsis

The global architeture of the Rascal Tutor

Description

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:

Global Translation

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

Compilation of a course

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.

Benefits
  • Index creation is modular: an index is created per course and these indices are combined at runtime.

Pitfalls
  • Courses are compiled on a per-course basis. Support for incremental courses compilation is not yet available.

2. Authoring

Synopsis

Creating and writing a course for the Rascal Tutor.

Description

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 the courses 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.

Benefits

You can use your favourite editor and standard system command to author a course.

Pitfalls

There is no editing support or incremental course compilation available (yet).

3. Concept

Synopsis

A concept is the basic building block of a course.

Syntax
# 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.

Description

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.

Pitfalls
  • Note that all section names start with a period, e.g., .Examples.

  • No space is allowed before the section name.

3.1. Name

Synopsis

The display (presentation) name of a concept.

Syntax
# ConceptName
Description

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.

Examples

The first line of this concept is:

.Name
Name

3.2. Synopsis

Synopsis

One-line summary of the concept that is usable as a tool tip or table of contents entry

Syntax
.Synopsis
MarkedText
Description

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

Synopsis

Part of the synopsis that summarizes syntax introduced by this concept.

Syntax
.Syntax
MarkedText
Description

The syntax section is intended to describe syntactic aspects of language constructs. The contents of this section are arbitrary text.

Examples

The syntax section for an if-then statement can be written as:

.Syntax
`if ( _Exp_ ) _Statement_;`

3.4. Types

Synopsis

Part of the synopsis that describes any types or typing rules introduced by this concept.

Syntax
.Types
MarkedText
Description

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.

Examples

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:

Types
Exp if ( Exp ) Statement;

bool

void

Exp Statement1 Statement2 if ( Exp ) Statement1 else Statement2;

bool

T1

T2

lub(T1, T2)

3.5. Function

Synopsis

Part of the synopsis that describes function signatures introduced by this concept.

Syntax
.Function
MarkedText
Examples

Here is an example for the readFile function:

Syntax
.Function
str readFile(loc file) throws UnsupportedScheme(loc file), PathNotFound(loc file), IOError(str msg)

3.6. Details

Synopsis

Explcitly order the subconcepts of the current concept.

Syntax
.Details
ConceptNames
Description

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.

Examples

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

Synopsis

Gives a concise explanation of a concept.

Syntax
.Description
MarkedText
Description

The Description section gives a concise explanation of a concept.

Examples

The Description section of the concept Description (= the previous section) reads as follows:

.Description
The Description section gives a concise explanation of a concept.
Pitfalls
  • Avoid giving examples in the Description section but reserve these for the Examples 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

Synopsis

Examples to illustrate the concept.

Syntax
.Examples
MarkedText
Description

Gives a number of simple but complete examples to illustrate the concepts and its variations. Running examples (using [Screen]) are preferred.

3.9. Benefits

Synopsis

Briefly lists known advantages of the concept.

Syntax
.Benefits
MarkedText

3.10. Pitfalls

Synopsis

Comprehensive list of known shortcomings or usage problems of the concept.

Syntax
.Pitfalls
MarkedText

4. Maintenance

Synopsis

How to maintain a course.

Description

The following topics are discussed:

  • Adding: Add a concept to a course.

  • Removing: Remove a concept from a course.

  • Renaming: How to rename a concept.

4.1. Adding

Synopsis

Add a concept to a course

Description

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

Synopsis

Remove a concept from a course.

Description

To remove a concept C:

  • Remove subdirectory C (and its subdirectories) using standard commands.

  • Recompile the course.

4.3. Renaming

Synopsis

How to rename a concept.

Description

To rename a concept C to D:

  • Rename C to D using the commands of the version control system.

  • Rename D/C.concept to D/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

Synopsis

Markup directives for creating concept pages.

Description

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

Synopsis

Markup directives used in input lines.

Description

For convenience we summarize the most commonn inline markup elements. See http://asciidoctor.org/docs/asciidoc-syntax-quick-reference/ for more details.

5.1.1. Bold

Synopsis

Create bold text.

Syntax
*Text*
Examples

*bold* gives bold.

5.1.2. Callout

Synopsis

Create a numeric callout for the digits 1—​9.

Syntax
< Digit >
Description

Callouts are used to attach numeric labels to a source code [Listing] for later discussion in the text.

Examples

[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.
Benefits

Callout are most usefull to place markers in code fragments for later reference in explanatory text.

5.1.3. Code

Synopsis

Create inline code fragments.

Syntax
`MarkedText`
Description

Creates inline fragments of text that represent code. Inside the MarkedText, other markup can be used.

Examples

` if ` --- that is ` followed by if followed by ` --- gives if.

5.1.4. ExternalURL

Synopsis

Refer to an external URL.

Syntax
  • URL

  • URL[MarkedText]

Description

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.

Examples
http://www.rascal-mpl.org
http://www.rascal-mpl.org[Rascal]

gives Rascal. Try it!

5.1.5. Image

Synopsis

Include an image.

Syntax
image::_File_[]
image::_File_[AlternateName, Width, Height, link=URI]
Description

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
Examples
image::dandelion.jpg[]

will produce:

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

produces a reduced image floating at the right.

Example 3

And, finally,

image::dandelion.jpg[Dandelion, 200, 300, link="https://flic.kr/p/GknoaW"]

produces a clickable image that links back to the source of the image.

Dandelion

Try it!

5.1.6. Italic

Synopsis

Create italic text.

Syntax
_ Text _
Examples

_italic_ gives: italic.

5.1.7. Reference to Concept

Synopsis

Refer to a concept in this course or another course.

Syntax
  • << DisplayName >>

  • << ParentConceptName-ConceptName >>

  • link:/Course[LinkText]

  • link:/Course#ParentConceptName-ConceptName[LinkText]

Description

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.

Examples

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.

Pitfalls

Note the / before the course name in refernces to another course.

5.1.8. Variable

Synopsis

Markup for a variable.

Syntax
  • _VarName_

  • _VarName_~Index~

  • _VarName_^Index^

Description

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 ^)

Examples
  • _Var_ gives Var.

  • _Var_~1~ gives Var1.

  • _Var_^1^ gives Var1.

  • _Var_^1^~2~ gives Var12.

5.2. QuestionMarkup

Synopsis

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:

Question

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.

Examples
  • prep: import List; imports the List module before executing the following steps.

  • make: A = set[arb[int,str]] introduces A and assigns it a value of the indicated type.

  • make: B = same[A] introduces B and assigns it a value of the same type as A.

  • expr: C = <A> + <B>: inserts the values of A and B, performs the addition, and assigns the result to C.

  • type: set[int]: the required type is set[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

Synopsis

Multiple-choice question.

Syntax
QChoice OptName: MarkedText
GoodOrBad1: Choice1
GoodOrBad2: Choice2
...
Description

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.

Examples
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

Synopsis

A text question with a free-format answer.

Syntax
QText OptName: Text
a: Answer1
a: Answer2
...
Description

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.

Examples

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

Synopsis

A question about a Rascal type.

Syntax
  • QType OptName : TypeDescriptor

  • QType OptName : QSteps Test Listing

Description

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.

Examples

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

Synopsis

Description of a Rascal type used in type and value questions.

Syntax

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]

Description

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 and num 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.

Examples
TypeDescriptor Generated value

int

Arbitrary integer

int[-5,10]

An integer between -5 and 10

arb[int,bool,str]

An arbitrary integer, boolean or string

list[int]

A list of integers

set[int[0,10]]

A set of integers between 0 and 10

Pitfalls
  • 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

Synopsis

Question about the value of a Rascal expression or program.

Syntax
  • QValue OptName: TypeDescriptor

  • QValue OptName: QSteps Test Listing

Description

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 preceeding make or expr step.

  • The listing, and the expressions in the test may contain at most one placeholder <?>.

Examples

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

Synopsis

Mark up in Rascal source code.

Description

The mark up of concepts inside Rascal source code requires two steps:

5.3.1. Remote Concept Mapping

Synopsis

Include the concepts in a Rascal source module in a course.

Description

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.

Examples

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.

Pitfalls
  • Be carefull to avoid spaces, since the value reader does not like them.

5.3.2. Doc Annotations

Synopsis

A doc annotation attaches an inline concept description to a Rascal declaration.

Description

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
Examples

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.

Benefits

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.

Pitfalls
  • 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

Synopsis

Markup for structured text entities.

Description

The follwing structured markup is supported:

5.4.1. Admonition

Synopsis

Mark up for admonitions.

Syntax
  • NOTE: MarkedText

  • TIP: MarkedText

  • IMPORTANT: MarkedText

  • CAUTION: MarkedText

  • WARNING: MarkedText

Description

An admonition is remark that should draw the reader’s attention.

Examples

The input

NOTE: This is a note.

gives

This is a note.

The input:

WARNING: Use warnings sparingly.

will give:

Use warnings sparingly.
Pitfalls

An admonition should start at the begin of a line and the : should be followed by a single space.

5.4.2. Bullet Lists

Synopsis

A (possible nested) list of bullet points.

Syntax
  • * MarkedText

  • ** MarkedText

  • *** MarkedText

  • …​

Description

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.

Examples

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.

Pitfalls

An empty line is required before and after a BulletList.

5.4.3. NamedParagraph

Synopsis

Mark up for a named paragraph.

Syntax
  • ## ParagraphName

  • ### ParagraphName

  • …​

Description

A NamedParagraph produces a named paragraph of a level that is determined by the number of # characters preceding the ParagraphName.

Examples

The input:

## Paragraph

will give

Paragraph
Pitfalls
  • 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

Synopsis

Introduce a new paragraph.

Description

A new paragraph is created by a single empty line.

Examples

The input:

line1
line2

line3
line4

will produce:

line1 line2

line3 line4

5.4.5. Numbered Lists

Synopsis

A (possibly nested) list of numbered points.

Syntax
  • Number MarkedText

  • . MarkedText

  • .. MarkedText

  • ... MarkedText

  • …​

Description

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.

Examples

The input

. First item.
. Second item.

will produce:

  1. First item.

  2. Second item.

The input

. First item.
  ..  First subitem.
  ..  Second subitem.
. Second item

will produce:

  1. First item.

    1. First subitem.

    2. Second subitem.

  2. Second item

Pitfalls

An empty line is required before and after a NumberedList.

5.4.6. Table

Synopsis

Mark up for a table.

Syntax
|===
| Header1 | Header2 | ...

| Entry11  | Entry12  | ...

| Entry21  | Entry22  | ...
|===
Description

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
Examples
|===
| 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

A | B

Or operator

Benefits

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

Synopsis

Generate a local table of contents of current concept.

Syntax

loctoc::[Depth]

Description

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.

Examples

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.