Jump to page: 1 2 3
Thread overview
Improving the D documentation web presentation
May 25, 2020
WebFreak001
May 25, 2020
Paul Backus
May 27, 2020
WebFreak001
May 27, 2020
aberba
May 27, 2020
Guillaume Piolat
May 27, 2020
WebFreak001
May 28, 2020
Adam D. Ruppe
May 28, 2020
WebFreak001
May 29, 2020
Adam D. Ruppe
May 29, 2020
WebFreak001
May 29, 2020
Adam D. Ruppe
May 29, 2020
Adam D. Ruppe
May 29, 2020
Adam D. Ruppe
May 29, 2020
Adam D. Ruppe
May 30, 2020
WebFreak001
Jun 07, 2020
Gabriel
May 27, 2020
Andre Pany
May 27, 2020
WebFreak001
May 30, 2020
bauss
May 30, 2020
James Lu
May 25, 2020
as some of you might know, there are 2 versions of the official phobos documentation:

ddoc based (https://dlang.org/phobos/index.html)
ddox based (https://dlang.org/library/index.html)

I actually quite like the ddox based documentation for future extending because it can contain a lot more information per symbol and also allows us to write much larger examples for standard library functionality. I think this one has better SEO too.

However I still see myself all the time on the ddoc based site as it is simply more polished and faster to find multiple symbols in a module.

So here I have a few small proposals how we could improve on the presentation of the ddox page. I will be referencing to the .NET (C#) documentation quite a lot here, because I think it does a pretty good job.

Polish the overview: the descriptions of modules are currently all kinds of messed up stuff (tables, headings, deprecated warnings), having nicer descriptions (only short strings, no duplicates, no empty ones) would be a good start for this overview page. Also because the left sidebar just shows the same as the list of modules, it would probably be smart to remove the left sidebar so we have more space for description text. Additionally instead of having all APIs in there, I would propose to let the user first select the kind of project they are interested in (phobos, druntime, dmd) and then only show the modules for that project. See https://docs.microsoft.com/en-us/dotnet/api/ for an example.

Move the search: the search at the top right is a google search on all other D pages. On the ddox it's a quick and easy to use search with a different functionality. I think for showing this to the user, it should be moved to the left above the module tree. This search should also be visible on the index if the sidebar is removed there.

Improve navigation: my biggest usability complaint with the ddox API pages is that you have to navigate so much to look through different symbols inside a module, compared to the ddoc page. Much like in the .NET docs, we should show a tree of symbols in the sidebar. I think this could nicely fit and also be easier to read if we slightly increase the padding per entry, make the sidebar scrollable (maybe also add position: sticky) and scroll to the currently selected module by default. I think we can also improve how the currently active selection looks, because right now it is just a darker shade of red with an underline. To not overload this with symbols, only symbols in the currently active module should be shown as children of a module.

What is your thought on the current ddox and ddoc documentation? Which one do you like and/or use more?
May 25, 2020
On Monday, 25 May 2020 at 13:56:10 UTC, WebFreak001 wrote:
> as some of you might know, there are 2 versions of the official phobos documentation:
[...]
> Move the search: the search at the top right is a google search on all other D pages. On the ddox it's a quick and easy to use search with a different functionality.
[...]
> Improve navigation: my biggest usability complaint with the ddox API pages is that you have to navigate so much to look through different symbols inside a module, compared to the ddoc page.
[...]
> What is your thought on the current ddox and ddoc documentation? Which one do you like and/or use more?

IMHO, dpldocs.info is the only version that gets all of this right. Search easily accessible at the top of the page, module contents listed in a sidebar on the left, and detailed pages on each symbol for easy navigation and cross-referencing.

Mostly I access it via duckduckgo's !dpldocs bang [1], which lets me type search queries directly into my browser's address bar, or a shell script I've bound to vim's `K` command (which looks up the identifier under the cursor). It's super convenient.

[1] https://duckduckgo.com/bang
May 25, 2020
On 5/25/20 9:56 AM, WebFreak001 wrote:
> What is your thought on the current ddox and ddoc documentation? Which one do you like and/or use more?

Lots of chatter about that over the years. I grew to appreciate having both options. (We're not alone, e.g. GNU does the same.)
May 27, 2020
On Monday, 25 May 2020 at 16:12:14 UTC, Andrei Alexandrescu wrote:
> On 5/25/20 9:56 AM, WebFreak001 wrote:
>> What is your thought on the current ddox and ddoc documentation? Which one do you like and/or use more?
>
> Lots of chatter about that over the years. I grew to appreciate having both options. (We're not alone, e.g. GNU does the same.)

Unfortunately while searching for `dlang spawnShell` or similar, the first hit on google is https://dlang.org/library/std/process/spawn_shell.html

The function description is not that good:
Pid spawnShell (
  scope const(char)[] command,
  File stdin = makeGlobal(),
  File stdout = makeGlobal(),
  File stderr = makeGlobal(),
  scope const(string[string]) env = cast(const(string[string]))null,
  Config config = cast(Config)0,
  scope const(char)[] workDir = null,
  scope string shellPath = nativeShell()
) @trusted;

comparing to https://dlang.org/phobos/std_process.html#spawnShell

@trusted Pid spawnShell(scope const(char)[] command, File stdin = std.stdio.stdin, File stdout = std.stdio.stdout, File stderr = std.stdio.stderr, scope const string[string] env = null, Config config = Config.none, scope const(char)[] workDir = null, scope string shellPath = nativeShell);

As I know this issue, I refuse to use the first hit on google, but for other users, this
is quite confusing / disturbing I assume.

Kind regards
André
May 27, 2020
On Wednesday, 27 May 2020 at 06:38:46 UTC, Andre Pany wrote:
> On Monday, 25 May 2020 at 16:12:14 UTC, Andrei Alexandrescu wrote:
>> On 5/25/20 9:56 AM, WebFreak001 wrote:
>>> What is your thought on the current ddox and ddoc documentation? Which one do you like and/or use more?
>>
>> Lots of chatter about that over the years. I grew to appreciate having both options. (We're not alone, e.g. GNU does the same.)
>
> Unfortunately while searching for `dlang spawnShell` or similar, the first hit on google is https://dlang.org/library/std/process/spawn_shell.html
>
> The function description is not that good:
> Pid spawnShell (
>   scope const(char)[] command,
>   File stdin = makeGlobal(),
>   File stdout = makeGlobal(),
>   File stderr = makeGlobal(),
>   scope const(string[string]) env = cast(const(string[string]))null,
>   Config config = cast(Config)0,
>   scope const(char)[] workDir = null,
>   scope string shellPath = nativeShell()
> ) @trusted;
>
> comparing to https://dlang.org/phobos/std_process.html#spawnShell
>
> @trusted Pid spawnShell(scope const(char)[] command, File stdin = std.stdio.stdin, File stdout = std.stdio.stdout, File stderr = std.stdio.stderr, scope const string[string] env = null, Config config = Config.none, scope const(char)[] workDir = null, scope string shellPath = nativeShell);
>
> As I know this issue, I refuse to use the first hit on google, but for other users, this
> is quite confusing / disturbing I assume.
>
> Kind regards
> André

oh yep you are right, the values are quite a mess. I just searched for "dlang run program" as I would imagine some newcomer might do. After "Run D program locally - Dlang Tour" the second link is https://dlang.org/library/std/process/execute.html


auto Tuple!(int,"status",string,"output") execute (
  scope const(char[])[] args,
  const(string[string]) env = cast(const(string[string]))null,
  Config config = cast(Config)0,
  ulong maxOutput = 18446744073709551615LU,
  scope const(char)[] workDir = null
) @trusted;

auto Tuple!(int,"status",string,"output") execute (
  scope const(char)[] program,
  const(string[string]) env = cast(const(string[string]))null,
  Config config = cast(Config)0,
  ulong maxOutput = 18446744073709551615LU,
  scope const(char)[] workDir = null
) @trusted;


Compared to


@trusted auto execute(scope const(char[])[] args, const string[string] env = null, Config config = Config.none, size_t maxOutput = size_t.max, scope const(char)[] workDir = null);

@trusted auto execute(scope const(char)[] program, const string[string] env = null, Config config = Config.none, size_t maxOutput = size_t.max, scope const(char)[] workDir = null);

@trusted auto executeShell(scope const(char)[] command, const string[string] env = null, Config config = Config.none, size_t maxOutput = size_t.max, scope const(char)[] workDir = null, string shellPath = nativeShell);


Things I would like to see improved on the documentation page in general:
- use structured standard sections (See_Also, Examples)
  - maybe automatically generate See_Also from mentioned symbols too
- maybe a copy of the module documentation? It's exactly what I had searched for (see https://dlang.org/phobos/std_process.html) and I think it would improve discovery in the ddox style documentation. Some module documentation might need to be adjusted and general examples should probably be omitted.
- we need much more full examples per function! Compare this to the C# documentation which has like examples for every property of commonly used types.
  - to avoid code duplication for this, we need some way to embed examples or other documentation as references inside documentation


Also as an example for a better documented signature of that execute function to show to a beginner I would suggest:


auto Tuple!(int,"status", string,"output") execute(
  scope const(char[])[]  args,
  const string[string]   env       = null,
        Config           config    = Config.none,
        ulong            maxOutput = size_t.max,
  scope const(char)[]    workDir   = null
) @trusted;

auto Tuple!(int,"status", string,"output") execute(
  scope const(char)[]    program,
  const string[string]   env       = null,
        Config           config    = Config.none,
        ulong            maxOutput = size_t.max,
  scope const(char)[]    workDir   = null
) @trusted;


* fixed the default values (made them like in the ddoc docs)
* made const for an entire type format like scope (I think it's more obvious what it means in a formatted context like this)
* horizontally aligned scope/const/in/out, type, argument name, default value
* horizontally aligned across all definitions
* special formatting for Tuple because it's a common type
May 27, 2020
On Monday, 25 May 2020 at 14:54:44 UTC, Paul Backus wrote:
> On Monday, 25 May 2020 at 13:56:10 UTC, WebFreak001 wrote:
>> as some of you might know, there are 2 versions of the official phobos documentation:
> [...]
>> Move the search: the search at the top right is a google search on all other D pages. On the ddox it's a quick and easy to use search with a different functionality.
> [...]
>> Improve navigation: my biggest usability complaint with the ddox API pages is that you have to navigate so much to look through different symbols inside a module, compared to the ddoc page.
> [...]
>> What is your thought on the current ddox and ddoc documentation? Which one do you like and/or use more?
>
> IMHO, dpldocs.info is the only version that gets all of this right. Search easily accessible at the top of the page, module contents listed in a sidebar on the left, and detailed pages on each symbol for easy navigation and cross-referencing.
>
> Mostly I access it via duckduckgo's !dpldocs bang [1], which lets me type search queries directly into my browser's address bar, or a shell script I've bound to vim's `K` command (which looks up the identifier under the cursor). It's super convenient.
>
> [1] https://duckduckgo.com/bang

yep dpldocs is pretty good, we should really promote it, maybe as a replacement to the current ddox one as it is quite similar.

Small things I think could be improved:
- show all overloads extended, or at least a list of method names with types like in https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.process.start?view=netcore-3.1
- automatically collect all referenced functions (in the docs) in the See_Also section - or can you think of a case where this is undesirable?



Also do you think the const(char)[] might be confusing to newcomers?
May 27, 2020
On Wednesday, 27 May 2020 at 07:34:50 UTC, WebFreak001 wrote:
> On Monday, 25 May 2020 at 14:54:44 UTC, Paul Backus wrote:
>> [...]
>
> yep dpldocs is pretty good, we should really promote it, maybe as a replacement to the current ddox one as it is quite similar.
>
> Small things I think could be improved:
> - show all overloads extended, or at least a list of method names with types like in https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.process.start?view=netcore-3.1
> - automatically collect all referenced functions (in the docs) in the See_Also section - or can you think of a case where this is undesirable?
>
>
>
> Also do you think the const(char)[] might be confusing to newcomers?

dpldocs is functionally the best. Not aesthetics though :). If we could give it the ddoc look and feel, that'll be complete.
May 27, 2020
On Wednesday, 27 May 2020 at 09:51:16 UTC, aberba wrote:
>
> dpldocs is functionally the best. Not aesthetics though :). If we could give it the ddoc look and feel, that'll be complete.

+1

dpldocs also has a hidden functionality of searching across all packages whose dpldocs is generated
May 27, 2020
On Wednesday, 27 May 2020 at 09:51:16 UTC, aberba wrote:
> [...]
>
> dpldocs is functionally the best. Not aesthetics though :). If we could give it the ddoc look and feel, that'll be complete.

I tinkered a little bit with the HTML and CSS of dpldocs, here are some changes I made:

Screenshots:

Before:
https://i.imgur.com/bQ60YWA.png
After:
https://i.imgur.com/hJOGhrR.png

Before:
https://i.imgur.com/i2tow79.png
After:
https://i.imgur.com/JKingMa.png

Module:
https://i.imgur.com/PmJlkoo.png

I didn't touch the headerbar, I think the design should just be copied from the homepage there.

HTML changes:

- Added a span inside the h1 title with class .name
- Prepended the symbol kind as text to the title ("Function")
- Add `lang="en"` to <html>
	JS code to preview this: document.body.parentElement.setAttribute("lang", "en")
- In the Parameters section move all the types into the parameter names
	JS code to preview this: document.querySelectorAll(".parameter-descriptions dt").forEach(dt => dt.appendChild(dt.nextElementSibling.querySelector(".parameter-type")))
- Delete the empty parameter type holders
	JS code to preview this: document.querySelectorAll(".parameter-type-holder:empty").forEach(a => a.parentElement.removeChild(a))
- In the Parameters section delete the "Type:" string for each argument
	JS code to preview this: document.querySelectorAll(".parameter-descriptions .parameter-type-holder").forEach(t => t.removeChild(t.childNodes[0]));
- for each pre.d_code.highlighted, insert a <header> tag before it, move the "Copy to Clipboard" and "Toggle Line Numbers" buttons into the header tag, wrap everything in a <div class="codeblock">
	JS code to preview this: document.querySelectorAll("pre.d_code.highlighted").forEach(c=>{c.parentElement.insertBefore(h=document.createElement("header"),c);while(b=h.previousElementSibling,b.tagName=="BUTTON")h.prepend(b);h.parentElement.insertBefore(w=document.createElement("div"),h);w.className="codeblock";w.appendChild(h);w.appendChild(c)})
- Disable Line numbers by default for short code (<15 lines)
- Delete & Disable the dynamic style (resize style)
	JS code to preview this: window.onresize = undefined; var d = document.querySelector("#dynamic-style"); d.parentElement.removeChild(d);
- In the small overloads buttons (.overloads>li .overload-signature), remove all parameter type qualifiers and default values, only keep names and basic types

Quick apply JS:
// manually add function kind & span.name
// manually disable line numbers in short code blocks
// manually edit overload buttons to only have argument types & names
document.body.parentElement.setAttribute("lang", "en")
document.querySelectorAll(".parameter-descriptions dt").forEach(dt => dt.appendChild(dt.nextElementSibling.querySelector(".parameter-type")))
document.querySelectorAll(".parameter-type-holder:empty").forEach(a => a.parentElement.removeChild(a))
document.querySelectorAll(".parameter-descriptions .parameter-type-holder").forEach(t => t.removeChild(t.childNodes[0]));
document.querySelectorAll("pre.d_code.highlighted").forEach(c=>{c.parentElement.insertBefore(h=document.createElement("header"),c);while(b=h.previousElementSibling,b.tagName=="BUTTON")h.prepend(b);h.parentElement.insertBefore(w=document.createElement("div"),h);w.className="codeblock";w.appendChild(h);w.appendChild(c)})
window.onresize = undefined; var d = document.querySelector("#dynamic-style"); d.parentElement.removeChild(d);


Additional work to be done:

Make link for `const(char)[]` as type explaining that it works with strings and char arrays. Also embed the graph from and link to https://dlang.org/spec/const3.html#implicit_qualifier_conversions

Make link for `size_t` and `ptrdiff_t` as type explaining that it's an (unsigned) integer type, commonly (u)int or (u)long with link to https://dlang.org/spec/type.html#size_t

CSS additions:

#page-body #page-content {
  padding-left: 1.75em;
}

#page-content h1:first-child {
  margin-top: 2rem;
  font-size: 2.2rem;
  font-family: "Roboto Slab", sans-serif;
  font-weight: normal;
  margin-bottom: 0.5rem;
}

#page-content h1:first-child + .breadcrumbs {
  margin-top: 0;
}

#page-content h1 .name {
  font-family: Consolas, "Bitstream Vera Sans Mono", "Andale Mono", Monaco, "DejaVu Sans Mono", "Lucida Console", monospace;
}

#page-content h2,
#page-content h3 {
  margin-top: 1.5em;
  font-family: "Roboto Slab", sans-serif;
  font-weight: normal;
}

#page-content h2 {
  font-size: 1.6rem;
}

#page-content h3 {
  font-size: 1.26rem;
}

#table-of-contents, .enum-members, .documentation-comment .tip, .documentation-comment .note, .documentation-comment .warning, .documentation-comment .pitfall, .documentation-comment li, .documentation-comment p {
  font-size: 1rem;
}

#page-body #page-nav {
  padding-left: 1em;
  padding-right: 0;
  border-left-style: solid;
  border-left-width: 1px;
  overflow: unset;
}

#page-nav ul {
  list-style: none;
}

#page-nav .type-separator {
  margin-bottom: 0.25em;
}

#page-nav a {
  box-sizing: border-box;
  font-family: "Roboto Slab", sans-serif;
  padding: 1pt 0.25em 1pt 0.5em;
  text-overflow: ellipsis;
  overflow: hidden;
}

#page-nav a:hover {
  position: relative;
  overflow: visible;
  z-index: 10;
  background-color: rgb(245, 245, 245);
  width: max-content;
}

#page-nav a.parent {
  line-height: 0.9;
  overflow: visible;
}

#page-nav a.parent:first-child {
  margin-top: 0.75em;
}

tt.D, .inline-code, .parameter-descriptions .parameter-name {
  color: black;
	font-weight: 500;
	background-color: #f2f2f2;
	padding: 0px 0.5ex;
  border-radius: 2px;
}

.parameter-descriptions .parameter-name {
  margin-right: 1.5rem;
  font-weight: bold;
	padding: 0.25ex 0.75ex;
}

.parameter-descriptions dd {
  margin-left: 1.5em;
}

.parameter-descriptions dd p:first-child {
  margin-top: 0.5em;
}

.parameter-descriptions dt:not(:first-child) {
  margin-top: 1.5em;
}

.codeblock {
  border: solid 1px #ccc;
  padding: 0;
  margin: 0;
}

.codeblock header {
  background-color: #e8e8e8;
  padding: 0;
  display: flex;
  justify-content: flex-end;
}

.codeblock header:before {
  display: inline-block;
  content: "Example";
  justify-content: flex-start;
  flex-grow: 1;
  padding: 0.25em 1em;
  font-weight: bold;
}

.codeblock header button {
/*  TODO: add :before class with icons here (copy, line numbers)  */
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  margin: 0;
  padding: 0 1em;
  background-color: transparent;
  border: none;
  border-left: 1px solid #ccc;
  cursor: pointer;
}

.codeblock header button:hover {
  background-color: rgba(255, 255, 255, 0.5);
}

.codeblock pre.d_code {
  border: none;
  border-top: solid 1px #ccc;
  margin: 0;
  padding: 1em 0;
  max-width: unset !important;;
}

.hide-line-numbers .codeblock .with-line-wrappers,
.codeblock pre.d_code:not(.with-line-wrappers) {
  padding: 1em;
}

.codeblock .with-line-wrappers .br {
  margin-right: 1em;
}

.annotated-prototype .overloads li {
  margin: 0;
}

.member-list .dt, .overload-option, pre {
  max-width: unset;
}

.documentation-comment p {
  hyphens: auto;
}

.declaration-prototype, .aggregate-prototype, .function-prototype {
  margin-left: 0;
  margin-right: 0;
}

May 28, 2020
On Wednesday, 27 May 2020 at 12:55:07 UTC, WebFreak001 wrote:
> [...]

So I'm gonna integrate at least some of this tonight or tomorrow... but probably not all of it.

> - Prepended the symbol kind as text to the title ("Function")

like idk the value of this.

> - Disable Line numbers by default for short code (<15 lines)

fun fact i think right now my limit is 7 lines...

> - Delete & Disable the dynamic style (resize style)

I know I put that in for a reason but forgot what it was... what was it breaking for you?




>   max-width: unset !important;;

these max widths too btw were there to keep the main content from going wide just because of some long line in an example.

I gotta extract the diffs and put it in here to try on the sdpy docs.

> .documentation-comment p {
>   hyphens: auto;
> }

i hate hyphens tho
« First   ‹ Prev
1 2 3