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
67 changes: 65 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,9 @@ Listing: Example listing
becomes

```html
<caption><span>Listing&nbsp;1:</span> Example listing</caption>
<div class="listing" id="_listing-1">
<figcaption><span>Listing&nbsp;1:</span> Example listing</figcaption>
</div>
```

## How?
Expand Down Expand Up @@ -170,7 +172,7 @@ The default values for each type of content is synthesised in the following tabl
|------------------------|---------|---------|-----------|
| `caption_prefix` | "Image" | "Table" | "Listing" |
| `numbering` | False | False | False |
| `content_class` | - | - | - |
| `content_class` | - | - | listing |
| `caption_class` | - | - | - |
| `caption_prefix_class` | - | - | - |
| `caption_top` | False | True | True |
Expand Down Expand Up @@ -224,6 +226,67 @@ figcaption span:first-child {
```
There are further examples in the [wiki](https://github.com/flywire/caption/wiki).

## Compatibility with attr_list extension

*caption* supports preserving `attr_list` extension supplied `id` and `class` attributes by:

* giving priority to markdown defined `id` attributes
* concatenating `class` attributes.

### `image_captions`

This samples shows how to create a captioned image with `id` and `class` through markdown `attr_list` extension.

```markdown
![Alt text](/path/to/image.png "This is the title of the image."){ #title-image .test-class }
```

becomes

```html
<figure id="_figure-1">
<img alt="Alt text" src="/path/to/image.png" id="title-image" class="test-class" />
...
```

### `table_captions`

This samples shows how to create a captioned table with `id` and `class` through markdown `attr_list` extension.

```markdown
Table: Example with heading, two columns and a row
{#example-with-heading .test-class}

| Syntax | Description |
| ----------- | ----------- |
| Header | Title |
```

becomes

```html
<table id="example-with-heading" class="test-class table">
...
```

### `caption`

This samples shows how to create a generic caption with `id` and `class` through markdown `attr_list` extension.


```markdown
Listing: Example listing
{ #example-listing .test-class }
```

becomes

```html
<div class="listing test-class" id="example-listing">
<figcaption><span>Listing&nbsp;1:</span> Example listing</figcaption>
</div>
```

## Customisable

If the settings aren't flexible enough the source code can be changed and
Expand Down
14 changes: 10 additions & 4 deletions caption/caption.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,15 @@ def build_content_element(self, par, caption, replace=True):
par.tag = self.content_tag
for k, v in attrib.items():
par.set(k, v)

if self.content_class:
par.set("class", self.content_class)
par.set("id", "_{}-{}".format(self.name, self.number))
if "class" in attrib:
par.set("class", self.content_class + " " + attrib["class"])
else:
par.set("class", self.content_class)
if "id" not in attrib:
par.set("id", "_{}-{}".format(self.name, self.number))

if replace:
par.text = "\n"
par.tail = "\n"
Expand Down Expand Up @@ -116,7 +122,7 @@ def run(self, root):

class ListingCaptionTreeProcessor(CaptionTreeprocessor):
name = "listing"
content_tag = "div class=listing"
content_tag = "div"

def matches(self, par):
return par.text and par.text.startswith("Listing: ")
Expand All @@ -141,7 +147,7 @@ def __init__(self, **kwargs):
"CSS class to add to the caption prefix <span /> element.",
],
"caption_class": ["", "CSS class to add to the caption element."],
"content_class": ["", "CSS class to add to the content element."],
"content_class": ["listing", "CSS class to add to the content element."],
"link_process": ["", "Some content types support linked processes."],
"caption_top": [False, "Put the caption at the top of the content."],
}
Expand Down
12 changes: 11 additions & 1 deletion caption/table_caption.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
# Copyright (c) 2019 Philipp Trommler
#
# SPDX-License-Identifier: GPL-3.0-or-later
from xml.etree import ElementTree

from markdown import Extension

Expand Down Expand Up @@ -42,6 +41,17 @@ def run(self, root):
title = self.get_title(child)
root.remove(child)
caption = self.build_caption_element(title)

attrib = child.attrib
if "class" in attrib:
if "class" in next_item.attrib:
next_item.set("class", attrib["class"] +
" " + next_item.attrib["class"])
else:
next_item.set("class", attrib["class"])
if "id" in attrib:
next_item.set("id", attrib["id"])

self.build_content_element(next_item, caption, replace=False)
self.add_caption_to_content(next_item, caption)

Expand Down
12 changes: 12 additions & 0 deletions test/test_image_caption.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,3 +248,15 @@ def test_combined_options():
],
)
assert out_string == expected_string


def test_image_attr_list():
in_string = """\
![alt text](/path/to/image.png "Title"){#testid .testal}"""
expected_string = """\
<figure id="_figure-1">
<img alt="alt text" class="testal" id="testid" src="/path/to/image.png" />
<figcaption><span>Figure&nbsp;1:</span> Title</figcaption>
</figure>"""
out_string = markdown.markdown(in_string, extensions=["attr_list", ImageCaptionExtension()])
assert out_string == expected_string
16 changes: 14 additions & 2 deletions test/test_listing_caption.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,20 @@ def test_listing():
in_string = """\
Listing: Simple listing test"""
expected_string = """\
<div class=listing id="_listing-1">
<div class="listing" id="_listing-1">
<figcaption><span>Listing&nbsp;1:</span> Simple listing test</figcaption>
</div class=listing>"""
</div>"""
out_string = markdown.markdown(in_string, extensions=[CaptionExtension()])
assert out_string == expected_string


def test_listing_attr_list():
in_string = """\
Listing: Simple listing test\n\
{#testid .testclass}"""
expected_string = """\
<div class="listing testclass" id="testid">
<figcaption><span>Listing&nbsp;1:</span> Simple listing test</figcaption>
</div>"""
out_string = markdown.markdown(in_string, extensions=["attr_list", CaptionExtension()])
assert out_string == expected_string
31 changes: 31 additions & 0 deletions test/test_table_caption.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,17 @@ def test_no_table():
</tbody>"""


BASE_MD_TABLE_ATTR_LIST = """\
Table: Example with heading, two columns and a row
{#testid .testal}

| Syntax | Description |
| ----------- | ----------- |
| Header | Title |
| Paragraph | Text |
"""


def test_defaults():
expected_string = """\
<table id="_table-1">
Expand Down Expand Up @@ -132,3 +143,23 @@ def test_caption_prefix():
</table>""".format(TABLE_INNER_CONTENT)
out_string = markdown.markdown(BASE_MD_TABLE, extensions=["tables", TableCaptionExtension(caption_prefix="Tabula")])
assert out_string == expected_string


def test_attr_list():
expected_string = """\
<table class="testal" id="testid">
<caption><span>Table&nbsp;1:</span> Example with heading, two columns and a row</caption>
{}
</table>""".format(TABLE_INNER_CONTENT)
out_string = markdown.markdown(BASE_MD_TABLE_ATTR_LIST, extensions=["attr_list", "tables", TableCaptionExtension()])
assert out_string == expected_string


def test_content_class_attr_list():
expected_string = """\
<table class="testclass testal" id="testid">
<caption><span>Table&nbsp;1:</span> Example with heading, two columns and a row</caption>
{}
</table>""".format(TABLE_INNER_CONTENT)
out_string = markdown.markdown(BASE_MD_TABLE_ATTR_LIST, extensions=["attr_list", "tables", TableCaptionExtension(content_class="testclass")])
assert out_string == expected_string