This is a paper-writing framework designed to ease the pain of authoring papers for WG21, built on top of Pandoc.
In short, you write your papers in Markdown and the framework produces the paper either in HTML or PDF.
python3
xelatex
(Only for PDF papers)
brew install mactex # Only for PDF papers
sudo apt-get install texlive-latex-base # Only for PDF papers
Debian installation may require these additional packages:
texlive-fonts-recommended
texlive-latex-recommended
texlive-latex-extra
git submodule add https://github.com/mpark/wg21.git
echo "include wg21/Makefile" > Makefile
make <paper>.pdf # `<paper>.md` -> `generated/<paper>.pdf`
make <paper>.html # `<paper>.md` -> `generated/<paper>.html`
See mpark/wg21-papers for an example use of this project.
make <paper>.pdf # `<paper>.md` -> `generated/<paper>.pdf`
make <paper>.html # `<paper>.md` -> `generated/<paper>.html`
This framework provides support for various common elements for C++ papers.
- Title
- Table of Contents
- Markdown
- Embedded Markdown within Code
- Comparison Tables
- Proposed Wording
- Stable Names
- Citations
- References
- Unicode Considerations
The title is specified in a YAML metadata block.
date: today
will generate today's date inYYYY-MM-DD
(ISO 8601) format.
YAML lists can be used to specify multiple audiences and authors:
---
title: Integration of chrono with text formatting
document: P1361R0
date: 2018-10-16
audience:
- Library Evolution Working Group
- Library Working Group
author:
- name: Victor Zverovich
email: <victor.zverovich@gmail.com>
- name: Daniela Engert
email: <dani@ngrt.de>
- name: Howard E. Hinnant
email: <howard.hinnant@gmail.com>
---
The default toc-depth
is 3
, but it can be specified to go deeper:
Refer to the full Pandoc Markdown spec for useful extensions!
Within default, cpp
, and diff
code elements, any text surrounded by the @
symbol is formatted as Markdown! This is useful for conventions such as
see below
, unspecified
, and exposition-only variable names.
This also works for inline code, e.g.,
Recall the `static_cast`{.cpp} syntax: `static_cast < @_type-id_@ > ( @_expression_@ )`{.cpp}.
If you need to nest embedded Markdown, surround the outer context with @@
.
This comes up sometimes if you want to produce inline diffs within a code block,
and some of the inner code need to be marked up.
```
template <@[`invocable`]{.rm}[`class`]{.add}@ F@[`, class`]{.add}@>
struct @_as-receiver_@ {
@[`private:`]{.rm}@
@[`using invocable_type = std::remove_cvref_t<F>;`]{.rm}@
@[`invocable_type`]{.rm}[`F`]{.add}@ f_;
@[`public:`]{.rm}@
@@[`explicit @_as-receiver_@(invocable_type&& f)`]{.rm}@@
@@[`@_as-receiver_@(@_as-receiver_@&& other) = default;`]{.rm}@@
void set_value() @[`noexcept(is_nothrow_invocable_v<F&>)`]{.add}@ {
invoke(f_);
}
@[`[[noreturn]]`]{.add}@ void set_error(std::exception_ptr) @[`noexcept`]{.add}@ {
terminate();
}
void set_done() noexcept {}
};
```
Comparison Tables are fenced Div
blocks that open with ::: cmptable
and close with :::
. Fenced code blocks are the only elements that
actually get added to Comparison Tables, except that the last header (if any)
before a fenced code block is attached to the cell above.
::: cmptable
### Before
```cpp
switch (x) {
case 0: std::cout << "got zero"; break;
case 1: std::cout << "got one"; break;
default: std::cout << "don't care";
}
```
### After
```cpp
inspect (x) {
0: std::cout << "got zero";
1: std::cout << "got one";
_: std::cout << "don't care";
}
```
:::
Each fenced code block is pushed onto the current row, and
horizontal rules (---
) are used to move to the next row.
::: cmptable
### Before
```cpp
switch (x) {
case 0: std::cout << "got zero"; break;
case 1: std::cout << "got one"; break;
default: std::cout << "don't care";
}
```
### After
```cpp
inspect (x) {
0: std::cout << "got zero";
1: std::cout << "got one";
_: std::cout << "don't care";
}
```
---
```cpp
if (s == "foo") {
std::cout << "got foo";
} else if (s == "bar") {
std::cout << "got bar";
} else {
std::cout << "don't care";
}
```
```cpp
inspect (s) {
"foo": std::cout << "got foo";
"bar": std::cout << "got bar";
_: std::cout << "don't care";
}
```
:::
The last block quote > caption
(if any) is used as the caption.
::: cmptable
> Put your caption here
### Before
```cpp
switch (x) {
case 0: std::cout << "got zero"; break;
case 1: std::cout << "got one"; break;
default: std::cout << "don't care";
}
```
### After
```cpp
inspect (x) {
0: std::cout << "got zero";
1: std::cout << "got one";
_: std::cout << "don't care";
}
```
:::
Paragraph numbers are bracketed Span
elements that look
like: [2]{.pnum}
and [2.1]{.pnum}
.
[2]{.pnum} An expression is _potentially evaluated_ unless it is an unevaluated
operand (7.2) or a subexpression thereof. The set of _potential results_ of
an expression `e` is defined as follows:
- [2.1]{.pnum} If `e` is an _id-expression_ (7.5.4), the set contains only `e`.
- [2.2]{.pnum} If `e` is a subscripting operation (7.6.1.1) with an array operand,
the set contains the potential results of that operand.
Large changes are fenced Div
blocks with ::: add
for additions, ::: rm
for removals.
Small, inline changes are bracketed Span
elements that looks like
[new text]{.add}
or [old text]{.rm}
.
Use line blocks (|
) in order to preserve the leading spaces.
> | _selection-statement:_
> | `if constexpr`_~opt~_ `(` _init-statement~opt~_ _condition_ `)` _statement_
> | `if constexpr`_~opt~_ `(` _init-statement~opt~_ _condition_ `)` _statement_ `else` _statement_
> | `switch (` _init-statement~opt~_ _condition_ `)` _statement_
> | [`inspect` `constexpr`~_opt_~ `(` _init-statement~opt~_ _condition_ `)` `{`
> _inspect-case-seq_
> `}`]{.add}
>
> ::: add
> | _inspect-case-seq:_
> | _inspect-case_
> | _inspect-case-seq_ _inspect-case_
>
> | _inspect-case:_
> | _attribute-specifier-seq~opt~_ _inspect-pattern_ _inspect-guard~opt~_ `:` _statement_
>
> | _inspect-pattern:_
> | _wildcard-pattern_
> | _identifier-pattern_
> | _constant-pattern_
> | _structured-binding-pattern_
> | _alternative-pattern_
> | _binding-pattern_
> | _extractor-pattern_
>
> | _inspect-guard:_
> | `if (` _expression_ `)`
> :::
There are three supported styles of note:
-
Use the
note
class for notes that are expected to appear in the specification wording[Notes will look like this]{.note}
-
Use the
ednote
for editorial notes, these will be formatted as[Editorial notes are important]{.ednote}
-
Use
draftnote
to include text that is intended as questions or information for reviews and working groups.[Drafting notes can be used to provide comments for reviewers that are explicitly not to be included in the specification.]{.draftnote} [It is also possible to indicate the a note is for a specific `audience` via this optional attribute.]{.draftnote audience="the reader"}
Stable names are bracketed Span
elements that look like: [stable.name]{.sref}
.
In [expr.sizeof]{.sref}/5:
The identifier in a `sizeof...` expression shall name a [parameter]{.rm} pack.
The `sizeof...` operator yields the number of [arguments provided for]{.rm}
[elements in]{.add} the [parameter]{.rm} pack [identifier]{.rm} ([temp.variadic]{.sref}).
You may can also add a class -
or .unnumbered
to omit the section number.
For example, [expr.sizeof]{- .sref}
or [expr.sizeof]{.unnumbered .sref}
Run
make update
to update the local cache ofannex-f
.
In-text citations look like this: [@id]
The bibliography is automatically generated from https://wg21.link/index.yaml for citations of the following types.
Type | Id |
---|---|
Paper | Nxxxx / PxxxxRn |
Issue | CWGxxxx / EWGxxxx / LWGxxxx / LEWGxxxx / FSxxxx |
Editorial | EDITxxx |
Standing Document | SDx |
The [@N3546]
example from Citations generates:
Run
make update
to update the local cache ofindex.yaml
.
Manual references are specified in a YAML metadata block similar to Title, typically at the bottom of the document.
The `id` field is for in-text citations (e.g., [@PAT]),
and `citation-label` is the label for the reference.
Typically `id` and `citation-label` are kept the same.
---
references:
- id: PAT
citation-label: Patterns
title: "Pattern Matching in C++"
author:
- family: Park
given: Michael
URL: https://github.com/mpark/patterns
---
If you build for LaTeX output and you have Unicode characters in any of
your paper's source code, you may have problems. First, the default PDF engine
simply does not support Unicode characters. You can add --pdf-engine=xelatex
to the call to pandoc
in the Makefile
to use xelatex
instead.
That gives you access to some font selections for different parts of your paper
(see the Fonts section of the Pandoc manual). The option that controls your
source code fonts is monofont
. You can add a line with your monofont
choice
to your YAML metadata block. Here, it's "DejaVu Sans Mono" which provides
glyphs for a large amount of the Unicode characters:
---
title: Integration of chrono with text formatting
document: P1361R0
date: 2018-10-16
audience:
- Library Evolution Working Group
- Library Working Group
author:
- name: Victor Zverovich
email: <victor.zverovich@gmail.com>
- name: Daniela Engert
email: <dani@ngrt.de>
- name: Howard E. Hinnant
email: <howard.hinnant@gmail.com>
monofont: "DejaVu Sans Mono"
---
If you want the list of available fonts on your system, most supported systems will produce a list via the command-line tool fc-list
.
Distributed under the Boost Software License, Version 1.0.
- Blog Post: How I format my C++ papers
- Lightning Talk @ C++Now 2019: WG21 Paper in Markdown