[libvirt] [PATCH v2 2/3] NEWS: Reformat at generation time

Andrea Bolognani abologna at redhat.com
Thu Jan 5 14:34:36 UTC 2017


Instead of encoding formatting information inside the
corresponding XSLT stylesheet, use a Python script to reformat
the text appropriately based on a few simple markers.

Splitting the task between the XSLT stylesheet and the Python
script allows us to keep both parts very simple.
---
Changes from v1:

  * Address review comments
    - Avoid breaking 'make syntax-check'

 Makefile.am           |  17 +++++---
 docs/Makefile.am      |   2 +-
 docs/reformat-news.py | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 124 insertions(+), 7 deletions(-)
 create mode 100755 docs/reformat-news.py

diff --git a/Makefile.am b/Makefile.am
index 5c813b2..f30976f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -47,12 +47,17 @@ pkgconfigdir = $(libdir)/pkgconfig
 pkgconfig_DATA = libvirt.pc libvirt-qemu.pc libvirt-lxc.pc libvirt-admin.pc
 
 NEWS: $(srcdir)/docs/news.xml $(srcdir)/docs/news-ascii.xsl
-	$(AM_V_GEN)if [ -x $(XSLTPROC) ] ; then			\
-	  $(XSLTPROC) --nonet $(srcdir)/docs/news-ascii.xsl	\
-	     $(srcdir)/docs/news.xml				\
-	   | perl -0777 -pe 's/\n\n+$$/\n/'			\
-	   | perl -pe 's/[ \t]+$$//'				\
-	   > $@-t && mv $@-t $@ ; fi
+	$(AM_V_GEN) \
+	if [ -x $(XSLTPROC) ]; then \
+	  $(XSLTPROC) --nonet \
+	    $(srcdir)/docs/news-ascii.xsl \
+	    $(srcdir)/docs/news.xml \
+	  >$@-tmp \
+	    || { rm -f $@-tmp; exit 1; }; \
+	  $(srcdir)/docs/reformat-news.py $@-tmp >$@ \
+	    || { rm -f $@-tmp; exit 1; }; \
+	  rm -f $@-tmp; \
+	fi
 
 $(top_srcdir)/HACKING: $(top_srcdir)/docs/hacking1.xsl \
 			$(top_srcdir)/docs/hacking2.xsl \
diff --git a/docs/Makefile.am b/docs/Makefile.am
index 8b34048..8d2e2b0 100644
--- a/docs/Makefile.am
+++ b/docs/Makefile.am
@@ -156,7 +156,7 @@ schemadir = $(pkgdatadir)/schemas
 schema_DATA = $(wildcard $(srcdir)/schemas/*.rng)
 
 EXTRA_DIST=					\
-  apibuild.py genaclperms.pl \
+  apibuild.py reformat-news.py genaclperms.pl \
   site.xsl subsite.xsl newapi.xsl news-ascii.xsl news-html.xsl page.xsl \
   hacking1.xsl hacking2.xsl wrapstring.xsl \
   $(dot_html) $(dot_html_in) $(gif) $(apihtml) $(apipng) \
diff --git a/docs/reformat-news.py b/docs/reformat-news.py
new file mode 100755
index 0000000..e536205
--- /dev/null
+++ b/docs/reformat-news.py
@@ -0,0 +1,112 @@
+#!/usr/bin/env python
+
+# reformat-news.py: Reformat the NEWS file properly
+#
+# Copyright (C) 2017 Red Hat, Inc.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library.  If not, see
+# <http://www.gnu.org/licenses/>.
+#
+# Authors:
+#     Andrea Bolognani <abologna at redhat.com>
+
+import sys
+
+COLUMNS = 80
+
+def reformat_with_indent(text, initial_indent, indent):
+
+    res = ""
+    line = initial_indent
+
+    for word in text.split():
+
+        # If adding one more word (plus a whitespace, plus a newline)
+        # to the current line would push us over the desired number
+        # of columns we start a new line instead
+        if len(line) + len(word) > (COLUMNS - 2):
+            res = res + line + "\n"
+            line = indent
+
+        # We need to take care when we've just started a  new line,
+        # as we don't want to add any additional leading whitespace
+        # in that case
+        if line == indent or line == initial_indent:
+            line = line + word
+        else:
+            line = line + " " + word
+
+    # Append whatever's left
+    res = res + line + "\n"
+
+    return res
+
+
+def reformat(line):
+
+    # Empty lines don't need to be reformatted or even inspected
+    if len(line) == 0:
+        return "\n"
+
+    # For all non-empty lines, we decide the indentation level based
+    # on the first character
+    marker = line[0]
+
+    # Heading or release
+    if marker == '=' or marker == '#':
+        initial_indent = 0
+        indent = 2
+    # Section
+    elif marker == '*':
+        initial_indent = 2
+        indent = 4
+    # Change summary
+    elif marker == '-':
+        initial_indent = 4
+        indent = 6
+    # Change description
+    else:
+        initial_indent = 8
+        indent = 8
+
+    return reformat_with_indent(line, " " * initial_indent, " " * indent)
+
+
+def main(args):
+
+    if len(args) < 2:
+        sys.stdout.write("Usage: " + args[0] + " FILE\n")
+        sys.exit(1)
+
+    with open(args[1], 'r') as f:
+
+        process = False
+
+        for line in f:
+
+            # Odd occurrences of this specific marker cause the processing
+            # to start, even occurrences causes it to stop. In practice,
+            # this allows us to have some pre-formatted text at the
+            # beginning and end of the file
+            if line[0] == '=':
+                process = not process
+
+            if not process:
+                sys.stdout.write(line)
+            else:
+                sys.stdout.write(reformat(line.strip()))
+
+
+if __name__ == "__main__":
+    main(sys.argv)
-- 
2.7.4




More information about the libvir-list mailing list