Skip to content

Instantly share code, notes, and snippets.

@howardjones
Created November 30, 2019 09:27
Show Gist options
  • Save howardjones/e7c5cbae7e1df432da7f478cca7fb059 to your computer and use it in GitHub Desktop.
Save howardjones/e7c5cbae7e1df432da7f478cca7fb059 to your computer and use it in GitHub Desktop.
Reformatted copy of DFORMAT, a troff preprocessor for representing data formats. See https://lists.gnu.org/archive/html/groff/2012-11/pdfRiXK_KnNhU.pdf
#!/usr/bin/awk -f
# mailto:jlb@research.bell-labs.com
function error(s)
{
print "dformat error: " s " near input line " NR | "cat 1>&2";
}
BEGIN {
s= "recht 0.3 addrht 0.055 recspread 0.15 ";
s=s"charwid 0.07 textht 0.167 addrdelta 4 ";
s=s"bitwid 0.125 linedisp 0.04 addr both ";
s=s"fill off linethrutext 1 ";
s=s"shaded off";
n=split(s, x);
for (i = 1; i <= n - 1; i += 2) oparm[x[i]] = parm[x[i]] = x[i+1];
}
inlang == 0 {
if ($0 !~ /^\.begin[ \t]/ || $2 != "dformat") {
print;
} else {
inlang = 1;
print ".PS";
boxacnt = 0;
if (firstpic != 1) {
firstpic = 1;
print "fillval = 0.1";
}
}
next;
}
/^\.end/ {
inlang = 0;
print ".PE";
next;
}
$1 == "style" {
if (!($2 in parm)) {
error("unrecognized name: " $2);
} else if ($3 == "reset") {
t=oparm[$2];
oparm[$2] = parm[$2];
parm[$2] = t;
} else {
oparm[$2] = parm[$2];
parm[$2] = $3;
#error("set shaded to: " $3)
}
next;
}
$1 == "pic" {
$1 = "";
print $0;
next;
}
/^[^ \t]/ {
printf "BoxA: box invis ht %g wid 0", parm["recht"]
if (boxacnt++) {
printf " with .n at BoxA.s - (0, %g)",parm["recspread"] + maxdy * parm["textht"];
}
printf "\n";
maxdy = sumboxlen = 0;
gsub(/[ \t]+$/, "");
if ($0 != "noname") {
printf " \"%s \" rjust at BoxA.w\n", $0;
printf " box invis with .e at BoxA.w ht 0 wid %g\n",parm["charwid"] * (length($0) + 3);
}
printf " BoxB: box invis ht %g wid 0 at BoxA\n", parm["recht"];
next;
}
/./ {
boxname = "";
if ($1 ~ /:$/) {
boxname = substr($1, 1, length($1) - 1);
$1 = "";
$0 = " " $0;
}
range = $1;
$1 = "";
gsub(/^[ \t]+/, "");
gsub(/[ \t]+$/, "");
text = $0;
n=split(range, x, "-");
rlo = x[1];
rhi = (n >= 2) ? x[2] : rlo;
cwid = (rhi >= rlo) ? rhi - rlo + 1 : rlo - rhi + 1;
rwid = (n >= 3) ? (0 + x[3]) : cwid;
btype = x[4];
if (btype !~ /^(dot|dash|invis)/) {
btype = "solid";
}
textlen = parm["charwid"] * length(text);
boxlen = parm["bitwid"] * rwid;
dy = 0;
if (textlen > boxlen) {
# set dy, the channel for this text
chan[maxdy + 1] = -999;
for (dy = 1; chan[dy] + textlen > sumboxlen; dy++)
if (dy > maxdy) {
maxdy = dy;
}
if (parm["linethrutext"] == 0) {
for (k = 1; k <= dy; k++) {
chan[k] = sumboxlen+boxlen;
}
} else {
chan[dy] = sumboxlen;
}
}
sumboxlen += boxlen;
fill = "";
if (parm["fill"] == "on") {
fill = " fill ";
}
shaded = "";
if (parm["shaded"] != "off") {
shaded = " shaded ";
shaded = shaded "\"" parm["shaded"] "\" ";
}
if (boxname != "") {
printf " %s:", boxname;
}
printf " BoxB: box %s %s %s ht %g wid %g with .w at BoxB.e\n",
shaded, fill, btype, parm["recht"], boxlen;
if (dy == 0) {
printf " \"%s\" at BoxB.c\n", text;
} else {
if (rwid < 2) {
start = "BoxB.s";
} else {
start = "BoxB.se - (" parm["linedisp"] ",0)";
}
printf " line from %s down %g\n", start, dy * parm["textht"];
printf " \"%s\\|\" at last line .s rjust\n", text;
printf " box invis with .e at last line .s ht 0 wid %g\n",textlen;
}
if (parm["addr"] ~ /^(left|right|both)$/) {
dp = int(parm["addrdelta"]); # Delta Point size
if (dp < 0 || dp > 9) {
error("bad addrdelta value: " dp);
}
dah = parm["addrht"]; # Delta Addr Height
pb = parm["addr"]; # Parameter for Bits
if (rlo == rhi) {
printf " \"\\s-%d%s\\s+%d\" at BoxB.s + (0,%g)\n",dp, rlo, dp, dah;
} else {
if (pb == "left" || pb == "both") {
printf "\t\"\\|\\s-%d%s\\s+%d\" ljust at BoxB.sw + (0,%g)\n",dp, rlo, dp, dah;
}
if (pb == "right" || pb == "both") {
printf "\t\"\\s-%d%s\\s+%d\\|\" rjust at BoxB.se + (0,%g)\n",dp, rhi, dp, dah;
}
}
}
}
END {
if (inlang) {
error("eof inside begin/end");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment