Help for FAQ Editors
Who Should Read This… and Why
Who: C++ FAQ Editors should read this.
Why: it gives you the essentials of how to properly update the FAQ.
Style (Don’t Skip This)
There are lots of things in the FAQ that are broke: pre-C++11 advice, weak on TMP, etc. Please fix those. With great vigor.
But please don’t ‘fix’ the casual, fun, pithy writing style; that writing style ain’t broke. The FAQ uses tasteful but colorful language, it is often pointed, and rarely boring. Readers love that style; some writers don’t. The geek in all of us wants to be tone-neutral, flat, staid. In contrast, the FAQ is a fun read. Readers actually enjoy reading it. That keeps them reading, and they end up understanding C++ better as result. They have fun, and they either keep reading or come back again later or both. Please don’t ‘fix’ this style; it has been proven to be effective for more than two decades with hundreds of thousands of readers. The style ain’t broke.
Sample of what Ain’t Broke: the Teaser-Lines. FAQ answers start with a teaser line: an incomplete, sometimes comical statement that is occasionally outrageous and often imprecise or inaccurate or both. The teaser is not the place for the nitty gritty, accurate, complete answer with all the if’s and’s and but’s — that’s what the rest of the FAQ’s answer is for. The teaser-line is an attention-getter; it whets the appetite and intices the reader into the real answer. It’s the sizzle, not the steak. Please don’t try to make it ‘complete’ or ‘accurate.’
Sample of what Ain’t Broke: the “Xyzzy is Evil” lingo. The FAQ intentionally uses outrageous lingo like “evil” or “righteous” when talking about technical constructs. It’s part of the playfulness theme, it makes the FAQ enjoyable and engaging, and readers read more and learn more because they enjoy the experience. So please don’t ‘fix’ it by removing the word evil. And don’t get anal-retentive about demanding a hyper-precise and technically defensible definition of exactly when a particular construct is evil vs. righteous: an evil construct isn’t one that should never be used — it is simply a construct to generally avoid except when it the lesser of the other evils, the least bad of the alternatives. There’s even a FAQ explaining the FAQ’s use of the term. It’s lighthearted and tongue-in-cheek, and it is good for readers. Please don’t rip it out.
“Always”/”Never”, “Prefer”/”Avoid”, and “Consider”. We acknowledge that virtually all guidelines have exceptions. Note that even the constructs labeled as “evil” aren’t “Never Use Xyz”-rules; the FAQ says that evil constructs are appropriate when they are the lesser of the other evils. With that in mind, prefer using these words in guidelines (following C++ Coding Standards): “always” and “never” mean “this should just flow out of your fingertips (or not) by default” except in rare cases; “prefer” and “avoid” mean “often right (or wrong) but be aware of some common exceptions” where you might do differently; and “consider” means “this is a technique that can be useful in specific situations.
Summary: The FAQ needs a lot of technical changes. Lots. But the readers love its playful, fun-to-read style — a style that has been validated since 1991. Have fun as a writer, then your readers will also have fun. That will keep them reading, which ultimately causes them to learn more C++. So flop your stinky feet up onto your messy desk, kick back, and keep the FAQ perky.
IDs for Every FAQ and Chapter
Every FAQ and Chapter has an ID that is globally unique throughout the FAQ and is immutable. These IDs are used for the (many!) internal cross references.
In the example below, the chapter’s ID is ctors, which is also (by design!)
the basename of its URL: http://www.isocpp.org/wiki/faq/ctors
. The FAQ’s ID is init-lists.
## Constructors {#ctors} … ### Should my constructors use “initialization lists” or “assignment”? {#init-lists} …
Keys for working with IDs:
- IDs are Globally Unique. Chapter and FAQ IDs are combined into a single namespace, so the “globally
unique” requirement means there must not be any other Chapter or FAQ with ID
ctors
, and similarly there must not be any other Chapter or FAQ with IDinit-lists
. - IDs are Immutable. Chapter and FAQ IDs are immutable: once they have been published, they must never be changed. A Chapter’s (human readable) title can be changed, but its ID (once published) must never be changed. Similarly a FAQ’s (human readable) question and answer can be changed, but its ID (once published) must never be changed.
- FAQ IDs Name the FAQ’s Subject, Not its Location. Unless a given FAQ is bound into a specific Chapter,
resist the temptation to use the Chapter-ID as a prefix for the FAQ ID. A FAQ’s ID should give editors a
handle on what it is, not where it is (since it might, and often will, get relocated into a different
chapter). For example, there’s a FAQ describing the Nifty Counter Idiom, which happens (as of this writing)
to be located in the chapter called “Constructors” (ID
ctors
), however the Nifty Counter Idiom’s ID isnifty-counter-idiom
, notctors-nifty-counter-idiom
. - IDs are Used as Link Targets. The Markdown syntax for all links to all Chapters and FAQs must always use the target’s ID, never its URL. The mechanisms that produce HTML turn those IDs into real URLs and provide ways to resolve those URLs even after the target is moved. In other words, permalinks.
The big picture goal here is to enable plasticity in the table of contents. The FAQ is a living document; its overall organization will change over time. To improve the FAQ’s utility to readers, FAQ editors will, over time, add new FAQs, reorder the FAQs within a Chapter, move FAQs from one Chapter to another, reorder the Chapters, split Chapters, and creating new Chapters. Because of IDs and all the other mechanisms surrounding IDs, all these changes can be made without fear of link rot. All links, even “deep” links, are permalinks.
IDs are good.
Use them for the children.
FAQ-Markdown Basics
The C++ FAQ uses a variant of Markdown (a superset of a subset of the union of Markdown and SmartyPants). This section explains the basics you will need when editing a FAQ.
When you want… | You type… | Readers see… | Discussion | ||||||
---|---|---|---|---|---|---|---|---|---|
Use Markdown, Not HTML | Prefer Markdown here! |
Prefer Markdown here! |
FAQ-Markdown allows embedded HTML, but that should be extremely rare. The FAQ proper is currently (Sept 2013) 99.999% Markdown and 0.001% HTML. Who knows if that ratio might shift some, but HTML should remain rare. |
||||||
Paragraphs | Ordinary text flows into paragraphs automatically. To start a new paragraph, separate it from preceding text with a blank line.Adjacent lines
flow into a
paragraph.
A blank line
starts a new
paragraph. |
Adjacent lines flow into a paragraph. A blank line starts a new paragraph. |
|||||||
Curly Double Quotes | Like “this”
TODO: Use JS to inject “
|
Like “this” |
They aren’t curlified in a `code-span` or ~~~~code-block~~~~ |
||||||
Curly Single Quotes | It’s like ‘this’, ‘k?
TODO: Use JS to inject ‘
|
It’s like ‘this’, ‘k? |
Not curlified in a `code-span` or ~~~~code-block~~~~ |
||||||
Hyphen | Like - this. |
Like - this. |
|||||||
“en” dash | Like -- this. |
Like – this. |
|||||||
“em” dash | Like --- this. |
Like — this. |
|||||||
Bold | Like **this** |
Like this |
Use **this** Not __this__ Why: consistency with the rest of the FAQ |
||||||
Italics | Like *this* |
Like this |
Use *this* Not _this_ Why: consistency with the rest of the FAQ |
||||||
Code-span | Like `std::cout << 42` |
Like std::cout << 42 |
Code-spans preserve horizontal whitespace. Code-spans quote most Markdown meta-chars: |
||||||
Link to a Chapter of the FAQ |
Like [this][ctors]
(Target = ID ctors)
|
Like this
|
When linking to a Chapter: Use the target’s ID Not the target’s URL Why: see here for details. |
||||||
Link to an individual FAQ |
Like [this][init-lists]
(Target = ID init-lists)
|
Like this
|
When linking to a FAQ: Use the target’s ID Not the target’s URL Why: see here for details. |
||||||
Link to an external web page |
Like [this](http://boost.org)
(Target = URL http://boost.org)
|
Like this
|
When linking to an external web page: Use the target’s URL | ||||||
Several links to the same external web page |
Like [this][42].
…
And [also this][42].
…
[42]: http://boost.org
(Target = URL in [42]: …)
|
These home-grown IDs are local/scoped to the Chapter. Use numbers for these home-grown IDs |
|||||||
Unordered List |
Lorem ipsum
+ Dolor sit
amet.
+ Sed do eiusmod
tempor.
+ Dolore magna
aliqua.
Ut enim ad minim veniam.
(That’s space “+” space)
|
Lorem ipsum
Ut enim ad minim veniam. |
Use + … Not * … Why: consistency with the rest of the FAQ |
||||||
Ordered List |
Lorem ipsum
1. Dolor sit
amet.
1. Sed do eiusmod
tempor.
1. Dolore magna
aliqua.
Ut enim ad minim veniam.
(That’s space “1.” space)
|
Lorem ipsum
Ut enim ad minim veniam. |
Use 1. … 1. … 1. … Not 1. … 2. … 3. … Why: reduce tedium, eliminate manual renumbering |
||||||
List of List |
Lorem ipsum
+ Dolor sit amet
+ Consectetur
+ Adipisicing
+ Elit
+ Sed do eiusmod tempor
+ Incididunt
+ Ut
+ Labore
+ Dolore magna aliqua.
Ut enim ad minim veniam.
|
Lorem ipsum
Ut enim ad minim veniam. |
Nest either {unordered, ordered} …inside either {unordered, ordered} …to any nesting level. |
||||||
Indentation |
Lorem ipsum
> dolor sit
> amet.
Consectetur adipisicing elit
(That’s space “>” space) |
Lorem ipsum
Consectetur adipisicing elit |
Use > > … for double-indent. Use > + … to indent a bullet-list. Use > 1. … to indent an ordered-list. Use > ~~~~ to indent a code-block. Use > | … | to indent a table. |
||||||
Code-Block |
~~~~
void f(int n)
{
// code is prettified
std::cout << “n = ” << n
<< std::endl;
}
~~~~
|
|
Code-blocks preserve whitespace. Code-blocks quote most Markdown meta-chars: |
||||||
Tables |
| Function | Description |
| --------- | --------------- |
| `help()` | Show help info |
| `crash()` | *Crash Matrix!* |
|
|
Use <br> to add a line-break within a table-cell. Use the (optional) leading/trailing |s You don’t need to “line up” the |s. |
See below for rules regarding meta-character like +, *, >, |, ~, `, etc.
Creating New and/or Reordering Chapters/FAQs
“Structural” changes are changes which affect the overall table of contents. That means new Chapters/FAQs, the titles of the Chapters/FAQs, or the order of the Chapters/FAQs.
Create New Chapters
Each Chapter is a web page, implemented as a single contiguous markdown file, and has this form:
## Chapter Title Goes Here {#chapter-id-goes-here} /*…FAQs go here…*/ {embed=”id-defns”}
The chapter’s ID (shown above as chapter-id-goes-here
): (1) Must start with lower-case a-z, followed
optionally by lower-case a-z, digits 0-9, and/or hyphens; e.g., abcs
not ABCs
,
input-output
not input_output
, big3
. (2) Is
immutable: once published, a chapter’s ID must never change; its textual title can be changed, but not its
ID. (3) Must be globally unique: no chapter ID may be the same as the ID of any
other chapter or of any FAQ. (4) Must match the basename part of the URL, e.g., ID input-output
must go with
URL http://www.isocpp.org/wiki/faq/input-output
.
Before the page is published, one of the admins must add the newly created chapter into the magical id-defns file. It must also be added to the main index page.
Create New FAQs
Each FAQ is contained in a chapter, is part of the chapter’s markdown file, and has this form:
### The Question Goes Here? {#faq-id-goes-here} …pithy teaser-line goes here… …main body of the FAQ goes here…
The FAQ’s ID (shown above as faq-id-goes-here
): (1) Must start with lower-case a-z, followed optionally by
lower-case a-z, digits 0-9, and/or hyphens; e.g., nan
not NaN
,
const-cast
not const_cast
, etc. (2) Is
immutable: once published, a FAQ’s ID must never change; its textual title/question can be changed, but
not its ID. (3) Must be globally unique: no FAQ ID may be the same as the ID of
any other FAQ or any chapter.
Before the page is published, one of the admins must add the newly created FAQ into the magical id-defns file.
The detailed answer is where you flesh out the pithy teaser-line. If there are enough if’s and’s and but’s to render the the teaser-line misleading, it’s often best to leave the teaser-line misleading but start the main body with a confession, such as, “That was an oversimplification; keep reading for the real deal.” The idea is to motivate them to slog through the gnarly details.
As a general pattern, it’s more readable and approachable if you handle the common case first, then later add the edge cases.
Reorder Chapters
To reorder existing chapters, simply change the order they appear in the master index file.
Reorder FAQs
To reorder existing FAQs within the same chapter, simply edit the chapter and move them around.
To move a FAQ from one chapter to another, move the FAQ to the new chapter file, then get an admin to modify into the magical id-defns file.
Modify Chapter Title
Open the chapter, click Edit, and modify the human-readable text of the chapter-title (“Classes and Objects” in the example below), then get an admin to modify into the magical id-defns file.
Taken from http://www.isocpp.org/wiki/faq/classes-and-objects
## Classes and Objects {#classes-and-objects} /*…blah blah…*/
The chapter title is allowed to contain inline Markdown like `code-spans`
, *italics*
, etc., and it can
span multiple physical lines of the Markdown input. It must not contain links, and it must not contain block
items such as code-blocks, ordered/unordered lists, etc.
Reminder: the chapter title is mutable, but the chapter ID (classes-and-objects
in
the above example) is not. Once published, the ID must never be changed.
Modify FAQ Title/Question
Open the chapter, click Edit, and modify the human-readable text of the FAQ-title (“Classes and Objects” in the example below), then get an admin to modify into the magical id-defns file.
Taken from http://www.isocpp.org/wiki/faq/inline-functions
/*…blah blah…*/ ### Do `inline` functions improve performance? {#inline-and-perf} Yes and no. Sometimes. Maybe. There are no simple answers. `inline` functions might make the code faster, they might /*…blah blah…*/
The FAQ title/question title is allowed to contain inline Markdown like `code-spans`
, *italics*
, etc.,
and it can span multiple physical lines of the Markdown input. It must not contain links, and it must not
contain block items such as code-blocks, ordered/unordered lists, etc.
Reminder: the FAQ title/question is mutable, but the FAQ ID (inline-and-perf
in the
above example) is not. Once published, the ID must never be changed.
Displaying Meta-Chars
The FAQ’s variant of Markdown and SmartyPants has a number of meta-chars. Unfortunately some of them are common in C++ code; be careful.
The table below explains which meta-chars are automatically quoted inside a `code-span`
, and the
preferred workaround to showing them as literals.
For example, if you type ptr = ®
it shows up as ptr = ® (&
is a meta-char), and if you type f<int>()
it
shows up as f<int>
is syntactically like an HTML element); however both of these can be repaired
via a `code-span`
.
The other way to force meta-chars to show up as literals is to put them inside a ~~~~ code-block ~~~~
.
Naturally a code-block has a visually distinctive block on the screen; this may or may not be what you want.
Known Bugs and Workarounds
This section enumerates the known bugs/quirks, along with workarounds.
{if...}
Bug: Markdown carps badly (page is completely blank) if you use the
character-sequence {if...}
or &123;if...&125;
anywhere in your Markdown. (Where ‘anywhere’ means in normal text, ###
-headers,
`code-spans`
, ~~~~code-blocks~~~~
; anywhere.)
Note: the ...
part means any chars, for example, {if foo}
or {if-foo}
or {iffy}
or any other sequence
of characters that start with if
.
Examples:
Context If you
use thisOr if you
use thisOr if you
use thisThen this
will happenIn normal text {if}
{if blah}
{iffy blah}
page ‘crashes’
(entire page will be blank)In a header ### {if}
### {if blah}
### {iffy blah}
page ‘crashes’
(entire page will be blank)In a `code-span`
`{if}`
`{if blah}`
`{iffy blah}`
page ‘crashes’
(entire page will be blank)In a ~~~~code-block~~~~
~~~~
{if}
~~~~
~~~~
{if blah}
~~~~
~~~~
{iffy blah}
~~~~
page ‘crashes’
(entire page will be blank)
Workarounds:
When {if...}
appears in normal text (neither `code-span`
nor ~~~~code-block~~~~
):
Do not use
this MarkdownInstead use
this MarkdownResult seen
by readersComments {if...}
(if...)
(if…) Use parens rather than braces {if...}
{ if...}
{ if…} Add a space after the open-brace {if...}
{if...}
{if…} Encode the i
asi
When {if...}
appears in a `code-span`
:
Do not use
this MarkdownInstead use
this MarkdownResult seen
by readersComments `{if...}`
`(if...)`
(if...)
Use parens rather than braces `{if...}`
`{ if...}`
{ if...}
Add a space after the open-brace `{if...}`
<code>{if...}</code>
{if...}
Encode the i
asi
and use an explicit<code>...</code>
When {if...}
appears in a ~~~~code-block~~~~
:
~~~~ Alternative 1: (if...) // use parens rather than braces Alternative 2: { if...} // add a space after the open brace ~~~~