or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

configuration.mdcore-setup.mddirectives-nodes.mdheader-buttons.mdindex.mdpage-enhancement.mdtransforms.md

directives-nodes.mddocs/

0

# Directives and Custom Nodes

1

2

Custom reStructuredText directives and docutils nodes for enhanced content presentation. Provides margin notes and sidenote functionality for book-style layouts.

3

4

## Capabilities

5

6

### Margin Directive

7

8

A custom reStructuredText directive for creating content that appears in the page margin.

9

10

```python { .api }

11

class Margin(Sidebar):

12

"""

13

Directive for content that appears in the right margin of the page.

14

15

Inherits from docutils Sidebar directive with custom styling.

16

"""

17

18

optional_arguments: int = 1 # Optional title argument

19

required_arguments: int = 0 # No required arguments

20

21

def run(self) -> list:

22

"""

23

Process the directive and return docutils nodes.

24

25

Returns:

26

List of docutils nodes with 'margin' CSS class applied

27

"""

28

```

29

30

### SideNote Node

31

32

A custom docutils node for rendering side notes and margin notes in HTML output.

33

34

```python { .api }

35

class SideNoteNode(nodes.Element):

36

"""

37

Custom docutils node for side/margin note content in HTML output.

38

39

Generates required HTML structure for both desktop and mobile

40

presentation of marginal content.

41

"""

42

43

def __init__(self, rawsource="", *children, **attributes):

44

"""

45

Initialize the SideNoteNode.

46

47

Parameters:

48

- rawsource: Raw source text (optional)

49

- children: Child nodes

50

- attributes: Node attributes

51

"""

52

53

@classmethod

54

def add_node(cls, app: Sphinx) -> None:

55

"""

56

Register the node with a Sphinx application.

57

58

Parameters:

59

- app: Sphinx application instance

60

"""

61

```

62

63

### Node Visitor Functions

64

65

HTML rendering functions for the SideNoteNode.

66

67

```python { .api }

68

def visit_SideNoteNode(self, node):

69

"""

70

HTML visitor function called when entering a SideNoteNode.

71

72

Generates opening HTML tags based on node type:

73

- For marginnotes: Creates marginnote-label class

74

- For sidenotes: Creates label with span wrapper

75

76

Parameters:

77

- self: HTML writer instance

78

- node: SideNoteNode being processed with 'names' attribute

79

"""

80

81

def depart_SideNoteNode(self, node):

82

"""

83

HTML visitor function called when leaving a SideNoteNode.

84

85

Generates closing HTML tags and interactive checkbox input:

86

- Closes span tags for sidenotes

87

- Adds checkbox input for toggle behavior

88

- Uses node names for element IDs

89

90

Parameters:

91

- self: HTML writer instance

92

- node: SideNoteNode being processed with 'names' attribute

93

"""

94

```

95

96

## Usage Examples

97

98

### Using the Margin Directive

99

100

In reStructuredText content:

101

102

```rst

103

Regular paragraph content here.

104

105

.. margin:: Optional Title

106

107

This content will appear in the right margin alongside the

108

regular content. It's perfect for side notes, additional

109

information, or commentary.

110

111

More regular content continues here.

112

```

113

114

### Creating SideNote Nodes Programmatically

115

116

```python

117

from sphinx_book_theme.nodes import SideNoteNode

118

from docutils import nodes

119

120

# Create a sidenote node

121

sidenote = SideNoteNode()

122

sidenote.attributes["names"] = ["sidenote-role-1"]

123

124

# Add content to the sidenote

125

content = nodes.inline()

126

content.attributes["classes"] = ["sidenote"]

127

content += nodes.Text("This is a side note.")

128

129

sidenote.append(content)

130

```

131

132

### Registering SideNote Node with Sphinx

133

134

```python

135

from sphinx.application import Sphinx

136

from sphinx_book_theme.nodes import SideNoteNode

137

138

# In a Sphinx extension setup function

139

def setup(app: Sphinx):

140

# Register the custom node

141

SideNoteNode.add_node(app)

142

143

return {"parallel_read_safe": True}

144

```

145

146

### Margin Directive in Extensions

147

148

```python

149

from sphinx.application import Sphinx

150

from sphinx_book_theme.directives import Margin

151

152

# Register the directive

153

def setup(app: Sphinx):

154

app.add_directive("margin", Margin)

155

156

return {"parallel_read_safe": True}

157

```

158

159

## HTML Output Examples

160

161

### Sidenote HTML Structure

162

163

```html

164

<label for='sidenote-role-1' class='margin-toggle'>

165

<span>Sidenote content with number</span>

166

</label>

167

<input type='checkbox' id='sidenote-role-1' name='sidenote-role-1' class='margin-toggle'>

168

```

169

170

### Marginnote HTML Structure

171

172

```html

173

<label for='marginnote-role-1' class='margin-toggle marginnote-label'>

174

</label>

175

<input type='checkbox' id='marginnote-role-1' name='marginnote-role-1' class='margin-toggle'>

176

```