From ed296fc007b9ff33d0ac236050eb58360a31977d Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Wed, 23 Aug 2017 10:03:14 +0100 Subject: [PATCH] Monkey patch the blockdiag extension The blockdiag extension currently provides poor support for word wrapping. While a PR has been filed, the project appears to be dormant and it's likely going to be a while (if ever) before it gets merged. As such, it's easier to carry our own, monkey patched version of the plugin. Change-Id: Iac2f8cadc688334e07ad46c5af1870b568c56e73 Co-Authored-By: Eric Fried --- doc/source/conf.py | 55 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/doc/source/conf.py b/doc/source/conf.py index d2c9666a99bc..96bce69365ce 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -163,3 +163,58 @@ latex_documents = [ ('index', 'Nova.tex', u'Nova Documentation', u'OpenStack Foundation', 'manual'), ] + +# -- Custom extensions -------------------------------------------------------- + + +def monkey_patch_blockdiag(): + """Monkey patch the blockdiag library. + + The default word wrapping in blockdiag is poor, and breaks on a fixed + text width rather than on word boundaries. There's a patch submitted to + resolve this [1]_ but it's unlikely to merge anytime soon. + + TODO: Remove this once blockdiag is bumped to 1.6, which will hopefully + include the fix. + + .. [1] https://bitbucket.org/blockdiag/blockdiag/pull-requests/16/ + """ + from blockdiag.imagedraw import textfolder + + def splitlabel(text): + """Split text to lines as generator. + + Every line will be stripped. If text includes characters "\n\n", treat + as line separator. Ignore '\n' to allow line wrapping. + """ + lines = [x.strip() for x in text.splitlines()] + out = [] + + for line in lines: + if line: + out.append(line) + else: + yield ' '.join(out) + out = [] + + yield ' '.join(out) + + def splittext(metrics, text, bound, measure='width'): + folded = [' '] + for word in text.split(): + # Try appending the word to the last line + tryline = ' '.join([folded[-1], word]).strip() + textsize = metrics.textsize(tryline) + if getattr(textsize, measure) > bound: + # Start a new line. Appends `word` even if > bound. + folded.append(word) + else: + folded[-1] = tryline + return folded + + # monkey patch those babies + textfolder.splitlabel = splitlabel + textfolder.splittext = splittext + + +monkey_patch_blockdiag()