Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add api and style section about documentation #8

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added guidelines.pdf
Binary file not shown.
1 change: 1 addition & 0 deletions src/chapters/api.typ
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#set heading(offset: 2)
#include "api/flexibility.typ"
#include "api/simplicity.typ"
#include "api/documentation.typ"
74 changes: 74 additions & 0 deletions src/chapters/api/documentation.typ
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#import "/src/util.typ": *
#import mantys: *

= Documentation <sec:api:docs>
Documentaiton comemnts are important for consumers of the API as well as new contributors to your package or project to understand the usage and purpose of an item.
An item may be a state variable, a counter, a function, a reusable piece of regular content, or anything that can be bound using a `let` statement.
tingerrr marked this conversation as resolved.
Show resolved Hide resolved

#wbox[
For the exact syntax used for documentation comments, refer to @sec:style:docs.
]

For functions a public API should always document all public arguments, their usage and purpose as well as constraints on their values.
tingerrr marked this conversation as resolved.
Show resolved Hide resolved
Internal arguments may be ommited, if they are not meant to be exposed to a user, but should still be documented for contributors in the source or a contribution document.
tingerrr marked this conversation as resolved.
Show resolved Hide resolved
Depending on the doc aprser in use, named arguments may need their defaults explicitly stated and should have if the doc parser can't parse them automatically.
If functions require or return contextual values, this should also be communicated clearly.
Functions should also document their return type, even if it is general, such as `any`.
Should a function return different types depending on it's inputs or the state of the document, it must be documented when this may happen or at least which types to expect and check for at the call site.

Values like states and counters, if exposed, should document their invariants, such as the allowed types for states or the expected depth range of a counter for example.
The type of the value itself should likewise be annotatd using the function return type syntax.
tingerrr marked this conversation as resolved.
Show resolved Hide resolved

#do-dont[
```typst
// - well documented invariants
// - most doc parsers will identify named defaults, we omit them for brevity
// in this example

/// Does things.
///
/// This function is contextual if `arg` == `other`.
tingerrr marked this conversation as resolved.
Show resolved Hide resolved
///
/// - arg (int): Fancy arg, must be less than or equal to `other`.
tingerrr marked this conversation as resolved.
Show resolved Hide resolved
/// - other (int): Other fancy arg, must be larger than `arg`.
/// -> content
#let func(arg, other: 1) = {
assert(arg <= other)

if arg == other {
context { ... }
} else {
...
}
}
```
][
```typst
// user don't know how these definitions must be shaped, optional fields on
// dictionaries especially can make it hard to get a full graps of those implicit
tingerrr marked this conversation as resolved.
Show resolved Hide resolved
// invariants if they can only inspect the state var in their doc to reverse
// engineer the definition shape

/// Contains the function definitions.
#let item = state("defs", (:))

// - invariants of `arg` are not documented and may result in poor UX
// - other is not documented
// - does not document contexuality

/// Does things.
///
/// - arg (any): Fancy arg.
#let func(arg, other: 1) = {
// the lack of typing information would cause a hard to understand error
// message for a novice user
assert(arg <= other)

if arg == other {
context { ... }
} else {
...
}
}
```
]
1 change: 1 addition & 0 deletions src/chapters/style.typ
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@
#include "style/sugar.typ"
#include "style/trailing.typ"
#include "style/linebreaks.typ"
#include "style/documentation.typ"
63 changes: 63 additions & 0 deletions src/chapters/style/documentation.typ
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#import "/src/util.typ": *
#import mantys: *

= Documentation <sec:style:docs>
#wbox[
This section documents the syntax of documentation commens, see @sec:api:docs for the contents and purpose of documentation comments.
tingerrr marked this conversation as resolved.
Show resolved Hide resolved
]

Documentation for items are placed on comments right before the item, with three forward slashes `///` and a leading space.
The first leading space and comment tokens are stripped of the line and each line is joined to make up the body of the doc comment.
tingerrr marked this conversation as resolved.
Show resolved Hide resolved
The content of doc comments should be simple Typst markup with some extra documentation specific syntax and assumptions about structure.
tingerrr marked this conversation as resolved.
Show resolved Hide resolved
Doc comments do not use any other strucutre at this moment, regular comments `//` and `/**/` are ignored by most doc parsers.

#do-dont[
```typst
/// This is a doc comment
#let item = ...
```
][
```typst
/**
* This is not a doc comment, it's a regular comment.
*/
#let item = ...

// This is not a doc comment, it's a regular comment.
#let item = ...
```
]

Doc comments are split into two parts:
- the general description, including examples and package specific sections and the
- optional trailer containing semantic information about the annotated item.

Doc comments may include special syntax such as `@@val` or `@@func()`, these are used by doc generators like #mty.package[Tidy] to generate cross references in documentation.

#wbox[
There seems to be no special syntax to refer to things other than functions and values at this moment.
]

== Description
The general description makes no assumptions on syntax other than including the aforementioned cross-reference syntax.
It may be any Typst syntax, but should ideally kept simple to allow LSPs to convert it into Markdown for editor hover actions.

== Semantic Trailer
The semantic trailer of doc comments is the last section of the doc comments containing optional information about the documented item.
This may include a list of parameter descriptions, a return type annotation, and other annotations, all of which are not treated as regular Typst syntax.

At this moment #mty.package[Tidy] accepts the following syntax:
```ebnf
param-name ::= typst-ident
type-name ::= typst-ident
type ::= ( '..' )? type-name
tingerrr marked this conversation as resolved.
Show resolved Hide resolved
type-list ::= '(' type ( ',' type )+ ')'
description ::= typst-markup

param-documentation ::= '/// - ' param-name ' ' type-list ':' [description]
tingerrr marked this conversation as resolved.
Show resolved Hide resolved
tingerrr marked this conversation as resolved.
Show resolved Hide resolved
return-type ::= '/// -> ' type-name
tingerrr marked this conversation as resolved.
Show resolved Hide resolved
```

As well as some other more specific ones like doc tests.
We shall only consider this subset for now.
The trailer may contain zero or more lines of `param-documentation` and an optional `return-type` line.