From ebf5ae2e5caf1e843c313328f43c9e8c6fda0081 Mon Sep 17 00:00:00 2001
Message-Id: <ebf5ae2e5caf1e843c313328f43c9e8c6fda0081.1719037253.git.mdw@distorted.org.uk>
From: Mark Wooding <mdw@chiark.greenend.org.uk>
Date: Sat, 2 Jan 2016 15:37:03 +0000
Subject: [PATCH] doc/sod.sty, doc/*.tex: New notation for line control in
 `prog'.
Organization: Straylight/Edgeware

From: Mark Wooding <mdw@distorted.org.uk>

By default, breaks are no longer allowed between lines in a `prog'
environment.  `\\+' introduces some vertical whitespace and allows a
break.  `\\-' introduces a little space, but doesn't allow a break.
---
 doc/concepts.tex   | 31 +++++++++++-----------
 doc/sod.sty        | 23 ++++++++++++++---
 doc/structures.tex |  4 +--
 doc/tutorial.tex   | 64 +++++++++++++++++++++++-----------------------
 4 files changed, 70 insertions(+), 52 deletions(-)

diff --git a/doc/concepts.tex b/doc/concepts.tex
index 51cca98..20402dc 100644
--- a/doc/concepts.tex
+++ b/doc/concepts.tex
@@ -371,21 +371,22 @@ do this for you.
 
 The following simple mixin class is suggested.
 \begin{prog}
-  [nick = disposable] \\*
-  class DisposableObject : SodObject \{ \\*[\jot] \ind
-    void release() \{ ; \} \\*
-    \quad /\=\+* Release resources held by the receiver. */ \-\- \\*[\jot]
-  \} \\[\bigskipamount]
-  code c : user \{ \\* \ind
-    /\=\+* Free object p's instance storage.  If p is a DisposableObject \\*
-       {}* then release its resources beforehand. \\*
-       {}*/ \- \\*
-    void free_instance(void *p) \\*
-    \{ \\* \ind
-      DisposableObject *d = SOD_CONVERT(DisposableObject, p); \\*
-      if (d) DisposableObject_release(d); \\*
-      free(d); \- \\*
-    \} \- \\*
+  [nick = disposable] \\
+  class DisposableObject : SodObject \{ \\- \ind
+    void release() \{ ; \} \\
+    \quad /* Release resources held by the receiver. */ \- \\-
+  \}
+  \\+
+  code c : user \{ \\- \ind
+    /\=\+* Free object p's instance storage.  If p is a DisposableObject \\
+       {}* then release its resources beforehand. \\
+       {}*/ \- \\
+    void free_instance(void *p) \\
+    \{ \\ \ind
+      DisposableObject *d = SOD_CONVERT(DisposableObject, p); \\
+      if (d) DisposableObject_release(d); \\
+      free(d); \- \\
+    \} \- \\
   \}
 \end{prog}
 
diff --git a/doc/sod.sty b/doc/sod.sty
index 28b6ccc..ed39c24 100644
--- a/doc/sod.sty
+++ b/doc/sod.sty
@@ -124,9 +124,27 @@
 %% Environment for setting programs.  Newlines are explicit, because
 %% otherwise I need comments in weird places to make the vertical spacing
 %% come out properly.  You can write `\obeylines' if you really want to.
-\def\prog{\codeface\quote\tabbing}
+\def\prog{\let\prog@@cr\@tabcr\let\@tabcr\@progcr\codeface\quote\tabbing}
 \def\endprog{\endtabbing\endquote}
 \def\ind{\quad\=\+\kill}
+\def\@progcr{\futurelet\@tempa\@progcr@i}
+{\def\:{\gdef\@progcr@sp}\: {\@progcr}}
+\def\@progcr@i{%
+  \ifx\@tempa\@sptoken\let\next@\@progcr@sp\else
+  \if1\ifx\@tempa[1\else
+      \ifx\@tempa*1\else
+      0\fi\fi
+    \let\next@\prog@@cr\else
+  \if1\ifx\@tempa+1\else
+      \ifx\@tempa-1\else
+      0\fi\fi
+    \let\next@\@progcr@ii\else
+  \let\next@\@progcr@a\fi\fi\fi
+  \next@}
+\def\@progcr@a{\prog@@cr*{}\ignorespaces}
+\def\@progcr@ii#1{\csname @progcr@#1\endcsname\ignorespaces}
+\@namedef{@progcr@+}{\prog@@cr[\medskipamount]}
+\@namedef{@progcr@-}{\prog@@cr*[\jot]}
 
 %% Put a chunk of text in a box.
 \newenvironment{boxy}[1][\q@]{%
@@ -207,10 +225,9 @@
   \if@nobreak\else\par\goodbreak\fi%
   \global\@dheadfirsttrue%
   \begingroup%
-    \codeface%
     \let\@endparenv\relax%
     \clubpenalty\@M \widowpenalty\@M \interlinepenalty50%
-    \tabbing#1\endtabbing%
+    \@prog#1\endtabbing%
   \endgroup%
   \penalty\@M\@afterheading%
   \list{}{\rightmargin\z@\topsep\z@}\item%
diff --git a/doc/structures.tex b/doc/structures.tex
index d379c99..2fcbb2e 100644
--- a/doc/structures.tex
+++ b/doc/structures.tex
@@ -307,7 +307,7 @@ type @|struct $C$__ilayout|.
     union $B$__ichainu_$i$ $i$; \\
     \quad$\vdots$ \- \\
   \};
-  \\[\bigskipamount]
+  \\+
   typedef struct $C$__ichain_$h$ $C$;
 \end{prog}
 
@@ -412,7 +412,7 @@ structure.
       \quad$\vdots$ \- \\
     \} $c$; \- \\
   \};
-  \\[\bigskipamount]
+  \\+
   extern const union $C$__vtu_$h$ $C$__vtable_$h$;
 \end{prog}
 
diff --git a/doc/tutorial.tex b/doc/tutorial.tex
index bb357d8..f313e0e 100644
--- a/doc/tutorial.tex
+++ b/doc/tutorial.tex
@@ -96,8 +96,8 @@ The main consequences of this are as follows.
 Of course, this means that your build system needs to become more
 complicated.  If you use \man{make}{1}, then something like
 \begin{prog}
-  SOD = sod \\
-  \\
+  SOD = sod
+  \\+
   .SUFFIXES: .sod .c .h \\
   .sod.c:; \$(SOD) -tc \$< \\
   .sod.h:; \$(SOD) -th \$<
@@ -109,46 +109,46 @@ ought to do the job.
 
 The following is a simple Sod input file.
 \begin{prog}
-/* -*-sod-*- */ \\
-\\
-code c : includes \{ \\
-\#include "greeter.h" \\
-\} \\
-\\
-code h : includes \{ \\
-\#include <stdio.h> \\
-\#include <sod/sod.h> \\
-\} \\
-\\
-class Greeter : SodObject \{ \\ \ind
-  void greet(FILE *fp) \{ \\ \ind
-    fputs("Hello, world!\textbackslash n", fp); \- \\
-  \} \- \\
-\}
+  /* -*-sod-*- */
+  \\+
+  code c : includes \{ \\
+  \#include "greeter.h" \\
+  \}
+  \\+
+  code h : includes \{ \\
+  \#include <stdio.h> \\
+  \#include <sod/sod.h> \\
+  \}
+  \\+
+  class Greeter : SodObject \{ \\ \ind
+    void greet(FILE *fp) \{ \\ \ind
+      fputs("Hello, world!\textbackslash n", fp); \- \\
+    \} \- \\
+  \}
 \end{prog}
 Save it as @"greeter.sod", and run
 \begin{prog}
-sod --gc --gh greeter
+  sod --gc --gh greeter
 \end{prog}
 This will create files @"greeter.c" and @"greeter.h" in the current
 directory.  Here's how we might use such a simple thing.
 \begin{prog}
-\#include "greeter.h" \\
-\\
-int main(void) \\
-\{ \\ \ind
-  SOD_DECL(Greeter, g); \\
-  \\
-  Greeter_greet(g, stdout); \\
-  return (0); \- \\
-\}
+  \#include "greeter.h"
+  \\+
+  int main(void) \\
+  \{ \\ \ind
+    SOD_DECL(Greeter, g);
+    \\+
+    Greeter_greet(g, stdout); \\
+    return (0); \- \\
+  \}
 \end{prog}
 Compare this to the traditional
 \begin{prog}
-\#include <stdio.h> \\
-\\
-int main(void) \\ \ind
-  \{ fputs("Hello, world@\\n", stdout); return (0); \}
+  \#include <stdio.h>
+  \\+
+  int main(void) \\ \ind
+    \{ fputs("Hello, world@\\n", stdout); return (0); \}
 \end{prog}
 and I'm sure you'll appreciate the benefits of using Sod already -- mostly to
 do with finger exercise.  Trust me, it gets more useful.
-- 
[mdw]

