Skip to content
Open
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
2 changes: 1 addition & 1 deletion src/directives/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ export function parseDirectiveOptions(
// In docutils all values are simply read as strings,
// but loading with YAML these can be converted to other types, so we convert them back first
// TODO check that it is sufficient to simply do this conversion, or if there is a better way
converted_value = convertor(`${converted_value || ""}`)
converted_value = convertor(`${converted_value ?? ""}`)
} catch (error) {
throw new DirectiveParsingError(
`Invalid option value: (option: '${name}'; value: ${value})\n${error}`
Expand Down
92 changes: 92 additions & 0 deletions tests/listTableHeaderRows.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import MarkdownIt from "markdown-it"
import docutils_plugin from "../src"
import { parseDirectiveOptions } from "../src/directives/main"
import { nonnegative_int, unchanged } from "../src/directives/options"

function render(src: string): string {
return MarkdownIt().use(docutils_plugin).render(src)
}

const listTableBody = `* - A
- B
* - C
- D`

describe("list-table header-rows: 0 is a valid value", () => {
it("YAML option block header-rows: 0 must not throw OptionSpecError / Value is not set", () => {
const html = render(`\`\`\`{list-table}
---
header-rows: 0
---
${listTableBody}
\`\`\``)
expect(html).not.toMatch(/OptionSpecError/)
expect(html).not.toMatch(/Value is not set/)
expect(html).not.toMatch(/directive-error/)
expect(html).toContain("<table>")
expect(html).not.toContain("<thead>")
expect(html).toContain("<tbody>")
expect(html).toContain("<td>A</td>")
})

it("colon form :header-rows: 0 must also accept numeric 0", () => {
const html = render(`\`\`\`{list-table}
:header-rows: 0

${listTableBody}
\`\`\``)
expect(html).not.toMatch(/OptionSpecError/)
expect(html).not.toMatch(/Value is not set/)
expect(html).not.toMatch(/directive-error/)
expect(html).toContain("<table>")
expect(html).not.toContain("<thead>")
expect(html).toContain("<tbody>")
expect(html).toContain("<td>A</td>")
})

it("header-rows: 1 must still work (thead present)", () => {
const html = render(`\`\`\`{list-table}
:header-rows: 1

${listTableBody}
\`\`\``)
expect(html).not.toMatch(/directive-error/)
expect(html).toContain("<thead>")
expect(html).toContain("<th>A</th>")
expect(html).toContain("<tbody>")
expect(html).toContain("<td>C</td>")
})
})

describe("parseDirectiveOptions preserves numeric 0", () => {
const spec = { option_spec: { "header-rows": nonnegative_int } }

it("YAML header-rows: 0 converts to number 0, not empty string", () => {
const [, options] = parseDirectiveOptions(["---", "header-rows: 0", "---"], spec)
expect(options["header-rows"]).toBe(0)
})

it("colon :header-rows: 0 converts to number 0 (yaml.load yields 0)", () => {
const [, options] = parseDirectiveOptions([":header-rows: 0"], spec)
expect(options["header-rows"]).toBe(0)
})

it("header-rows: 1 still converts to number 1", () => {
const [, options] = parseDirectiveOptions([":header-rows: 1"], spec)
expect(options["header-rows"]).toBe(1)
})

it("null option values still become empty string before convertor", () => {
const [, options] = parseDirectiveOptions(["---", "a:", "---"], {
option_spec: { a: unchanged }
})
expect(options.a).toBe("")
})

it("false option values still become empty string before convertor", () => {
const [, options] = parseDirectiveOptions(["---", "a: false", "---"], {
option_spec: { a: unchanged }
})
expect(options.a).toBe("")
})
})