# Scribble: How to wrap a subsection in a custom \`div\` element?

**URL:** <https://racket.discourse.group/t/scribble-how-to-wrap-a-subsection-in-a-custom-div-element/1340>\
**Category:** Questions & Answers\
**Tags:** question, scribble, html\
**Created:** [September 30, 2022, 2:13pm UTC](https://racket.discourse.group/t/scribble-how-to-wrap-a-subsection-in-a-custom-div-element/1340 "2022-09-30T14:13:11Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![sschwarzer](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/sschwarzer/32/1940_2.png) [@sschwarzer](https://racket.discourse.group/u/sschwarzer)\
**Post date:** [September 30, 2022, 2:13pm UTC](https://racket.discourse.group/t/scribble-how-to-wrap-a-subsection-in-a-custom-div-element/1340/1 "2022-09-30T14:13:11Z")

</div>

I'm trying to write a function that wraps a subsection, i.e. the `subsection` _and_ the content belonging to the subsection, in a `div` element with a custom class.

The function without the `div` wrapping currently looks like this:

```scheme
@(define (glossary-entry2 #:cross-reference? [cross-reference? #f]
                          #:stub? [stub? #f]
                          title-text
                          level
                          . text)
   (list
     (subsection #:style 'unnumbered title-text)
     (paragraph empty-style (elem (bold "Level: ") (symbol->string level)))
     text))

```

and is used like this:

```nohighlight
@glossary-entry2["Arity" 'basic]{

The arity describes how many arguments a function can accept. Everything from
zero to infinitely many arguments is possible. Note that functions can have
optional arguments, so even for a specific function, the arity may not be a
single number.

Arity refers only to positional arguments, not keyword arguments.

See also:
@itemize[
  @item{@secref*["Procedure" 'glossary] @in-g}
  @item{@secref*["Keywords_and_Arity" 'reference] @in-rr}]
}

```

The workaround with `elem`, which I described [here](https://racket.discourse.group/t/adding-html-attributes-to-scribble-subsubsection/1296/3), doesn't work since `elem` can't contain arbitrary content, e.g. a `part` or `itemization`. (I get a corresponding contract violation.)

[This thread](https://racket.discourse.group/t/scribble-pre-rendered-html/1216) may be related to my question, but it "doesn't work" because I couldn't find out where `sxml->element` is defined.

* * *

_Context:_ I want this for the implementation of [this ticket](https://todo.sr.ht/~sschwarzer/racket-glossary/1). Depending on the checked boxes, some JavaScript code could go over the `div`s for the glossary entries and make them visible or invisible.

---

<div class="post-metadata">

**Author:** ![soegaard](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/soegaard/32/19_2.png) [@soegaard](https://racket.discourse.group/u/soegaard)\
**Post date:** [September 30, 2022, 3:21pm UTC](https://racket.discourse.group/t/scribble-how-to-wrap-a-subsection-in-a-custom-div-element/1340/2 "2022-09-30T15:21:00Z")

</div>

I am wondering whether the "General Sibling Combinator" CSS selector could be used instead?

> **[General sibling combinator - CSS: Cascading Style Sheets | MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/General_sibling_combinator)**
>
> The general sibling combinator (~) separates two selectors and matches all iterations of the second element, that are following the first element (though not necessarily immediately), and are children of the same parent element.

If the subsection is given a specific class, say, "entry" then `.entry ~ div` can be used to select siblings.

---

<div class="post-metadata">

**Author:** ![sschwarzer](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/sschwarzer/32/1940_2.png) [@sschwarzer](https://racket.discourse.group/u/sschwarzer)\
**Post date:** [September 30, 2022, 4:03pm UTC](https://racket.discourse.group/t/scribble-how-to-wrap-a-subsection-in-a-custom-div-element/1340/3 "2022-09-30T16:03:07Z")

</div>

> [@soegaard](#):
>
> I am wondering whether the "General Sibling Combinator" CSS selector could be used instead?

Interesting, I didn't know about this selector. 🙂

That said, as I understand the linked CSS documentation, this would usually select too much. For example, if I have

```html
<h4 class="basic">Title 1</h4>

<p>foo</p>

<h4 class="intermediate">Title 2</h4>

<p>bar</p>

<h4 class="basic">Title 3</h4>

<p>baz</p>

```

`h4.basic ~ p` would select _all_ sibling `p`s after the first `h4.basic`, which would include the `h4.intermediate`.

Actually, if the whole content of each subsection was wrapped in a `div`, the selector would work, since the documentation says "[...] and are children of the same parent element." But this again would require the `div` I asked for. 😉

---

<div class="post-metadata">

**Author:** ![sschwarzer](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/sschwarzer/32/1940_2.png) [@sschwarzer](https://racket.discourse.group/u/sschwarzer)\
**Post date:** [October 2, 2022, 3:33pm UTC](https://racket.discourse.group/t/scribble-how-to-wrap-a-subsection-in-a-custom-div-element/1340/4 "2022-10-02T15:33:42Z")

</div>

Meanwhile I tried two other approaches:

- Wrapping the content in a [nested-flow](https://docs.racket-lang.org/scribble/core.html#%28def._%28%28lib._scribble%2Fcore..rkt%29._nested-flow%29%29) caused a contract violation because a nested flow can't contain a `part` (implied by the `subsection`).
- The [xexpr-property](https://docs.racket-lang.org/scribble/core.html#%28def._%28%28lib._scribble%2Fhtml-properties..rkt%29._xexpr-property%29%29) style property, as part of an `elem`, passed through the HTML I specified, but it put it _inside_ the `p` tags from the `element`, so it generated invalid HTML like `<p><div class="intermediate"></p>`.

I can think of other workarounds that _might_ work "somehow", but I have no idea how to apply them (again, if it's even possible):

- Capture the generated HTML string and post-process it before it's written. For example, the Scribble document could include some distinct text like `[div intermediate]`, which would later be replaced by `<div class="intermediate">`. However, I have no idea how to capture and post-process the HTML as part of `raco setup`.
- After the HTML file has been generated, post-process it with some custom code. However, I have no idea how to plug this into [raco setup](https://docs.racket-lang.org/raco/setup-info.html).

Maybe someone else has advice along these lines?

@mflatt @samth :

What I'd _actually_ like to have in Scribble:

- A way to wrap some content inside given HTML tags (specified as a style). Essentially, this would be like `elem` or `nested-flow`, but with the constraint of forbidding `part`s and other contents removed; and
- A way to insert literal HTML in a document, similar to `xexpr-property`, but without insisting of enclosing tags (like `p` in the above description). This approach could be generalized for multiple formats/renderers, e.g. LaTeX or Markdown.

For my specific use case, either of these approaches would work, but I think both would be useful. If I had decide on one, it would be the second since it's more general. However, depending on how the Scribble document is written, this might create invalid HTML because it may not be clear which particular HTML code Scribble generates. So the first approach would probably be safer if it could be used.

---

<div class="post-metadata">

**Author:** ![mflatt](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/mflatt/32/6_2.png) [@mflatt](https://racket.discourse.group/u/mflatt)\
**Post date:** [October 6, 2022, 3:35am UTC](https://racket.discourse.group/t/scribble-how-to-wrap-a-subsection-in-a-custom-div-element/1340/5 "2022-10-06T03:35:21Z")

</div>

I don't think you've overlooked any way to do this at the Scribble level, right now.

If we were to add something, I imagine it would take the form of a style property for a `part`. (The `subsection` and similar functions accept style properties that get propagated to a `part`). The HTML renderer would look for the style property in `render-part-content` and add a `div` layer around the list that it currently returns.

One caveat is that a part may have subparts that are rendered on separate HTML pages. I imagine that this `div` layer would wrap only things that are rendered on the same page as the part title. There's plenty of precedent for a style property that behaves specific to HTML pages, though.

---

<div class="post-metadata">

**Author:** ![sschwarzer](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/sschwarzer/32/1940_2.png) [@sschwarzer](https://racket.discourse.group/u/sschwarzer)\
**Post date:** [October 6, 2022, 12:06pm UTC](https://racket.discourse.group/t/scribble-how-to-wrap-a-subsection-in-a-custom-div-element/1340/6 "2022-10-06T12:06:22Z")

</div>

> [@mflatt](#):
>
> If we were to add something, I imagine it would take the form of a style property for a `part`. (The `subsection` and similar functions accept style properties that get propagated to a `part`). The HTML renderer would look for the style property in `render-part-content` and add a `div` layer around the list that it currently returns.

As I understand this, the style properties of a (e.g.) `subsection` would be added to the `div`? I think it would be good to be able to specify separate style properties for the `div` and the `h*` tags (for example, for specifying a `class` for the `div` and removing the top border for the `h*`).

That said, if I had to choose _one_ approach (adding the style properties to `div` vs. the `h*`), I'd prefer the style properties to be added to the `div` because then I'd still be able to style the `h*`s with an additional CSS file with

```css
div.my_class h4 { ... }

```

while still being able to specify style properties for the `div` as a whole.
