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

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

320

321

322

323

324

325

326

327

328

329

330

331

332

333

334

335

336

337

338

339

340

341

342

343

344

345

346

347

348

349

350

351

352

353

354

355

356

357

358

359

360

361

362

363

364

365

366

367

368

369

370

371

372

373

374

375

376

377

378

379

380

381

382

383

384

385

386

387

388

389

390

391

392

393

394

395

396

397

398

399

400

401

402

403

404

405

406

407

408

409

410

411

# -*- coding: UTF-8 -*- 

"""Just a copy & paste of the :mod:`docutils.examples` module (as 

instructed there). 

 

:func:`restify` is an alias for :func:`html_body`. 

 

:func:`latex_body` deduced from :func:`html_body`. 

 

""" 

from __future__ import print_function 

 

#~ import traceback 

from docutils import core, io, nodes, utils 

 

 

# Copied from doctest: 

import re 

# This regular expression finds the indentation of every non-blank 

# line in a string. 

_INDENT_RE = re.compile('^([ ]*)(?=\S)', re.MULTILINE) 

 

 

def min_indent(s): 

    "Return the minimum indentation of any non-blank line in `s`" 

    indents = [len(indent) for indent in _INDENT_RE.findall(s)] 

    if len(indents) > 0: 

        return min(indents) 

    else: 

        return 0 

 

 

def doc2rst(s): 

    if s is None: 

        return u'' 

    s = s.expandtabs() 

    # If all lines begin with the same indentation, then strip it. 

    mi = min_indent(s) 

    if mi > 0: 

        s = '\n'.join([l[mi:] for l in s.split('\n')]) 

    return s 

 

 

def abstract(o, indent=0): 

    s = doc2rst(o.__doc__).strip() 

    if not s: 

        return '(no docstring)' 

    paras = s.split('\n\n', 1) 

    par = paras[0] 

    if indent: 

        par = (' ' * indent).join(par.splitlines()) 

    return par 

 

 

#~ from docutils.parsers.rst import roles 

#~ def doc_role(typ, rawtext, text, lineno, inliner, 

             #~ options={}, content=[]): 

    #~ node = nodes.reference(rawtext, reftype=role, refdomain=domain, 

                                 #~ refexplicit=has_explicit_title) 

    #~ return [node], [] 

#~ roles.register_local_role('doc', docrole) 

def html_parts(input_string, source_path=None, destination_path=None, 

               input_encoding='unicode', doctitle=1, initial_header_level=1): 

    """ 

    Given an input string, returns a dictionary of HTML document parts. 

 

    Dictionary keys are the names of parts, and values are Unicode strings; 

    encoding is up to the client. 

 

    Parameters: 

 

    - `input_string`: A multi-line text string; required. 

    - `source_path`: Path to the source file or object.  Optional, but useful 

      for diagnostic output (system messages). 

    - `destination_path`: Path to the file or object which will receive the 

      output; optional.  Used for determining relative paths (stylesheets, 

      source links, etc.). 

    - `input_encoding`: The encoding of `input_string`.  If it is an encoded 

      8-bit string, provide the correct encoding.  If it is a Unicode string, 

      use "unicode", the default. 

    - `doctitle`: Disable the promotion of a lone top-level section title to 

      document title (and subsequent section title to document subtitle 

      promotion); enabled by default. 

    - `initial_header_level`: The initial level for header elements (e.g. 1 

      for "<h1>"). 

    """ 

    overrides = {'input_encoding': input_encoding, 

                 'doctitle_xform': doctitle, 

                 'initial_header_level': initial_header_level} 

    parts = core.publish_parts( 

        source=input_string, source_path=source_path, 

        destination_path=destination_path, 

        writer_name='html', settings_overrides=overrides) 

    return parts 

 

 

def html_body(input_string, source_path=None, destination_path=None, 

              input_encoding='unicode', output_encoding='unicode', 

              doctitle=1, initial_header_level=1): 

    """ 

    Given an input string, returns an HTML fragment as a string. 

 

    The return value is the contents of the <body> element. 

 

    Parameters (see :func:`html_parts` for the remainder): 

 

    - `output_encoding`: The desired encoding of the output.  If a Unicode 

      string is desired, use the default value of "unicode" . 

    """ 

    parts = html_parts( 

        input_string=input_string, source_path=source_path, 

        destination_path=destination_path, 

        input_encoding=input_encoding, doctitle=doctitle, 

        initial_header_level=initial_header_level) 

    fragment = parts['html_body'] 

    if output_encoding != 'unicode': 

        fragment = fragment.encode(output_encoding) 

    #~ print __file__, repr(fragment) 

    return fragment 

 

 

from docutils import writers 

from docutils.writers import html4css1 

 

 

class HTMLTranslator(html4css1.HTMLTranslator): 

 

    """ 

    Suppress surrounding DIV tag. Used by :func:`restify`. 

    """ 

    #~ def visit_document(self, node): 

        #~ self.head.append('<title>%s</title>\n' 

                         #~ % self.encode(node.get('title', ''))) 

 

    def depart_document(self, node): 

        self.fragment.extend(self.body) 

        # I just removed the following two lines: 

        #~ self.body_prefix.append(self.starttag(node, 'div', CLASS='document')) 

        #~ self.body_suffix.insert(0, '</div>\n') 

        # skip content-type meta tag with interpolated charset value: 

        self.html_head.extend(self.head[1:]) 

        # was only useful to understand what's happening: 

        #~ print self.body_prefix 

        #~ print self.body_suffix 

        #~ raise Exception("foo") 

        self.html_body.extend(self.body_prefix[1:] + self.body_pre_docinfo 

                              + self.docinfo + self.body 

                              + self.body_suffix[:-1]) 

        assert not self.context, 'len(context) = %s' % len(self.context) 

 

 

class Writer(html4css1.Writer): 

 

    def __init__(self): 

        writers.Writer.__init__(self) 

        self.translator_class = HTMLTranslator 

 

 

# simply importing the sphinx.roles module causes these text roles to 

# be installed: 

 

import sphinx.roles 

 

from docutils.parsers.rst import roles 

 

try: 

    from sphinx.util.nodes import split_explicit_title 

except ImportError:  # sphinx 0.6.6 didn't have this 

    import re 

    explicit_title_re = re.compile(r'^(.+?)\s*(?<!\x00)<(.*?)>$', re.DOTALL) 

 

    def split_explicit_title(text): 

        """Split role content into title and target, if given.""" 

        match = explicit_title_re.match(text) 

        if match: 

            return True, match.group(1), match.group(2) 

        return False, text, text 

 

 

def install_sphinx_emu(): 

    """ 

    install some roles to emulate sphinx. 

    """ 

    def mod_role(role, rawtext, text, lineno, inliner, options={}, content=[]): 

        has_explicit_title, title, target = split_explicit_title(text) 

        ref = 'http://not_implemented/' + target 

        return [nodes.reference(rawtext, utils.unescape(title), refuri=ref, 

                                **options)], [] 

    roles.register_local_role('mod', mod_role) 

 

    def class_role(role, rawtext, text, lineno, inliner, options={}, content=[]): 

        has_explicit_title, title, target = split_explicit_title(text) 

        ref = 'http://not_implemented/' + target 

        return [nodes.reference(rawtext, utils.unescape(title), refuri=ref, 

                                **options)], [] 

    roles.register_local_role('class', class_role) 

 

    def srcref_role(role, rawtext, text, lineno, inliner, options={}, content=[]): 

        has_explicit_title, title, target = split_explicit_title(text) 

        ref = 'http://not_implemented/' + target 

        return [nodes.reference(rawtext, utils.unescape(title), refuri=ref, 

                                **options)], [] 

    roles.register_local_role('srcref', srcref_role) 

 

#~ import sphinx 

#~ print sphinx.__file__ 

 

 

def restify(input_string, source_path=None, destination_path=None, 

            input_encoding='unicode', doctitle=1, initial_header_level=1): 

    u""" 

    Renders the given reST string into a unicode HTML chunk without 

    any surrounding tags like ``<HTML>``, ``<BODY>``, and especially 

    ``<DIV class="document">`` (this last one requires the above 

    :class:`HTMLTranslator` subclass,  thanks to `Günter Milde's hint 

    <http://sourceforge.net/mailarchive/message.php?msg_id=27467363>`_ 

    and `example code 

    <http://docutils.sourceforge.net/sandbox/html4strict/html4strict.py>`_). 

    """ 

    overrides = {'input_encoding': input_encoding, 

                 'doctitle_xform': doctitle, 

                 'initial_header_level': initial_header_level} 

    parts = core.publish_parts( 

        source=input_string, source_path=source_path, 

        destination_path=destination_path, 

        writer=Writer(), 

        settings_overrides=overrides) 

    fragment = parts['html_body'] 

    #~ if output_encoding != 'unicode': 

        #~ fragment = fragment.encode(output_encoding) 

    #~ print __file__, repr(fragment) 

    return fragment 

 

 

def rst2odt(input_string, source_path=None, destination_path=None, 

            input_encoding='unicode', doctitle=1, initial_header_level=1): 

    """ 

    Renders the given reST string into ODT xml. 

    """ 

    from docutils.writers.odf_odt import Writer, Reader 

 

    class MyWriter(Writer): 

 

        def assemble_my_parts(self): 

            writers.Writer.assemble_parts(self) 

            self.parts['content'] = self.visitor.content_astext() 

            #~ f = tempfile.NamedTemporaryFile() 

            #~ zfile = zipfile.ZipFile(f, 'w', zipfile.ZIP_DEFLATED) 

            #~ content = self.visitor.content_astext() 

            #~ self.write_zip_str(zfile, 'content.xml', content) 

            #~ self.write_zip_str(zfile, 'mimetype', self.MIME_TYPE) 

            #~ s1 = self.create_manifest() 

            #~ self.write_zip_str(zfile, 'META-INF/manifest.xml', s1) 

            #~ s1 = self.create_meta() 

            #~ self.write_zip_str(zfile, 'meta.xml', s1) 

            #~ s1 = self.get_stylesheet() 

            #~ self.write_zip_str(zfile, 'styles.xml', s1) 

            #~ s1 = self.get_settings() 

            #~ self.write_zip_str(zfile, 'settings.xml', s1) 

            #~ self.store_embedded_files(zfile) 

            #~ zfile.close() 

            #~ f.seek(0) 

            #~ whole = f.read() 

            #~ f.close() 

            #~ self.parts['whole'] = whole 

            #~ self.parts['encoding'] = self.document.settings.output_encoding 

            #~ self.parts['version'] = docutils.__version__ 

 

    overrides = {'input_encoding': input_encoding, 

                 'doctitle_xform': doctitle, 

                 'initial_header_level': initial_header_level} 

    parts = core.publish_parts( 

        source=input_string, source_path=source_path, 

        destination_path=destination_path, 

        writer=MyWriter(), 

        reader=Reader(), 

        settings_overrides=overrides) 

    print(20120311, list(parts.keys())) 

    print(20120311, parts['content']) 

    raise Exception("20120311") 

    fragment = parts['whole'] 

    fragment = parts['html_body'] 

    #~ if output_encoding != 'unicode': 

        #~ fragment = fragment.encode(output_encoding) 

    #~ print __file__, repr(fragment) 

    return fragment 

 

 

def old_restify(s, **kw): 

    """ 

    (Didn't work when the reST text contained a root title). 

    See :blogref:`20110525`. 

    """ 

    html = html_body(s, **kw) 

    if html.startswith('<div class="document">\n') and html.endswith('</div>\n'): 

        return html[23:-7] 

    raise Exception("Error: restify() got unexpected HTML: %r" % html) 

 

 

def latex_parts(input_string, source_path=None, destination_path=None, 

                input_encoding='unicode', doctitle=1, initial_header_level=1): 

    overrides = {'input_encoding': input_encoding, 

                 'doctitle_xform': doctitle, 

                 'initial_header_level': initial_header_level} 

    parts = core.publish_parts( 

        source=input_string, source_path=source_path, 

        destination_path=destination_path, 

        #~ writer_name='latex2e', 

        writer_name='newlatex2e', 

        settings_overrides=overrides) 

    return parts 

 

 

def latex_body(input_string, source_path=None, destination_path=None, 

               input_encoding='unicode', output_encoding='unicode', 

               doctitle=1, initial_header_level=1): 

    parts = latex_parts( 

        input_string=input_string, source_path=source_path, 

        destination_path=destination_path, 

        input_encoding=input_encoding, doctitle=doctitle, 

        initial_header_level=initial_header_level) 

    #~ print parts.keys() 

    fragment = parts['body'] 

    if output_encoding != 'unicode': 

        fragment = fragment.encode(output_encoding) 

    return fragment 

 

 

def rst2latex(input_string, 

              source_path=None, 

              input_encoding='unicode', 

              doctitle=1, 

              initial_header_level=1): 

    """ 

    returns a dict containing the following keys: 

 

      'body', 

      'latex_preamble', 

      'head_prefix', 

      'requirements', 

      'encoding', 

      'abstract', 

      'title', 

      'fallbacks', 

      'stylesheet', 

      'version', 

      'body_pre_docinfo', 

      'dedication', 

      'subtitle', 

      'whole', 

      'docinfo', 

      'pdfsetup' 

 

    """ 

    overrides = {'input_encoding': input_encoding, 

                 'doctitle_xform': doctitle, 

                 'initial_header_level': initial_header_level} 

    #~ doc = core.publish_doctree(source=input_string, 

                #~ source_path=source_path, 

                #~ 'input_encoding': input_encoding) 

 

    parts = core.publish_parts(source=input_string, 

                               source_path=source_path, 

                               #~ writer_name='latex2e', 

                               writer_name='latex2e', 

                               settings_overrides=overrides) 

    return parts 

    #~ print parts.keys() 

    #~ f = file('tmp.txt','w') 

    #~ f.write(repr(parts.keys())+'\n\n') 

    #~ f.write(repr(parts)) 

    #~ f.close() 

    #~ return parts['body'] 

 

 

if __name__ == '__main__': 

    test = u""" 

Test example 

============ 

 

This is a reST__ document containg non-ascii latin-1 chars:: 

 

  Ä Ë Ï Ö Ü 

  ä ë ï ö ü ÿ 

  à è ì ò ù 

  á é í ó ú 

  ã õ ñ 

  ç ß 

 

__ http://docutils.sf.net/rst.html 

 

A list: 

 

  - item 1 

  - item 2 

  - item 3 

   

A table: 

 

  =========== =========================== 

  terav       pehme 

  =========== =========================== 

  **s**\ upp  **z**\ oom 

  **š**\ okk  **ž**\ urnaal, **ž**\ anre 

  =========== =========================== 

 

 

 

""" 

    print(rst2odt(test)) 

    #~ print restify(test) 

    #~ print latex_body(test)