
# Coverage

This file is just a collection of tests designed to activate code in MD4C
which may otherwise be hard to hit. It's to improve our test coverage.


## `md_is_unicode_whitespace__()`

Unicode whitespace (here U+2000) forms a word boundary so these cannot be
resolved as emphasis span because there is no closer mark.

```````````````````````````````` example
*foo *bar
.
<p>*foo *bar</p>
````````````````````````````````


## `md_is_unicode_punct__()`

Ditto for Unicode punctuation (here U+00A1).

```````````````````````````````` example
*foo¡*bar
.
<p>*foo¡*bar</p>
````````````````````````````````


## `md_get_unicode_fold_info()`

```````````````````````````````` example
[Příliš žluťoučký kůň úpěl ďábelské ódy.]

[PŘÍLIŠ ŽLUŤOUČKÝ KŮŇ ÚPĚL ĎÁBELSKÉ ÓDY.]: /url
.
<p><a href="/url">Příliš žluťoučký kůň úpěl ďábelské ódy.</a></p>
````````````````````````````````


## `md_decode_utf8__()` and `md_decode_utf8_before__()`

### Alphanumerical Character (i.e. not whitespace, not punctuation)

Non-whitespace & non-punctuation characters below suppress `_` from being
recognized as an emphasis because `_` should be seen as in-word character:

Example of 1-byte UTF-8 sequence (U+0058):
```````````````````````````````` example
X__foo__X
.
<p>X__foo__X</p>
````````````````````````````````

Example of 2-byte UTF-8 sequence (U+0158):
```````````````````````````````` example
Ř__foo__Ř
.
<p>Ř__foo__Ř</p>
````````````````````````````````

Example of 3-byte UTF-8 sequence (U+0BA3):
```````````````````````````````` example
ண__foo__ண
.
<p>ண__foo__ண</p>
````````````````````````````````

Example of 4-byte UTF-8 sequence (U+13142):
```````````````````````````````` example
𓅂__foo__𓅂
.
<p>𓅂__foo__𓅂</p>
````````````````````````````````

### Whitespace character

Whitespace on the other hand should not suppress `_`:

Example of 1-byte UTF-8 sequence (U+0009):
```````````````````````````````` example
x→__foo__→
.
<p>x <strong>foo</strong></p>
````````````````````````````````
(The initial `x` to suppress indented code block.)

Example of 2-byte UTF-8 sequence (U+00A0):
```````````````````````````````` example
 __foo__
.
<p> <strong>foo</strong> </p>
````````````````````````````````

Example of 3-byte UTF-8 sequence (U+2000):
```````````````````````````````` example
 __foo__
.
<p> <strong>foo</strong> </p>
````````````````````````````````

(AFAIK, there is no 4-byte UTF-8 whitespace.)

### Punctuation character

Punctuation also should not suppress `_`:

Example of 1-byte UTF-8 sequence (U+002E):
```````````````````````````````` example
.__foo__.
.
<p>.<strong>foo</strong>.</p>
````````````````````````````````

Example of 2-byte UTF-8 sequence (U+00B7):
```````````````````````````````` example
·__foo__·
.
<p>·<strong>foo</strong>·</p>
````````````````````````````````

Example of 3-byte UTF-8 sequence (U+0C84):
```````````````````````````````` example
಄__foo__಄
.
<p>಄<strong>foo</strong>಄</p>
````````````````````````````````

Example of 4-byte UTF-8 sequence (U+1039F):
```````````````````````````````` example
𐎟__foo__𐎟
.
<p>𐎟<strong>foo</strong>𐎟</p>
````````````````````````````````


## `md_is_link_destination_A()`

```````````````````````````````` example
[link](</url\.with\.escape>)
.
<p><a href="/url.with.escape">link</a></p>
````````````````````````````````


## `md_link_label_eq()`

```````````````````````````````` example
[foo bar]

[foo bar]: /url
.
<p><a href="/url">foo bar</a></p>
````````````````````````````````


## `md_is_inline_link_spec()`

```````````````````````````````` example
> [link](/url 'foo
> bar')
.
<blockquote>
<p><a href="/url" title="foo
bar">link</a></p>
</blockquote>
````````````````````````````````


## `md_build_ref_def_hashtable()`

All link labels in the following example all have the same FNV1a hash (after
normalization of the label, which means after converting to a vector of Unicode
codepoints and lowercase folding).

So the example triggers quite complex code paths which are not otherwise easily
tested.

```````````````````````````````` example
[foo]: /foo
[qnptgbh]: /qnptgbh
[abgbrwcv]: /abgbrwcv
[abgbrwcv]: /abgbrwcv2
[abgbrwcv]: /abgbrwcv3
[abgbrwcv]: /abgbrwcv4
[alqadfgn]: /alqadfgn

[foo]
[qnptgbh]
[abgbrwcv]
[alqadfgn]
[axgydtdu]
.
<p><a href="/foo">foo</a>
<a href="/qnptgbh">qnptgbh</a>
<a href="/abgbrwcv">abgbrwcv</a>
<a href="/alqadfgn">alqadfgn</a>
[axgydtdu]</p>
````````````````````````````````

For the sake of completeness, the following C program was used to find the hash
collisions by brute force:

~~~

#include <stdio.h>
#include <string.h>


static unsigned etalon;



#define MD_FNV1A_BASE       2166136261
#define MD_FNV1A_PRIME      16777619

static inline unsigned
fnv1a(unsigned base, const void* data, size_t n)
{
    const unsigned char* buf = (const unsigned char*) data;
    unsigned hash = base;
    size_t i;

    for(i = 0; i < n; i++) {
        hash ^= buf[i];
        hash *= MD_FNV1A_PRIME;
    }

    return hash;
}


static unsigned
unicode_hash(const char* data, size_t n)
{
    unsigned value;
    unsigned hash = MD_FNV1A_BASE;
    int i;

    for(i = 0; i < n; i++) {
        value = data[i];
        hash = fnv1a(hash, &value, sizeof(unsigned));
    }

    return hash;
}


static void
recurse(char* buffer, size_t off, size_t len)
{
    int ch;

    if(off < len - 1) {
        for(ch = 'a'; ch <= 'z'; ch++) {
            buffer[off] = ch;
            recurse(buffer, off+1, len);
        }
    } else {
        for(ch = 'a'; ch <= 'z'; ch++) {
            buffer[off] = ch;
            if(unicode_hash(buffer, len) == etalon) {
                printf("Dup: %.*s\n", (int)len, buffer);
            }
        }
    }
}

int
main(int argc, char** argv)
{
    char buffer[32];
    int len;

    if(argc < 2)
        etalon = unicode_hash("foo", 3);
    else
        etalon = unicode_hash(argv[1], strlen(argv[1]));

    for(len = 1; len <= sizeof(buffer); len++)
        recurse(buffer, 0, len);

    return 0;
}
~~~


## Flag `MD_FLAG_COLLAPSEWHITESPACE`

```````````````````````````````` example
foo  bar → baz
.
<p>foo bar baz</p>
.
--fcollapse-whitespace
````````````````````````````````


## Flag `MD_FLAG_PRESERVEBLANKLINES`

A closing code fence is internally retyped as a blank line but still holds its
text, so it must not be counted as a blank line separation.

```````````````````````````````` example
```
foo
```
bar
.
<pre><code>foo
</code></pre>
<p>bar</p>
.
--fpreserve-blank-lines
````````````````````````````````

A blank line ending an HTML block is a genuine blank line and is reported.

```````````````````````````````` example
<div>
x


after
.
<div>
x
<br>
<p>after</p>
.
--fpreserve-blank-lines
````````````````````````````````

Blank lines attach to the innermost container open where they occur. Blank
lines between two list items are reported inside the preceding item (which also
makes the list loose):

```````````````````````````````` example
* a


* b
.
<ul>
<li><p>a</p>
<br>
</li>
<li><p>b</p>
</li>
</ul>
.
--fpreserve-blank-lines
````````````````````````````````

Consistently, blank lines trailing the last item (before a following paragraph
that ends the list) are reported inside that last item:

```````````````````````````````` example
* a
* b


para
.
<ul>
<li>a</li>
<li>b<br>
</li>
</ul>
<p>para</p>
.
--fpreserve-blank-lines
````````````````````````````````

Blank lines nested several containers deep attach to the innermost open
container (here the inner list item inside the block quote):

```````````````````````````````` example
> * a
>
>
> * b
.
<blockquote>
<ul>
<li><p>a</p>
<br>
</li>
<li><p>b</p>
</li>
</ul>
</blockquote>
.
--fpreserve-blank-lines
````````````````````````````````

Blank lines are split on a container boundary honouring proper nesting: a run
of blank lines that continues the block quote (with the `>` mark) is reported
inside it, while a following run of blank lines that no longer continues it is
reported at the outer level:

```````````````````````````````` example
> quote with trailing blank lines inside of it.
>
>


after the block quote.
.
<blockquote>
<p>quote with trailing blank lines inside of it.</p>
<br>
</blockquote>
<br>
<p>after the block quote.</p>
.
--fpreserve-blank-lines
````````````````````````````````

A line consisting only of spaces or tabs is a blank line and is counted (the
second and third lines below contain three spaces each):

```````````````````````````````` example
foo
   
   
bar
.
<p>foo</p>
<br>
<p>bar</p>
.
--fpreserve-blank-lines
````````````````````````````````

Blank lines neighbouring an ATX heading and a thematic break are reported:

```````````````````````````````` example
para


# H


---


end
.
<p>para</p>
<br>
<h1>H</h1>
<br>
<hr>
<br>
<p>end</p>
.
--fpreserve-blank-lines
````````````````````````````````
