Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
37 changes: 37 additions & 0 deletions changelog/fix18361.dd
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
Fix issue 18361 - Ddoc ability to opt-out of automatic keyword highlighting in running text

Currently, ddoc automatically highlights all occurrences of words in running
text that coincide with the symbol or module being documented, or a parameter
name of a function being documented. While convenient, it often caused
unintended highlighting of normal words in text when module, function, or
parameter identifiers coincide with normal words. This led to a proliferation
of prefixing words with `_` in order to suppress this behaviour.

Now a better solution has been implemented to completely opt-out of this
feature via the `DDOC_AUTO_PSYMBOL`, `DDOC_AUTO_KEYWORD`, and `DDOC_AUTO_PARAM`
macros, which are used for all such automatically-highlighted words in running
text. Occurrences of module, function, or parameter names inside code blocks
are not included. By default, these macros simply redirect to `DDOC_PSYMBOL`,
`DDOC_KEYWORD`, and `DDOC_PARAM`, but the user can now redefine these macros so
that they simply expand to the word itself without any highlighting:

----
DDOC_AUTO_PSYMBOL = $0
DDOC_AUTO_KEYWORD = $0
DDOC_AUTO_PARAM = $0
----

Furthermore, whenever a word is prefixed with `_` to suppress automatic
highlighting, it is now wrapped in the `DDOC_AUTO_PSYMBOL_SUPPRESS` macro. This
is to provide users who wish to opt out of automatic highlighting an easy way
to find all occurrences of these underscore prefixes so that they can be
removed from the text. For example, they can redefine this macro to something
highly-visible and easily searched for, such as:

----
DDOC_AUTO_PSYMBOL_SUPPRESS = FIXME_UNDERSCORE_PREFIX $0
----

and then search the generated documentation for the string
`FIXME_UNDERSCORE_PREFIX` and delete the `_` prefix from all corresponding
parts of the documentation comment text.
4 changes: 4 additions & 0 deletions res/default_ddoc_theme.ddoc
Original file line number Diff line number Diff line change
Expand Up @@ -736,3 +736,7 @@ DDOC_OVERLOAD_SEPARATOR = $0
DDOC_TEMPLATE_PARAM_LIST = $0
DDOC_TEMPLATE_PARAM = $0
DDOC_LINK_AUTODETECT = $(LINK $0)
DDOC_AUTO_PSYMBOL = $(DDOC_PSYMBOL $0)
DDOC_AUTO_KEYWORD = $(DDOC_KEYWORD $0)
DDOC_AUTO_PARAM = $(DDOC_PARAM $0)
DDOC_AUTO_PSYMBOL_SUPPRESS = $0
8 changes: 4 additions & 4 deletions src/dmd/doc.d
Original file line number Diff line number Diff line change
Expand Up @@ -2472,23 +2472,23 @@ extern (C++) void highlightText(Scope* sc, Dsymbols* a, OutBuffer* buf, size_t o
if (c == '_' && (i == 0 || !isdigit(*(start - 1))) && (i == buf.offset - 1 || !isReservedName(start, len)))
{
buf.remove(i, 1);
i = j - 1;
i = buf.bracket(i, "$(DDOC_AUTO_PSYMBOL_SUPPRESS ", j - 1, ")") - 1;
break;
}
if (isIdentifier(a, start, len))
{
i = buf.bracket(i, "$(DDOC_PSYMBOL ", j, ")") - 1;
i = buf.bracket(i, "$(DDOC_AUTO_PSYMBOL ", j, ")") - 1;
break;
}
if (isKeyword(start, len))
{
i = buf.bracket(i, "$(DDOC_KEYWORD ", j, ")") - 1;
i = buf.bracket(i, "$(DDOC_AUTO_KEYWORD ", j, ")") - 1;
break;
}
if (isFunctionParameter(a, start, len))
{
//printf("highlighting arg '%s', i = %d, j = %d\n", arg.ident.toChars(), i, j);
i = buf.bracket(i, "$(DDOC_PARAM ", j, ")") - 1;
i = buf.bracket(i, "$(DDOC_AUTO_PARAM ", j, ")") - 1;
break;
}
i = j - 1;
Expand Down
27 changes: 27 additions & 0 deletions test/compilable/ddoc18361.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// PERMUTE_ARGS:
// REQUIRED_ARGS: -D -Dd${RESULTS_DIR}/compilable -o-
// POST_SCRIPT: compilable/extra-files/ddocAny-postscript.sh 18361
// REQUIRED_ARGS: -d

// Test notes: 'main' is the symbol being documented (DDOC_AUTO_PSYMBOL),
// 'arguments' is a parameter (DDOC_AUTO_PARAM), and 'false' is a keyword
// (DDOC_AUTO_KEYWORD).
/**
* The main thing this program does is nothing, and I do _not want to hear any
* false arguments about that!
*
* Macros:
* DDOC_AUTO_PSYMBOL = $0
* DDOC_AUTO_KEYWORD = $0
* DDOC_AUTO_PARAM = $0
* DDOC_AUTO_PSYMBOL_SUPPRESS = HALPIMBEINGSUPPRESSED $0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

help?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

repressed?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, it was intended as a joke. The misspelling is intentional. It's basically supposed to be any string that's hard to accidentally reproduce or coincide with anything else, that stands out in the output so that we know for certain that the code is working as expected.

*
* DDOC = $(BODY)
Copy link
Member Author

@quickfur quickfur Feb 4, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These overrides are to reduce the scope of the test so that the output HTML does not depend on the styling of the outer elements, that are unrelated to this PR. So that later ddoc PRs won't necessitate updating the test output file unnecessarily.

* DDOC_DECL = $0
* DDOC_MEMBER_HEADER =
* DDOC_MODULE_MEMBERS = $0
* DDOC_MEMBER = $0
*/
void main(string[] arguments)
{
}
16 changes: 16 additions & 0 deletions test/compilable/extra-files/ddoc18361.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@

<span class="ddoc_anchor" id="main"></span>void <code class="code">main</code>(string[] <code class="code">arguments</code>);

<div class="ddoc_decl">
<section class="section ddoc_sections">
<div class="ddoc_summary">
<p class="para">
The main thing this program does is nothing, and I do HALPIMBEINGSUPPRESSED not want to hear any
false arguments about that!

</p>
</div>

</section>

</div>