-
Notifications
You must be signed in to change notification settings - Fork 26
Reference Design and Documentation
Warning: Wiki should not be edited directly. Edit the files in the ./wiki/ folder instead and make a PR.
- Introduction
- Why Change References
- Changes
- What is in a Reference?
- How to use
References
- Troubleshooting
In Drasil, references are used as a means to link relevant topics to one another, both for ease of reading the generated documentation, and for information encoding by connecting relevant ideas, theories, and definitions. This can be done internally through hyper-references, internally with citations, or externally with links.
Previous to the Summer 2021 redesign of References
, each reference was created and used in-line with Sentences
. This meant that the Sentence
itself actually held all of the data needed to produce a reference without needing a database. It only encapsulated the necessary surface-level information to display a reference. However, this method of forming references meant that Sentences
could not be used to create References
in a reliable manner. As such, it also restricted the use of NamedIdeas
as a shortname
for the reference, which in turn blocked the ability of linking complex ideas with the usual concept-level combinators. In the Combinator Documentation, many concept-level combinators have a variant with an appended T
. The problem here is that the need for a "title-version" of a combinator should not exist; Drasil knows (or should know) how to handle different cases through the NounPhrase
class and the use of Sentences
. Before this revision, References
used Strings
for display names when it was not necessary. Using Sentences
would be a much better fit for display names, as it allows Drasil to learn more about the reference itself. This way, we should be able to reduce the need for duplicate title-case versions of combinators and allow complex ideas with context to be referenced. In addition, this should allow for references to be created within normal sentences rather than needing a separate label for everything (see #1142, #2489, and #2562 for more information).
References
may now be created within Sentences
with the use of a UID
rather than the actual reference itself. This forces the References
themselves to be contained within a chunk database (similar to ConceptChunks, TheoryModels, Contents, etc.). The information for each reference is hidden until it is needed by the printer to be displayed. Any additional display information may be attached to a Reference
when it is used in a Sentence
by using makeCiteInfo
. The information may contain things like page numbers and equation referrals. See the RefInfo
documentation for more information.
In turn, References
must also be added to the chunk database (ChunkDB
) through a reference map. The bottom of most example files contain a list of references to be mapped. Then they are all imported to Body.hs
and placed in the reference map for the ChunkDB
of that particular example.
References
will now accept a Sentence
as its ShortName
rather than a String
. The change allows for more flexibility in defining references and allows for NamedIdeas
to translate directly into a reference.
Primarily, this change was aimed at defining section labels in a cleaner way. Section labels should not need to use a String
, instead they should be built off of a NamedIdea
so that traceability and maintainability may be better preserved. Currently, each section will have a related NamedIdea
that can be made into a reference.
As a second bonus to adding this, ShortNames
can now be anything that exists within the bounds of a Sentence
. This means that custom display name labels will be possible for in-text referencing.
Referring to issue #1142, the generated documents may now contain references with a label that is different from its internal ShortName
. We can now use in-line references with custom text in a similar way to that of GitHub. With this change, a reference link does not necessarily have to be the internal label that was applied to it (or even a related label, for that matter). Of course, it is still good practice to give a descriptive label to all references, but this is especially useful for making the generated documents easier to read and give an overall cleaner style. It also has the added benefit of reducing duplicate occurrences of a phrase in a sentence and its related label.
Previously, References
had to be defined by either building them manually or using these functions: makeRef2
, makeRef2S
, makeCite
, makeCiteS
, makeCiteInfo
, makeCiteInfoS
, rw
. They all used to perform different actions, however they have recently become very similar. With the change to how References
are put in a Sentence
(by UID
lookup), the different functions are not really needed. Instead, this change allows for more general functions to be defined. ref
is now the primary way to create a reference, while refS
, refInfo
, namedRef
, and namedComplexRef
will be created. The functions for each of these will be defined in the how-to section below.
Before this change, References
had the option to carry display-level reference information (as RefInfo
). This display-level information included specific pointers to page numbers, equations, or an optional note that the Drasil printers would then append to the Reference
itself. However, since the change to use UIDs
to look up references in a database, it no longer became practical to keep the RefInfo
attached to the reference itself. Keeping the RefInfo
inside a Reference
caused issues when the same Reference
was used more than once (and used with different RefInfo
). This could cause unwanted behavior such as a reference displaying different reference information than what was written in the actual code. Since the database is only able to hold one Reference
per one UID
, users would not have been able to include RefInfo
inside a Reference
internally. Instead, RefInfo
is now used at a Sentence
level. It is not encoded directly with the Reference
, but instead appended to it and used when needed (much like a custom display name). So whenever a user needs to show display-level reference information, it will be encoded into Drasil at the Sentence
level, which is meant to be used for display purposes.
However, there are some cases where we want the Reference
to actually hold RefInfo
without sinking to the level of Sentences
. This is where DecRef
comes in. DecRefs
are record types that contain a Reference
and its respective RefInfo
. This way, we can form a bridge of sorts between References
and Sentences
. In particular, these are used in instance & theory models and general & data definitions. Constructing a DecRef
is quite similar to a Reference
, where dRef
takes in a Reference
and sets the RefInfo
to None
, and dRefInfo
takes in a Reference
and any additional RefInfo
to be displayed.
The original goal of this change was to make the HasRefAddress
and Referable
class distinct from one another. After all, a Reference
itself is not exactly something Referable
, but it does have a HasRefAddress
and should be included in the ReferenceMap
of the chunk database. Thus, this change encased two smaller changes:
- Changing
ref
to take inHasRefAddress
rather thanReferable
. Since we wantref
to be applicable toReferences
but not includeReference
as an instance ofReferable
, this change had to be made. Since the classes were similar, it was a straightforward projection, but it also forced the second change. -
HasRefAddress
was initially only able to hold aString
. However, that alone was not enough for Drasil to be able to formulate a fullReference
from. So we needed a type with more context. Hence,LblType
became the new result of the method for theHasRefAddress
. TheString
form is still available (through thegetAdd
function), but now Drasil could determine aReference
with context.
Inside of drasil-docLang/Drasil/DocumentLanguage.hs
, there is now a new fillReferences
function. This allows users to use references just about wherever they wish without needing to worry about manually adding references to the project's chunk database. So long as the user plugs in all the models, definitions, sections, labelled content, concept instances, and citations, there should be no need for a user to manually input references. To explain the fillReferences
function a bit more, it first takes a partially filled database (SystemInformation
) and a list of all the sections to be put in the SRS (SRSDecl
). From there, it first searches through the SRSDecl
for any Section
and LabelledContent
references. Then, it takes all the information from the SystemInformation
(everything that is a part of the HasRefAddress
or Referable
class), gathers it into one nice list, and places it back in the database of SystemInformation
for use by the generators.
A Reference
contains an identifier, a reference address, a human-readable shortname for a display label, and any extra information about the reference. For more information, please see the Haddock documentation.
References
can be created from the following Referable
types (linked to the Haddock documentation for each): ConceptInstance
, Citation
, LabelledContent
, Section
, TheoryModel
, InstanceModel
, DataDefinition
, and GenDefn
These types should be included in the chunk database as needed.
To reference something within a Sentence
, these functions should be helpful: refS
, namedRef
, and namedComplexRef
. Sometimes it is necessary to include the references within a TheoryModel, InstanceModel, DataDefinition, or GenDefn when defining a reference map. This can be done by accessing the list of references with a lens and the getReferences
method from the HasReference
class (Eg. use (^. getReferences)
). To map the references to a database, use the ref
function on everything that is referable and then include the list of references in the symbMap
function of the Body.hs
file.
Common functions and their uses:
-
ref
: Creates aReference
from anything that isReferable
. Used in definingReferences
in other functions or mappingReferables
to a database -
refInfo
: Similar toref
but allows for additional reference information to be added to aReference
. -
refS
: Creates aReference
within aSentence
. Used often in drasil-examples. -
namedRef
: Creates aReference
with the given display name into aSentence
. Used often in drasil-examples. -
namedComplexRef
: Creates aReference
with the given display name and any additional reference information. Then wraps into aSentence
. Used often in drasil-examples.
If an error similar to Reference: UID not in ReferenceMap
occurs, try using grep
on the UID
to pinpoint which variable is being referenced. From there, track any functions that use this variable or include the variable inside the list of references to be added to the chunk database. drasil-docLang/Drasil/DocLang/SRS.hs
is a common source of this, as sections (and their references) are automatically generated for the most part.
Please see Debugging in Drasil
for more information.
- Home
- Getting Started
- Documentation (of Drasil specifics)
- Design
-
Readings
- Drasil Papers and Documents
- Related Work and Inspiration
- Writing Documentation
- Compression as a Means to Learn Structure
- Glossary, Taxonomy, Ontology
- Grounded Theory
- Model Driven Scrapbook
- Model Transformation Languages
- ODE Definitions
- The Code Generator
- Suggested Reading
- Sustainability
- Productivity
- Reuse
- Formal Concept Analysis
- Generative Programming
- Software Documentation
- Units and Quantities
- Misc.
- WIP Projects