Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

# -*- coding: utf-8 -*- 

""" 

@file 

@brief Defines a :epkg:`sphinx` extension for a quote. 

""" 

from docutils import nodes 

from docutils.parsers.rst import directives 

 

import sphinx 

from sphinx.locale import _ 

from docutils.parsers.rst.directives.admonitions import BaseAdmonition 

from docutils.statemachine import StringList 

from sphinx.util.nodes import nested_parse_with_titles 

 

 

class quote_node(nodes.admonition): 

""" 

Defines ``quote`` node. 

""" 

pass 

 

 

class QuoteNode(BaseAdmonition): 

""" 

A ``quotedef`` entry, displayed in the form of an admonition. 

It takes the following options: 

 

* *author* 

* *book* 

* *year* 

* *pages* 

* *tag* 

* *source* 

* *lid* or *label* 

* *index*, additional index words beside the title and the author 

* *date*, if the text was written or declared at specific date 

 

Example:: 

 

.. quote:: 

:author: author 

:book: book 

:year: year 

:pages: pages (optional) 

:tag: something 

:lid: id (used for further reference) 

:source: optional 

:index: word 

 

A monkey could... 

""" 

 

node_class = quote_node 

has_content = True 

required_arguments = 0 

optional_arguments = 0 

final_argument_whitespace = False 

option_spec = { 

'author': directives.unchanged, 

'book': directives.unchanged, 

'year': directives.unchanged, 

'pages': directives.unchanged, 

'tag': directives.unchanged, 

'lid': directives.unchanged, 

'label': directives.unchanged, 

'source': directives.unchanged, 

'class': directives.class_option, 

'index': directives.unchanged, 

'date': directives.unchanged, 

} 

 

def run(self): 

""" 

Builds the mathdef text. 

""" 

env = self.state.document.settings.env if hasattr( 

self.state.document.settings, "env") else None 

docname = None if env is None else env.docname 

if docname is not None: 

docname = docname.replace("\\", "/").split("/")[-1] 

 

if not self.options.get('class'): 

self.options['class'] = ['admonition-quote'] 

 

# body 

(quote,) = super(QuoteNode, self).run() 

if isinstance(quote, nodes.system_message): 

return [quote] 

 

# mid 

tag = self.options.get('tag', 'quotetag').strip() 

if len(tag) == 0: 

raise ValueError("tag is empty") 

 

def __(text): 

if text: 

return _(text) 

else: 

return "" 

 

# book 

author = __(self.options.get('author', "").strip()) 

book = __(self.options.get('book', "").strip()) 

pages = __(self.options.get('pages', "").strip()) 

year = __(self.options.get('year', "").strip()) 

source = __(self.options.get('source', "").strip()) 

index = __(self.options.get('index', "").strip()) 

date = __(self.options.get('date', "").strip()) 

 

indexes = [] 

if index: 

indexes.append(index) 

 

# add a label 

lid = self.options.get('lid', self.options.get('label', None)) 

if lid: 

tnl = ['', ".. _{0}:".format(lid), ""] 

else: 

tnl = [] 

 

if author: 

tnl.append("**{0}**, ".format(author)) 

indexes.append(author) 

if book: 

tnl.append("*{0}*".format(book)) 

indexes.append(book) 

if pages: 

tnl.append(", {0}".format(pages)) 

if date: 

tnl.append(" ({0})".format(date)) 

if source: 

if source.startswith("http"): 

tnl.append(", `source <{0}>`_".format(source)) 

else: 

tnl.append(", {0}".format(source)) 

tnl.append('') 

tnl.append(".. index:: " + ", ".join(indexes)) 

tnl.append('') 

 

content = StringList(tnl) 

content = content + self.content 

node = quote_node() 

 

try: 

nested_parse_with_titles(self.state, content, node) 

except Exception as e: 

from sphinx.util import logging 

logger = logging.getLogger("blogpost") 

logger.warning( 

"[blogpost] unable to parse '{0}' - '{1}' - {2}".format(author, book, e)) 

raise e 

 

node['tag'] = tag 

node['author'] = author 

node['pages'] = pages 

node['year'] = year 

node['label'] = lid 

node['source'] = source 

node['book'] = book 

node['index'] = index 

node['content'] = '\n'.join(self.content) 

node['classes'] += ["quote"] 

 

return [node] 

 

 

def visit_quote_node(self, node): 

""" 

visit_quote_node 

""" 

self.visit_admonition(node) 

 

 

def depart_quote_node(self, node): 

""" 

depart_quote_node, 

see https://github.com/sphinx-doc/sphinx/blob/master/sphinx/writers/html.py 

""" 

self.depart_admonition(node) 

 

 

def visit_quote_node_rst(self, node): 

""" 

visit_quote_node 

""" 

self.new_state(0) 

self.add_text(".. quote::") 

for k, v in sorted(node.attributes.items()): 

if k in ("content", 'classes'): 

continue 

if v: 

self.new_state(4) 

self.add_text(":{0}: {1}".format(k, v)) 

self.end_state(wrap=False, end=None) 

self.add_text(self.nl) 

self.new_state(4) 

self.add_text(node['content']) 

self.end_state() 

self.end_state() 

raise nodes.SkipNode 

 

 

def depart_quote_node_rst(self, node): 

""" 

depart_quote_node, 

see https://github.com/sphinx-doc/sphinx/blob/master/sphinx/writers/html.py 

""" 

pass 

 

 

def setup(app): 

""" 

setup for ``mathdef`` (sphinx) 

""" 

if hasattr(app, "add_mapping"): 

app.add_mapping('quote', quote_node) 

 

app.add_node(quote_node, 

html=(visit_quote_node, depart_quote_node), 

epub=(visit_quote_node, depart_quote_node), 

elatex=(visit_quote_node, depart_quote_node), 

latex=(visit_quote_node, depart_quote_node), 

text=(visit_quote_node, depart_quote_node), 

md=(visit_quote_node, depart_quote_node), 

rst=(visit_quote_node_rst, depart_quote_node_rst)) 

 

app.add_directive('quote', QuoteNode) 

return {'version': sphinx.__display_version__, 'parallel_read_safe': True}