Contributing to dlang.org
This document is aimed at people who want to contribute to the dlang.org website. It includes a brief tutorial in the technologies used and step-by-step instructions for typical tasks.
Installing
We assume you already have a dmd rig up and running. If not, follow the steps at Starting as a Contributor to get it running. The directory structure we'll assume in the following is:
~/ d/ dmd/ druntime/ phobos/
With this setup, let's proceed to downloading the source of dlang.org as follows:
cd ~/d
git clone https://github.com/D-Programming-Language/dlang.org
After this, the dlang.org directory will end up parallel to dmd, druntime, and phobos. Let's build the site (for now without the standard library documentation) by using the following command:
cd ~/d/dlang.org
make -j32 -f posix.mak html
The html target instructs make to only build the site. By default (if you specify no target), make also builds the core runtime and standard library documentation, both for the latest release and for the current code residing on your machine. That may get pretty involved, so let's leave it for later. For now, let's inspect the result of the build, all of which goes in the dlang.org/web directory. On Linux, for example, the command sensible-browser opens your default browser with a given file or address so we can use it as such:
sensible-browser ~/d/dlang.org/web/index.html
At this point if all went well a nicely-formatted HTML file pops up featuring a local replica of the dlang.org homepage. Congratulations!
Editing Content
Browsing through ~/d/dlang.org/ reveals that most files have the .dd extension. Those files are in Ddoc format; in order to work on dlang.org a basic understanding of the Ddoc format is needed.
At its core, Ddoc is a pure macro expansion system. In this context "pure" means the macro language has no relationship to other file format; all the expansion engine does is take in macro definitions and then munch through text and expand macros as they come along. A few macros are predefined to values that make HTML generation easy, so in that sense a slight affinity with HTML does exist; however, those macros can be trivially redefined to any other purpose. Also, Ddoc recognizes sections marked in a particular way as D source code. There are a few subtleties inherent to macro processors (e.g. how recursion works or in what order nested macros are expanded), but aside from those Ddoc is deceptively simple and very flexible. Exploiting the favorable relationship between Ddoc's simplicity and power is key to using it effectively.
Ddoc source files have the following structure:
Ddoc
Text with embedded macros such as $(MACRO1) and $(MACRO2) goes here.
Macros:
MACRO1=definition1
MACRO2=definition2
That is, a Ddoc file consists of the actual word "Ddoc" followed by a newline, then followed by the actual text of the document, followed by a line containing "Macros:", followed by macro definitions of the form NAME=value. The "Macros:" section is optional (as is the indentation of the macro definitions; it's present here for aesthetic reasons only). You might have guessed already that the syntax $(MACRONAME) expands the macro called MACRONAME into whatever text was ascribed to it in the "Macros:" section. Let's actually test that by saving the following text into a file called e.g. test.dd:
Ddoc
Text with embedded macros such as $(MACRO1) and $(MACRO2) goes here.
Macros:
MACRO1=definition1
MACRO2=definition2
DDOC_COMMENT=
DDOC=$(BODY)
The last two macro definitions seem to come out of nowhere and deserve some explanation, which this document will provide soon. For now let's "build" this file like this:
~/d/dmd/src/dmd test.dd
cat test.html
(You may of course just type dmd if it's in your $PATH) The produced file, by default carrying the .html extension, contains:
Text with embedded macros such as definition1 and definition2 goes here.
So the macro names got expanded to the text in their respective definitions. Sweet!
The Ddoc Expansion Process
Time to clear the air about the mysterious DDOC_COMMENT= and DDOC=$(BODY) definitions. When dmd processes a .ddoc file, it doesn't immediately expand the text; the process goes as follows:
- accumulate the text (sans the opening Ddoc\n) in memory and put it in a variable called BODY;
- when processing reaches the \nMacros:\n section, read and memorize the macro definitions underneath;
- expand and output $(DDOC_COMMENT Generated by Ddoc from filename.dd);
- expand and output the macro DDOC.
The default values of DDOC_COMMENT and DDOC are geared toward building simple HTML files. Indeed, if we remove the macro definitions from the test.dd file and rebuild, the resulting test.html contains:
<html><head>
<META http-equiv="content-type" content="text/html; charset=utf-8">
<title>test</title>
</head><body>
<h1>test</h1>
<!-- Generated by Ddoc from test.dd -->
Text with embedded macros such as definition1 and definition2 goes here.
<hr><small>Page generated by <a href="http://dlang.org/ddoc.html">Ddoc</a>. </small>
</body></html>
which is a serviceable albeit bland HTML document.