Metadata-Version: 2.1
Name: bootstrap4markdown
Version: 0.1
Summary: A Python-Markdown extension which provides a simple syntax for including Bootstrap objects within a Markdown document.
Author: Waylan Limberg
License: MIT License
        
        Copyright (c) 2023 Waylan Limberg
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
        
Project-URL: repository, https://github.com/waylan/bootstrap4markdown.py
Classifier: Development Status :: 4 - Beta
Classifier: Programming Language :: Python
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: pymdown-extensions (>=9.10)

# Bootstrap4Markdown

A Python-Markdown extension which provides a simple syntax for including
[Bootstrap] objects within a Markdown document.

## Installation

To install the extension, run the following command:

```
pip install bootstrap4markdown
```

## Usage

To use the extension, include its name in the list of extensions passed to
Python-Markdown.

```python
import markdown
markdown.markdown(src, extensions=['bs4md'])
```

Note that this extension only generates the requisite HTML for the supported
Bootstrap components. The user is responsible for providing the necessary CSS
and Javascript for the Bootstrap theme being used. The generated HTML assumes
Bootstrap version 5.3.

## Syntax

Bootstrap4Markdown is built on top of the [Blocks] extension. Therefore, all
blocks use the same basic form.

```
/// name-of-block | argument
    option: value

content
///
```

Therefore, each supported Bootstrap object maps to a specific block name as
defined below.

### Alerts

Bootstrap based [alerts] can be defined using blocks named `alert`.

```
/// alert
This is an alert.
///
```

A title (or heading) can be defined using the block's argument.

```
/// alert | Title
This alert has a title.
///
```

The color of the alert can be altered using the `type` option. For example,
setting `type: warning` will result in the `alert-warning` style being used
from your Bootstrap theme.

```
/// alert | Warning
    type: warning

This is a **warning** alert with a title.
///
```

Valid types are the string names of any of Bootstraps contextual classes:
`primary`, `secondary`, `success`, `danger`, `warning`, `info`, `light`, and
`dark`.

Notice that the body content body of the alert contains standard Markdown
content. By default the content will be parsed as a single block (paragraph)
and only inline level Markdown parsing will be applied to the content. However,
if the `markdown` option is set to `block`, then block-level parsing will be
applied to the content as well.

```
/// alert
    markdown: block

This alert contains two paragraphs of Markdown text.

This is the second paragraph.
///
```

An alert will include a dismiss button if `dismissable` is set to `true`.

```
/// alert
    dismissable: true

You can dismiss me!
///
```

Finally, any additional HTML attributes can be defined for the outer element of
the alert using the `attrs` option.

```
/// alert
    attrs:
        id: mycustomid
        class: p-5

Custom padding is set for this alert using on of Bootstraps'
[spacing](https://getbootstrap.com/docs/5.3/utilities/spacing/)
classes. (`p-5`).
///
```

#### Options

Option        | Type            | Description             | Default
------------- | --------------- | ----------------------- | -------
`type`        | string          | A string which matches one of Bootstrap's contextual classes. | `primary`
`dismissable` | boolean         | Enable or disable a dismiss button. | `false`
`markdown`    | string          | Indicate whether body content should be parsed as `block` or `inline` content. | `inline`
`attrs`       | key:value pairs | Define custom HTML attributes for the wrapping element. | `{}`

### Carousel

A Bootstrap based [carousel] (or slideshow) can be defined using two types of
blocks: the outer `carousel` block and a separate `slide` block for each
component of the slideshow.

```
//// carousel

/// slide | image1.jpg
    alt: Slide one.
///

/// slide | image2.jpg
    alt: Slide two.
///

////
```

Note that all `slide` blocks must be nested in a `carousel` block. Also, be sure
to use a different number of slashes for the parent `carousel` block than the
child `slide` blocks.

#### Carousel Block

The outer `carousel` block is used to define global options which apply to the
entire slideshow.

```
//// carousel
    attrs: {id: 'mycustomid'}
    controls: false
    indicators: true
    fade: true
    autoplay: carousel
    touch: false

...
////
```

Option        | Type     | Description                    | Default
------------- | ---------| ------------------------------ | -------
`controls`    | boolean  | Display previous/next buttons. | `true`
`indicators`  | boolean  | Display indicators to jump to a specific slide. | `false`
`fade`        | boolean  | Enable a crossfade transition between slides. | `false`
`autoplay`    | boolean or string | Enable autoplay. Set to `carousel` to autoplay on page load or `true` to autoplay after first interaction. | `false`
`attrs`       | key:value pairs | Define custom HTML attributes for the wrapping carousel element. | `{}`

Note that Boostrap requires each carousel to have a unique `id` defined for
it to work correctly. If one is not defined in the `attrs`, then a random [UUID]
string will be generated and assigned as the `id` of the carousel.

#### Slide Block

Nested within the `carousel` block, each slide is defined by a `slide` block.
Slides may take one of a few forms. The simplest form is an image.

```
///
slide | path/to/image.jpg
    alt: Some alt text for the image.
///
```

Note that the path to the image is defined in the argument and the alt text in
the `alt` option.

Image slides can also define a caption, which is text that overlays the image.
The caption is defined in the body of the image.

```
///
slide | path/to/image.jpg
    alt: Some alt text for the image.

# Caption Title

Caption Body.
///
```

However, if no argument is provided, then the body content is used as the body
of the slide. In both cases, Markdown processing is applied to the body content.

```
/// slide
    attrs: {class: 'text-center pt-5 bg-primary-subtle text-primary-emphasis min-vh-100'}

# HTML Slide

Slide Body
///
```

Note that various Bootstrap classes were set on the above slide. As Bootstrap's
documentation explains:

> Carousels don’t automatically normalize slide dimensions. As such, you may
> need to use additional utilities or custom styles to appropriately size
> content.

Of course, raw HTML can be used as well. For example, the following slide
includes a slide comprised of an SVG element.

```
/// slide
    markdown: inline

<svg class="d-block w-100" width="800" height="400" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Placeholder" preserveAspectRatio="xMidYMid slice" focusable="false">
<title>Placeholder</title>
<rect width="100%" height="100%" fill="#777"></rect>
<text x="50%" y="50%" fill="#555" dy=".3em">SVG Slide</text>
</svg>
///
```

In the above slide, the `markdown` option was set to `inline` so that the `svg`
would not be wrapped in a Markdown paragraph. However, when using block-level
raw HTML, you will want to indent the content one level (4 spaces) and set the
`markdown` option to `raw` to ensure that Markdown parsing does not muck up
your custom crafted HTML.

```
/// slide
    markdown: raw

    <h4>Title</h4>
    <p>Custom Body Content</p>
///
```

Option        | Type     | Description                    | Default
------------- | ---------| ------------------------------ | -------
`alt`         | string   | Alt text for an image slide. Ignored for none-image slides. | `''`
`active`      | boolean  | Set this slide to be the active slide. | `false`
`interval`    | integer or `null` | Number of seconds to display slide when autoplaying. Set to `null` to use Bootstrap's default. | `null`
`markdown`    | string | Indicate whether body or caption content should be parsed as `block`,  `inline`, or `raw` content. | `block`.
`attrs`       | key:value pairs | Define custom HTML attributes for the slide element. | `{}`

Note that if more that one slide is set to  `active: true`, then only the first
of all "active" slides is actually set to active. If no slides are explicitly
set to be active, then the first slide in the carousel is set to be active by
default.

## License

The Bootstrap4Markdown Extension to Python-Markdown is licensed under the
[MIT License] as defined in `LICENSE`.

## Change Log

### Version 0.1 (2023-03-07)

The initial release. Includes support for Alerts and Carousels.

[Bootstrap]: https://getbootstrap.com/
[Blocks]: https://facelessuser.github.io/pymdown-extensions/extensions/blocks/
[alerts]: https://getbootstrap.com/docs/5.3/components/alerts/
[carousel]: https://getbootstrap.com/docs/5.3/components/carousel/
[UUID]: https://en.wikipedia.org/wiki/Universally_unique_identifier
[MIT License]: https://opensource.org/license/mit/
