aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Kerrisk (man-pages) <mtk.manpages@gmail.com>2020-08-06 15:20:22 +0200
committerMichael Kerrisk (man-pages) <mtk.manpages@gmail.com>2020-11-04 15:32:34 +0100
commitc19e5f608b26269ea003e0c5a2c21e11d321345a (patch)
tree5b3e8d32d1b802d0cbe318ce33ab757617734e10
downloadman-pages-posix-c19e5f608b26269ea003e0c5a2c21e11d321345a.tar.gz
Add files written by Felix Janda for the POSIX.1-2008 TC1 conversion
Signed-off-by: Michael Kerrisk (man-pages) <mtk.manpages@gmail.com>
-rwxr-xr-x,xref.1.awk27
-rwxr-xr-x,xref.py95
-rw-r--r--README126
-rwxr-xr-x_strings.sed32
-rwxr-xr-xposix.py354
5 files changed, 634 insertions, 0 deletions
diff --git a/,xref.1.awk b/,xref.1.awk
new file mode 100755
index 0000000..92515d6
--- /dev/null
+++ b/,xref.1.awk
@@ -0,0 +1,27 @@
+#!/usr/bin/awk -f
+# ,xref.1.awk - convert ,xref.6 to ,xref.1
+#
+# Copyright (C) 2013 Felix Janda
+#
+# Permission is hereby granted, free of charge, to any person
+# obtaining a copy of this software and associated documentation files
+# (the "Software"), to deal in the Software without restriction,
+# including without limitation the rights to use, copy, modify, merge,
+# publish, distribute, sublicense, and/or sell copies of the Software,
+# and to permit persons to whom the Software is furnished to do so,
+# subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+#
+# delete first, third and fourth field in each line
+{$1="";$3="";$4=$2;$2=""; print}
diff --git a/,xref.py b/,xref.py
new file mode 100755
index 0000000..3cfd531
--- /dev/null
+++ b/,xref.py
@@ -0,0 +1,95 @@
+#!/usr/bin/env python3
+# ,xref.py - Collect xrefs from HTML version of POSIX standard
+#
+# Copyright (C) 2013 Felix Janda
+#
+# Permission is hereby granted, free of charge, to any person
+# obtaining a copy of this software and associated documentation files
+# (the "Software"), to deal in the Software without restriction,
+# including without limitation the rights to use, copy, modify, merge,
+# publish, distribute, sublicense, and/or sell copies of the Software,
+# and to permit persons to whom the Software is furnished to do so,
+# subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+import re
+import sys
+import fileinput
+from glob import glob
+from html.entities import entitydefs
+
+sections = [["basedefs"], ["functions"], ["utilities"], ["xrat"]]
+re1 = re.compile('^.*<a name="tag_*|</.*>\n$| Table: | Figure: ')
+re2 = re.compile('">[^>]*</a>')
+re3 = re.compile('^.*> |\..*\n$')
+
+htmlrefs=[] # will be filled with lists of the form ["Chapter 1", "Introduction"]
+files = [] # all V*_chap*.html files
+for s in sections:
+ l = glob(sys.argv[1] + "/" + s[0] + "/V*_chap*.html")
+ l.sort()
+ files = files + l
+for line in fileinput.input(files):
+ if '<a name="tag' in line and not "_foot_" in line:
+ new = [] # To be added to entityrefs
+ prefix = "Section"
+ if "<h2>" in line:
+ prefix = "Chapter"
+ chapter = re3.sub("", line, count=2)
+ table = 1
+ figure = 1
+ elif "Table:" in line:
+ prefix = "Table"
+ new.append(prefix + " " + chapter + "-" + str(table))
+ table += 1
+ elif "Figure:" in line:
+ prefix = "Figure"
+ new.append(prefix + " " + chapter + "-" + str(figure))
+ figure += 1
+
+ line = re1.sub("", re2.sub(" ", line), count=3)
+
+ # Let python deal with the html entities
+ for ent in entitydefs:
+ line = line.replace("&" + ent + ";", entitydefs[ent])
+
+ part = line.partition(" ")
+
+ # Deal with the Sections
+ if not len(new):
+ partpart = part[0].split("_")
+ s = chapter
+ for i in range(1, len(partpart)):
+ s = s + "." + str(int(partpart[i]))
+ new.append(prefix + " " + s)
+
+ new.append(part[2])
+ htmlrefs.append(new)
+
+# Get the label names from ,xref.1 and print the results to stdout
+re4 = re.compile('Chapter|Section|Table|Figure')
+i = 0
+for line in open(",xref.1").readlines():
+ line = line.lstrip(" ").strip("\n")
+ part = line.partition(" ")
+ if re4.match(part[2]):
+ for j in range(i, len(htmlrefs)):
+ if part[2] == htmlrefs[j][0]:
+ print(line + ", " + htmlrefs[j][1])
+ i = j
+ break
+ else:
+ print(line)
+ else:
+ print(line)
diff --git a/README b/README
new file mode 100644
index 0000000..d94b204
--- /dev/null
+++ b/README
@@ -0,0 +1,126 @@
+Conversion of Open Group's troff sources to POSIX man pages
+===========================================================
+
+1. Necessary data:
+==================
+
+- obtainable from The Open Group
+ - directory with the troff sources
+ - file ,xref.6 containing information to crossreferences
+ - file _strings.def containing information to references to other
+ standards
+- obtainable online
+ - the HTML version of the standard
+
+
+The directory of troff sources contains four directories: "Builtins",
+"Commands", "Functions", "Headers". (Some of these contain
+subdirectories with "LEGACY" interfaces.) The directories contain .mm
+and .h files containing groff_mm files with extensions by The Open
+Group. Upon request one can also obtain a file defining their custom
+macros but this file is not necessary for the scripts.
+
+A relevant line in ,xref.6 could look like
+
+gropdf-info:href workdir page 104 Section 3.441
+
+It contains a label ("workdir"), the page number and the
+section number.
+
+A line in _strings.def might look like
+
+.ds Z5 ISO\ POSIX\(hy1 standard
+
+This tells us how to translate the escape sequence \*(Z5 .
+
+The HTML version of the standard can be obtained at
+
+http://pubs.opengroup.org/onlinepubs/9699919799/download/index.html
+
+The relevant files for the scripts are basedefs/V1_chap*.html,
+functions/V2_chap*.html, utilities/V3_chap*.html and
+xrat/V4_*_chap*.html. These are parts of the standard we do not
+have the sources for.
+
+2. Procedure to generate the man pages
+======================================
+
+Change your directory to the directory containing the conversion
+scripts. Type
+
+./,xref.1.awk < ,xref.6 > ,xref.1
+./,xref.py /path/to/HTML_version_of_standard > ,xref
+
+to generate ,xref and
+
+sed -f _strings.sed _strings.def > _strings.
+
+to generate _strings. With this done you can start generating
+individual man pages. To generate all pages use:
+
+./posix.py 0p /path/to/troff_sources/Headers/*.h
+./posix.py 1p /path/to/troff_sources/Built-Ins/*.mm
+./posix.py 1p /path/to/troff_sources/Commands/*.mm
+./posix.py 3p /path/to/troff_sources/Functions/*.mm
+
+You can now find the converted pages in your current working
+directory.
+
+3. Description of the included scripts
+======================================
+
+,xref.1.awk takes ,xref.6 from its standard input, strips
+irrelevant lines and transforms lines of the form
+
+gropdf-info:href whitespace page 103 Section 3.436
+
+to
+
+ whitespace Section 3.436
+
+,xref.1.py expects ,xref.1 generated from ,xref.1.awk in the
+current working directory and the path to the HTML version of
+the standard as its first argument. It extracts section, table
+and figure names for parts of the standard we do not have sources
+for, adds them to the xrefs and writes them to standard output.
+For the example, inside
+
+/path/to/HTML_version_of_standard/basedefs/V1_chap03.html
+
+it finds a line
+
+class; see also <a href="#tag_03_436">White Space</a>.</p>
+
+and therefore outputs
+
+whitespace Section 3.436, White Space
+
+to ,xref.
+
+The sed script _strings.sed does a simple conversion of lines of
+the form
+
+.ds Z5 ISO\ POSIX\(hy1 standard
+
+to
+
+\*(Z5 ISO\ POSIX\(hy1 standard
+
+The main script is posix.py. It takes the name of the man section
+as its first argument and the names of the pages to be converted
+as its other arguments. Furthermore, it expects the data files
+,xref and _strings in its current working directory. It outputs
+converted man pages to its current working directory.
+
+Notes:
+
+A final processing of the xrefs happens in posix.py: On the one
+hand the section names for cross-references internal to the
+current page are added. On the other hand the references to
+other man pages are correctly formatted. The order of the entries
+in ,xref is used to deduce the right section number. This could
+also be achieved by careful examining the source directory.
+
+The code in posix.py to get the indentation right by inserting
+".RS ..." and ".RE" in the right places is very hacky and might
+fail with pages with a slightly more complex structure then now.
diff --git a/_strings.sed b/_strings.sed
new file mode 100755
index 0000000..ba4ca47
--- /dev/null
+++ b/_strings.sed
@@ -0,0 +1,32 @@
+# _strings.sed - convert _strings.def to _strings
+#
+# Copyright (C) 2013 Felix Janda
+#
+# Permission is hereby granted, free of charge, to any person
+# obtaining a copy of this software and associated documentation files
+# (the "Software"), to deal in the Software without restriction,
+# including without limitation the rights to use, copy, modify, merge,
+# publish, distribute, sublicense, and/or sell copies of the Software,
+# and to permit persons to whom the Software is furnished to do so,
+# subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+#
+# reformat lines starting with .ds
+/^\.ds .* .*$/{
+s/^\.ds /\\*(/;
+s/ /\t/;
+p
+}
+# delete everything else
+d
diff --git a/posix.py b/posix.py
new file mode 100755
index 0000000..a20bc69
--- /dev/null
+++ b/posix.py
@@ -0,0 +1,354 @@
+#!/usr/bin/env python
+# posix.py - Convert The Open Group troff sources to posix man pages
+#
+# Copyright (C) 2013 Felix Janda
+#
+# Permission is hereby granted, free of charge, to any person
+# obtaining a copy of this software and associated documentation files
+# (the "Software"), to deal in the Software without restriction,
+# including without limitation the rights to use, copy, modify, merge,
+# publish, distribute, sublicense, and/or sell copies of the Software,
+# and to permit persons to whom the Software is furnished to do so,
+# subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+import sys
+import os.path
+import re
+
+# Helper for troff()
+def quote(arg):
+ if " " in arg or "\\" in arg: return '"{}"'.format(arg)
+ else: return arg
+
+# troff(".BL", "some text", ",") --> '.B "some text" ,\n'
+def troff(macro, *args):
+ if len(args) == 1 and type(args[0]) is list:
+ args = args[0]
+ args = [quote(arg) for arg in args]
+ s = ".{} {}".format(macro, " ".join(args))
+ return s.strip(" ") + "\n"
+
+# For first processing
+# Replace a macro by a string
+brepl = {"mH":".SH",
+ "Cm":".I",
+ "Ev":".I",
+ "Ar":".I",
+ "yS":".LP\n.nf",
+ "yE":".fi",
+ "Cs":".sp\n.RS 4\n.nf\n\\fB",
+ "Ce":".fi \\fR\n.P\n.RE",
+ "HU":".SS",
+ "cV":".B",
+ "Fi":".B",
+ "rS":'.LP\n.I "The following sections are informative."',
+ "Cd":".I"}
+# Surround the argument of a macro by two strings.
+sur = {"LM":["{", "}"],
+ "Hd":[".I <", "> "],
+ "tK":["<", ">"],
+ "cH":[".B '", "' "],
+ "sG":[".B \\(dq", "\\(dq "],
+ "Fn":["\\fI","\\fR()"],
+ "Er":[".B [", "] "]}
+# Delete a macro
+delete = {"xR",
+ "iX",
+ "sS",
+ "sE",
+ "sP",
+ "TH",
+ "SK",
+ "sT",
+ "mS",
+ "mE",
+ "rE",
+ "po",
+ "if",
+ "ne",
+ "nr",
+ "tr",
+ "in"}
+# Places where we might need to insert .RS to get indentation right
+indentpoint = {"P", "BL", "DL", "VL", "AL", "Cs", "Ns"}
+# Places where we might need to insert .RE to get indentation right
+indentend = {"LE", "LI", "Ne"}
+# Generic replacements in the seconds processing
+repl = {"\\f1":"\\fR",
+ "\\f2":"\\fI",
+ "\\f3":"\\fB",
+ "\\f5":"\\fR",
+ "\\f6":"\\fI",
+ "\\f7":"\\fB",
+ "XBD\n":"the \\*(Zz,\n",
+ "XSH\n":"the \\*(Zy,\n",
+ "XCU\n":"the \\*(Zx,\n",
+ "XRAT\n":"the \\*(zj,\n",
+ "\\*(x":"",
+ "\\*(z!":"",
+ "\\*(z?":"",
+ ".TS H":".TS",
+ "\\(*D":" ",
+ ".B ":".BR ",
+ ".I ":".IR ",
+ '" "$':"$"}
+
+# Here it starts
+
+if len(sys.argv) == 1:
+ progname = os.path.basename(sys.argv[0])
+ sys.stderr.write("Usage: {} SECTION [FILE...]\n".format(progname))
+ exit(2)
+section = sys.argv[1]
+
+# Add the escape sequences from _strings to the repl dictionary
+lines=open("_strings").readlines()
+for l in lines:
+ p = l.partition("\t")
+ repl[p[0]] = p[2].strip("\n")
+
+# Generate refdictorig from the ,xref file. It will be later extended to
+# the refdict dictionary with table and figure names from the current man
+# page
+refdictregs = [[r'\\fB<([a-zA-Z0-9\._/]*)>\\fP$', r'.BR \1 ({}p)'],
+ [r'\\fI([a-zA-Z0-9_]*)\\fR\\\^\(\\\|\)$', r'.BR \1 ({}p)'],
+ [r'\\fI([a-zA-Z0-9]*)\\fR\\\^$', r'.BR \1 ({}p)']]
+refdictorig = dict()
+lines = open(",xref").readlines()
+nsec = -1 # current section
+for l in lines:
+ if l.startswith("intro_"): nsec += 1
+ p = l.partition(" ")
+ s = p[2].strip("\n").replace(', ', '" ", " "')
+ for reg in refdictregs: # Format references to other man pages
+ s = re.sub(reg[0], reg[1].format([0, 3, 1][nsec]), s)
+ if s[0] != ".": # Otherwise make it italic
+ s = '.I "{}"'.format(s)
+ if ".h" in s: s = s.replace("/", "_") # for <sys/types.h>
+ refdictorig[p[0]] = s
+
+for file in sys.argv[2:]:
+ input = open(file)
+ lines = input.readlines()
+ input.close()
+
+ # Complete the ref descriptions
+ refdict = refdictorig
+ for i, l in enumerate(lines):
+ l = l.strip("\n")
+ if l.startswith(".xR ") and l[4] in ["6", "7"]:
+ key = l.split(" ")[2]
+ # Add numbers to tables and figures in current page
+ lines[i - 1] += ' " ' + refdict[key].split(" ")[2]
+ refdict[key] = '{}, {}"'.format(refdict[key].strip('"'),
+ prev.split(' "')[1].strip('"'))
+ prev = l
+
+ in_DSI = 0 # Are we in a display?
+ list_stack = [["BL"]] # stack of groff_mm lists we are in
+ list_num_stack = [] # stack of current list item numbers
+ needindent = 0 # do we need to insert .RS before the next paragraph?
+
+ # First processing
+ for i, l in enumerate(lines):
+ # only consider lines with macros
+ if not l or l[0] != ".": continue
+
+ # read out macro name with its arguments
+ macro = l.strip("\n").partition(" ")[0][1:]
+ args = ["".join(t) for t in re.findall(r'([^\s"][^\s]*"*)|"([^"]*)"',
+ l.strip("\n"))][1:]
+
+ # strip comments
+ if macro.startswith('\\"'): lines[i] = ""
+
+ insert = "" # string to be inserted in front of current line
+ if needindent > 0:
+ if macro in indentpoint:
+ insert = ".RS {} \n".format(needindent)
+ needindent = -1
+ if needindent == -1 and macro in indentend:
+ insert = ".RE\n"
+
+ # "Note:" macros
+ if macro == "Ns":
+ lines[i] = ".TP 10\n.B Note"
+ if args: lines[i] += "s"
+ lines[i] += ":\n"
+ needindent = 10
+ if macro == "Ne":
+ lines[i] = troff("P")
+ needindent = -1
+
+ # Read the name of the current man page from the mS macro
+ if macro == "mS": name = args[0]
+
+ # mm display macros
+ if macro == "DS":
+ if "I" in args:
+ lines[i] = ".sp\n.RS\n"
+ in_DSI = 1
+ else: lines[i] = ""
+ elif macro == "DE":
+ if in_DSI: lines[i] = troff("RE")
+ else: lines[i] = ""
+ in_DSI = 0
+
+ # Fix table and figure captions
+ if macro == "TB":
+ if len(args) == 1: args.append("")
+ lines[i] = ".sp\n.ce 1\n\\fBTable{}: {}\\fR\n".format(args[1], args[0])
+ elif macro == "FG":
+ if len(args) == 1: args.append("")
+ lines[i] = ".sp\n.ce 1\n\\fBFigure{}: {}\\fR\n".format(args[1], args[0])
+ # strip unecessary macros around figures
+ elif macro == "F+":
+ lines[i] = lines[i + 1] = lines[i + 2] = ""
+
+ # mm list macro processing
+ elif macro in {"BL", "DL", "VL", "AL"}: # start of a list
+ needindent = 0
+ list_stack.insert(0, [macro, args])
+ if list_stack[0][0] == "AL":
+ list_num_stack.insert(0, 1)
+ lines[i] = ""
+ elif macro == "LI": # list item
+ # Strip some unecessary escape sequences to make the regexes for
+ # formatting the ERRORS section happy
+ if args: args[0] = args[0].replace("\\*!", "")
+
+ needindent = 4
+ if list_stack[0][0] == "BL": # bullet list
+ li_args = [" *", "4"]
+ elif list_stack[0][0] == "DL": # dashed list
+ li_args = ["--", "4"]
+ elif list_stack[0][0] == "VL": # variable item list
+ needindent = (int(list_stack[0][1][0]) - 8) // 2 + 8
+ li_args = [args[0], str(needindent)]
+ elif list_stack[0][0] == "AL": # advanced list
+ num = list_num_stack[0]
+ s = ""
+ if not list_stack[0][1]: # 1. 2. 3.
+ s = str(num)
+ elif list_stack[0][1][0] == "a": # a. b. c.
+ s = chr(num + 96)
+ elif list_stack[0][1][0] == "i": # i. ii. iii.
+ needindent += 1
+ s = "".join(["i" for j in range(num)])
+ li_args = ["{:>2s}.".format(s), str(needindent)]
+ list_num_stack[0] += 1
+ lines[i] = troff("IP", li_args)
+ elif macro == "LE": # list end
+ if list_stack[0][0] == "AL":
+ del list_num_stack[0]
+ del list_stack[0]
+ lines[i] = ""
+ needindent = -1
+ if len(list_stack) >= 2:
+ lines[i] = troff("LE") + troff("RE")
+
+ # References
+ elif macro == "cX":
+ key = args[0]
+ if key in refdict: s = refdict[key]
+ else: s = key
+ if len(args) > 1: s += args[1]
+ lines[i] = s + "\n"
+
+ # Generic replacements
+ if macro in delete:
+ lines[i] = ""
+ elif macro in brepl:
+ lines[i] = l.replace("." + macro, brepl[macro], 1)
+ elif macro in sur:
+ lines[i] = sur[macro][0] + args[0] + sur[macro][1] + " ".join(args[1:]) + "\n"
+
+ lines[i] = insert + lines[i]
+
+ # Second processing
+ in_SEE_ALSO = 0 # Are we in the SEE ALSO section?
+ in_EQ = 0 # Are we in a displayed equation?
+ for i, l in enumerate(lines):
+ if l == ".SH \"SEE ALSO\"\n":
+ in_SEE_ALSO = 1
+ elif l == ".SH \"CHANGE HISTORY\"\n":
+ lines = lines[:i] # We are not allowed to include the CHANGE HISTORY
+ break
+ elif l == ".EQ\n":
+ in_EQ = 1
+ elif l == ".EN\n":
+ in_EQ = 0
+ # hack the equations to be a bit better readable on terminals
+ if in_EQ or '$' in l:
+ l = re.sub(r' sup ([a-zA-Z0-9\\\(]*)', "\"^\" \\1\" \"", l)
+ l = re.sub(r' sub ([a-zA-Z0-9\\\(]*)', "_ \\1\" \"", l)
+ l = l.replace("left { ~\n", "")
+ l = l.replace("~", ' " " ')
+ # reformat the error codes in the ERRORS section
+ l = re.sub(r'.IP \[(E[0-9A-Z]*)\] [0-9]*\n', ".TP\n.B \\1\n", l)
+ l = re.sub(r'.IP "\[(E[0-9A-Z]*)\] or \[(E[0-9A-Z]*)\]" [0-9]*\n',
+ ".TP\n.BR \\1 \" or \" \\2\n", l)
+ # Strip some extra space in the beginning of lines
+ l = re.sub(r'^\\ ', "", l)
+ # Generic replacements
+ for me in repl:
+ l = l.replace(me, repl[me])
+ for me in repl: # To be sure...
+ l = l.replace(me, repl[me])
+ if in_SEE_ALSO: l = re.sub(r'^the', "The", l)
+ lines[i] = l
+
+ name = re.sub(r'^<|>$', r'', name).replace("/", "_")
+ # name printed on the top of the man page
+ if section != "0p": NAME = name.upper()
+ else: NAME = name
+ lines.insert(0,
+ "'\\\" et\n"
+ ".TH {} \"{}\" 2013 \"IEEE/The Open Group\" \"POSIX Programmer's Manual\"\n"
+ ".SH PROLOG\n"
+ "This manual page is part of the POSIX Programmer's Manual.\n"
+ "The Linux implementation of this interface may differ (consult\n"
+ "the corresponding Linux manual page for details of Linux behavior),\n"
+ "or the interface may not be implemented on Linux.\n"
+ "\n"
+ "".format(NAME, section.upper()))
+ lines.append(
+ ".SH COPYRIGHT\n"
+ "Portions of this text are reprinted and reproduced in electronic form\n"
+ "from IEEE Std 1003.1, 2013 Edition, Standard for Information Technology\n"
+ "-- Portable Operating System Interface (POSIX), The Open Group Base\n"
+ "Specifications Issue 7, Copyright (C) 2013 by the Institute of\n"
+ "Electrical and Electronics Engineers, Inc and The Open Group.\n"
+ "(This is POSIX.1-2008 with the 2013 Technical Corrigendum 1 applied.) In the\n"
+ "event of any discrepancy between this version and the original IEEE and\n"
+ "The Open Group Standard, the original IEEE and The Open Group Standard\n"
+ "is the referee document. The original Standard can be obtained online at\n"
+ "http://www.unix.org/online.html .\n"
+ "\n"
+ "Any typographical or formatting errors that appear\n"
+ "in this page are most likely\n"
+ "to have been introduced during the conversion of the source files to\n"
+ "man page format. To report such errors, see\n"
+ "https://www.kernel.org/doc/man-pages/reporting_bugs.html .\n"
+ )
+
+ text = "".join(lines)
+ # Final hacks for the indentation
+ for i in [[".LE\n.RE\n.P", ".P"], [".LE\n.RE\n.RE", ".RE"],
+ [".RE\n.LE\n.RE", ".RE"], ["\n.LE\n", "\n"]]:
+ text = text.replace(i[0], i[1])
+ output = open(name + "." + section, 'w')
+ output.write(text)
+ output.close()