From fdc2c6c706bcace07e60b470467decfbb27e5410 Mon Sep 17 00:00:00 2001 From: Andrei Alexandrescu Date: Mon, 21 Dec 2015 21:45:53 -0500 Subject: [PATCH 1/5] Ddoc: insert whenever encountering two newlines or more in the source text. --- src/doc.d | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/src/doc.d b/src/doc.d index d827a8cbe382..f31281a688d4 100644 --- a/src/doc.d +++ b/src/doc.d @@ -444,6 +444,7 @@ DDOC_PARAM_ROW = $(TR $0) DDOC_PARAM_ID = $(TD $0) DDOC_PARAM_DESC = $(TD $0) DDOC_BLANKLINE = $(BR)$(BR) +DDOC_PARAGRAPH_SEPARATOR = DDOC_ANCHOR = DDOC_PSYMBOL = $(U $0) @@ -2133,7 +2134,7 @@ extern (C++) void highlightText(Scope* sc, Dsymbols* a, OutBuffer* buf, size_t o { Dsymbol s = a.dim ? (*a)[0] : null; // test //printf("highlightText()\n"); - int leadingBlank = 1; + bool leadingBlank = true; int inCode = 0; int inBacktick = 0; //int inComment = 0; // in comment @@ -2168,8 +2169,36 @@ extern (C++) void highlightText(Scope* sc, Dsymbols* a, OutBuffer* buf, size_t o static __gshared const(char)* blankline = "$(DDOC_BLANKLINE)\n"; i = buf.insert(i, blankline, strlen(blankline)); } - leadingBlank = 1; iLineStart = i + 1; + if (!leadingBlank) + { + leadingBlank = true; + } + else + { + // Group two or more newlines into a paragraph break + auto scout = iLineStart; + for (; scout < buf.offset; ++scout) + { + c = buf.data[scout]; + if (c == ' ' || c == '\t') + { + continue; + } + if (c == '\n') + { + iLineStart = scout + 1; + continue; + } + // We got to a non-whitespace, time to insert the paragraph + // break. + i = iLineStart - 1; + static __gshared const(char)* ps = + "$(DDOC_PARAGRAPH_SEPARATOR)"; + i = buf.insert(i, ps, strlen(ps)); + break; + } + } break; case '<': { From 46fa5ae74981f06ce7b869c56f98bdeaca965e3f Mon Sep 17 00:00:00 2001 From: Andrei Alexandrescu Date: Tue, 22 Dec 2015 11:08:46 -0500 Subject: [PATCH 2/5] Fix a couple of errors --- src/doc.d | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/doc.d b/src/doc.d index f31281a688d4..7c408b8e764d 100644 --- a/src/doc.d +++ b/src/doc.d @@ -2174,7 +2174,7 @@ extern (C++) void highlightText(Scope* sc, Dsymbols* a, OutBuffer* buf, size_t o { leadingBlank = true; } - else + else if (!inCode) { // Group two or more newlines into a paragraph break auto scout = iLineStart; @@ -2192,10 +2192,9 @@ extern (C++) void highlightText(Scope* sc, Dsymbols* a, OutBuffer* buf, size_t o } // We got to a non-whitespace, time to insert the paragraph // break. - i = iLineStart - 1; - static __gshared const(char)* ps = + static __gshared immutable ps = "$(DDOC_PARAGRAPH_SEPARATOR)"; - i = buf.insert(i, ps, strlen(ps)); + i = buf.insert(iLineStart, ps.ptr, ps.length) - 1; break; } } From 00583d0621515099c3889e7e55aee9063cb26da0 Mon Sep 17 00:00:00 2001 From: Andrei Alexandrescu Date: Tue, 22 Dec 2015 11:26:28 -0500 Subject: [PATCH 3/5] @adamruppe review --- src/doc.d | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/doc.d b/src/doc.d index 7c408b8e764d..161a5d2693ea 100644 --- a/src/doc.d +++ b/src/doc.d @@ -2192,8 +2192,7 @@ extern (C++) void highlightText(Scope* sc, Dsymbols* a, OutBuffer* buf, size_t o } // We got to a non-whitespace, time to insert the paragraph // break. - static __gshared immutable ps = - "$(DDOC_PARAGRAPH_SEPARATOR)"; + immutable ps = "$(DDOC_PARAGRAPH_SEPARATOR)"; i = buf.insert(iLineStart, ps.ptr, ps.length) - 1; break; } From a6207f88856173de516ccafe92e1be2de36324a5 Mon Sep 17 00:00:00 2001 From: "Adam D. Ruppe" Date: Tue, 22 Dec 2015 19:47:39 -0500 Subject: [PATCH 4/5] fix Andrei's code to keep the existing DDOC_BLANKLINEs --- src/doc.d | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/doc.d b/src/doc.d index 161a5d2693ea..3807fb6a5082 100644 --- a/src/doc.d +++ b/src/doc.d @@ -2137,6 +2137,7 @@ extern (C++) void highlightText(Scope* sc, Dsymbols* a, OutBuffer* buf, size_t o bool leadingBlank = true; int inCode = 0; int inBacktick = 0; + int blankLineRun = 0; //int inComment = 0; // in comment size_t iCodeStart = 0; // start of code section size_t codeIndent = 0; @@ -2168,6 +2169,7 @@ extern (C++) void highlightText(Scope* sc, Dsymbols* a, OutBuffer* buf, size_t o { static __gshared const(char)* blankline = "$(DDOC_BLANKLINE)\n"; i = buf.insert(i, blankline, strlen(blankline)); + blankLineRun++; } iLineStart = i + 1; if (!leadingBlank) @@ -2422,6 +2424,18 @@ extern (C++) void highlightText(Scope* sc, Dsymbols* a, OutBuffer* buf, size_t o leadingBlank = 0; if (sc._module.isDocFile || inCode) break; + + + if(blankLineRun) { + // We got to a non-whitespace in a run of blank lines, time + // to insert the paragraph break to group two or more newlines + // into a paragraph separator + immutable ps = "$(DDOC_PARAGRAPH_SEPARATOR)"; + i = buf.insert(i, ps.ptr, ps.length) - 1; + } + + blankLineRun = 0; + char* start = cast(char*)buf.data + i; if (isIdStart(start)) { From 33bcb400d97adca81f3c7399761d08e9a5658038 Mon Sep 17 00:00:00 2001 From: Andrei Alexandrescu Date: Fri, 8 Jan 2016 11:16:45 -0500 Subject: [PATCH 5/5] Redo DDOC_PARAGRAPH_SEPARATOR to fix its issues --- src/doc.d | 219 ++++++++++++++++++++++++++---------------------------- 1 file changed, 105 insertions(+), 114 deletions(-) diff --git a/src/doc.d b/src/doc.d index 3807fb6a5082..d8586492378e 100644 --- a/src/doc.d +++ b/src/doc.d @@ -2135,10 +2135,9 @@ extern (C++) void highlightText(Scope* sc, Dsymbols* a, OutBuffer* buf, size_t o Dsymbol s = a.dim ? (*a)[0] : null; // test //printf("highlightText()\n"); bool leadingBlank = true; - int inCode = 0; - int inBacktick = 0; - int blankLineRun = 0; - //int inComment = 0; // in comment + bool inCode = 0; + bool inBacktick = 0; + uint blankLineRun = 0; size_t iCodeStart = 0; // start of code section size_t codeIndent = 0; size_t iLineStart = offset; @@ -2167,36 +2166,37 @@ extern (C++) void highlightText(Scope* sc, Dsymbols* a, OutBuffer* buf, size_t o } if (!sc._module.isDocFile && !inCode && i == iLineStart && i + 1 < buf.offset) // if "\n\n" { - static __gshared const(char)* blankline = "$(DDOC_BLANKLINE)\n"; - i = buf.insert(i, blankline, strlen(blankline)); - blankLineRun++; + static immutable blankline = "$(DDOC_BLANKLINE)\n"; + i = buf.insert(i, blankline.ptr, blankline.length); } iLineStart = i + 1; - if (!leadingBlank) + leadingBlank = true; + if (inCode) { - leadingBlank = true; + // Once a section of code is active, blank line runs are reset + blankLineRun = 0; } - else if (!inCode) + else { // Group two or more newlines into a paragraph break - auto scout = iLineStart; - for (; scout < buf.offset; ++scout) + if (i + 1 >= buf.offset) break; // end of file, uninteresting + // Look ahead to see if the run is continuing + switch (c = buf.data[i + 1]) { - c = buf.data[scout]; - if (c == ' ' || c == '\t') - { - continue; - } - if (c == '\n') - { - iLineStart = scout + 1; - continue; - } - // We got to a non-whitespace, time to insert the paragraph - // break. - immutable ps = "$(DDOC_PARAGRAPH_SEPARATOR)"; - i = buf.insert(iLineStart, ps.ptr, ps.length) - 1; - break; + case ' ', '\t', '\r': + break; + case '\n': + blankLineRun++; + break; + default: + // End of a run! + if (blankLineRun == 0) break; // just one newline + // Time to insert the paragraph break. + static immutable ps = "$(DDOC_PARAGRAPH_SEPARATOR)"; + i = buf.insert(i, ps.ptr, ps.length); + // Reset the counter for the next run + blankLineRun = 0; + break; } } break; @@ -2330,94 +2330,96 @@ extern (C++) void highlightText(Scope* sc, Dsymbols* a, OutBuffer* buf, size_t o /* A line beginning with --- delimits a code section. * inCode tells us if it is start or end of a code section. */ - if (leadingBlank) + if (!leadingBlank) { - size_t istart = i; - size_t eollen = 0; - leadingBlank = 0; - while (1) + // No special meaning uness '-' is the first non-ws in a line + break; + } + size_t istart = i; + size_t eollen = 0; + leadingBlank = 0; + while (1) + { + ++i; + if (i >= buf.offset) + break; + c = buf.data[i]; + if (c == '\n') { - ++i; - if (i >= buf.offset) + eollen = 1; + break; + } + if (c == '\r') + { + eollen = 1; + if (i + 1 >= buf.offset) break; - c = buf.data[i]; - if (c == '\n') + if (buf.data[i + 1] == '\n') { - eollen = 1; + eollen = 2; break; } - if (c == '\r') - { - eollen = 1; - if (i + 1 >= buf.offset) - break; - if (buf.data[i + 1] == '\n') - { - eollen = 2; - break; - } - } - // BUG: handle UTF PS and LS too - if (c != '-') - goto Lcont; } - if (i - istart < 3) + // BUG: handle UTF PS and LS too + if (c != '-') goto Lcont; - // We have the start/end of a code section - // Remove the entire --- line, including blanks and \n - buf.remove(iLineStart, i - iLineStart + eollen); - i = iLineStart; - if (inCode && (i <= iCodeStart)) - { - // Empty code section, just remove it completely. - inCode = 0; - break; - } - if (inCode) + } + if (i - istart < 3) + goto Lcont; + // We have the start/end of a code section + // Remove the entire --- line, including blanks and \n + buf.remove(iLineStart, i - iLineStart + eollen); + i = iLineStart; + if (inCode && (i <= iCodeStart)) + { + // Empty code section, just remove it completely. + inCode = 0; + break; + } + if (inCode) + { + inCode = 0; + // The code section is from iCodeStart to i + OutBuffer codebuf; + codebuf.write(buf.data + iCodeStart, i - iCodeStart); + codebuf.writeByte(0); + // Remove leading indentations from all lines + bool lineStart = true; + char* endp = cast(char*)codebuf.data + codebuf.offset; + for (char* p = cast(char*)codebuf.data; p < endp;) { - inCode = 0; - // The code section is from iCodeStart to i - OutBuffer codebuf; - codebuf.write(buf.data + iCodeStart, i - iCodeStart); - codebuf.writeByte(0); - // Remove leading indentations from all lines - bool lineStart = true; - char* endp = cast(char*)codebuf.data + codebuf.offset; - for (char* p = cast(char*)codebuf.data; p < endp;) + if (lineStart) { - if (lineStart) - { - size_t j = codeIndent; - char* q = p; - while (j-- > 0 && q < endp && isIndentWS(q)) - ++q; - codebuf.remove(p - cast(char*)codebuf.data, q - p); - assert(cast(char*)codebuf.data <= p); - assert(p < cast(char*)codebuf.data + codebuf.offset); - lineStart = false; - endp = cast(char*)codebuf.data + codebuf.offset; // update - continue; - } - if (*p == '\n') - lineStart = true; - ++p; + size_t j = codeIndent; + char* q = p; + while (j-- > 0 && q < endp && isIndentWS(q)) + ++q; + codebuf.remove(p - cast(char*)codebuf.data, q - p); + assert(cast(char*)codebuf.data <= p); + assert(p < cast(char*)codebuf.data + codebuf.offset); + lineStart = false; + endp = cast(char*)codebuf.data + codebuf.offset; // update + continue; } - highlightCode2(sc, a, &codebuf, 0); - buf.remove(iCodeStart, i - iCodeStart); - i = buf.insert(iCodeStart, codebuf.data, codebuf.offset); - i = buf.insert(i, cast(const(char)*)")\n", 2); - i -= 2; // in next loop, c should be '\n' - } - else - { - static __gshared const(char)* d_code = "$(D_CODE "; - inCode = 1; - codeIndent = istart - iLineStart; // save indent count - i = buf.insert(i, d_code, strlen(d_code)); - iCodeStart = i; - i--; // place i on > - leadingBlank = true; + if (*p == '\n') + lineStart = true; + ++p; } + highlightCode2(sc, a, &codebuf, 0); + buf.remove(iCodeStart, i - iCodeStart); + i = buf.insert(iCodeStart, codebuf.data, codebuf.offset); + i = buf.insert(i, cast(const(char)*)")\n", 2); + i -= 2; // in next loop, c should be '\n' + } + else + { + static __gshared const(char)* d_code = "$(D_CODE "; + inCode = 1; + codeIndent = istart - iLineStart; // save indent count + i = buf.insert(i, d_code, strlen(d_code)); + iCodeStart = i; + i--; // place i on > + leadingBlank = true; } break; default: @@ -2425,17 +2427,6 @@ extern (C++) void highlightText(Scope* sc, Dsymbols* a, OutBuffer* buf, size_t o if (sc._module.isDocFile || inCode) break; - - if(blankLineRun) { - // We got to a non-whitespace in a run of blank lines, time - // to insert the paragraph break to group two or more newlines - // into a paragraph separator - immutable ps = "$(DDOC_PARAGRAPH_SEPARATOR)"; - i = buf.insert(i, ps.ptr, ps.length) - 1; - } - - blankLineRun = 0; - char* start = cast(char*)buf.data + i; if (isIdStart(start)) {