internally split out main-usage functions for manpage-autogen support

This commit is contained in:
John Kerl 2015-11-01 21:49:49 -05:00
parent 228fa452d6
commit b1e4e62fab
3 changed files with 76 additions and 217 deletions

View file

@ -178,6 +178,19 @@ static char* rebackslash(char* sep) {
#define DEFAULT_OQUOTING QUOTE_MINIMAL
// ----------------------------------------------------------------
// The main_usage() function is split out into subroutines in support of the
// manpage autogenerator.
static void main_usage_synopsis(FILE* o, char* argv0) {
fprintf(o, "Usage: %s [I/O options] {verb} [verb-dependent options ...] {zero or more file names}\n", argv0);
}
static void list_all_verbs_raw(FILE* o) {
for (int i = 0; i < mapper_lookup_table_length; i++) {
fprintf(o, "%s\n", mapper_lookup_table[i]->verb);
}
}
static void list_all_verbs(FILE* o) {
char* leader = " ";
char* separator = " ";
@ -203,29 +216,21 @@ static void list_all_verbs(FILE* o) {
fprintf(o, "\n");
}
static void list_all_verbs_raw(FILE* o) {
for (int i = 0; i < mapper_lookup_table_length; i++) {
fprintf(o, "%s\n", mapper_lookup_table[i]->verb);
}
}
static void main_usage(FILE* o, char* argv0) {
fprintf(o, "Usage: %s [I/O options] {verb} [verb-dependent options ...] {file names}\n", argv0);
list_all_verbs(o);
fprintf(o, "Example: %s --csv --rs lf --fs tab cut -f hostname,uptime file1.csv file2.csv\n", argv0);
static void main_usage_help_options(FILE* o, char* argv0) {
fprintf(o, "Please use \"%s -h\" or \"%s --help\" to show this message.\n", argv0, argv0);
fprintf(o, "Please use \"%s --version\" to show the software version.\n", argv0);
fprintf(o, "Please use \"%s {verb name} --help\" for verb-specific help.\n", argv0);
fprintf(o, "Please use \"%s --list-all-verbs\" to list only verb names.\n", argv0);
fprintf(o, "Please use \"%s --help-all-verbs\" for help on all verbs.\n", argv0);
}
fprintf(o, "\n");
static void main_usage_functions(FILE* o, char* argv0) {
lrec_evaluator_list_functions(o);
fprintf(o, "Please use \"%s --help-function {function name}\" for function-specific help.\n", argv0);
fprintf(o, "Please use \"%s --help-all-functions\" or \"%s -f\" for help on all functions.\n", argv0, argv0);
fprintf(o, "\n");
}
static void main_usage_data_format_options(FILE* o, char* argv0) {
fprintf(o, "Data-format options, for input, output, or both:\n");
fprintf(o, " --idkvp --odkvp --dkvp Delimited key-value pairs, e.g \"a=1,b=2\"\n");
fprintf(o, " (default)\n");
@ -239,6 +244,9 @@ static void main_usage(FILE* o, char* argv0) {
fprintf(o, " -p is a keystroke-saver for --nidx --fs space --repifs\n");
fprintf(o, " Examples: --csv for CSV-formatted input and output; --idkvp --opprint for\n");
fprintf(o, " DKVP-formatted input and pretty-printed output.\n");
}
static void main_usage_separator_options(FILE* o, char* argv0) {
fprintf(o, "Separator options, for input, output, or both:\n");
fprintf(o, " --rs --irs --ors Record separators, e.g. 'lf' or '\\r\\n'\n");
fprintf(o, " --fs --ifs --ofs --repifs Field separators, e.g. comma\n");
@ -284,10 +292,16 @@ static void main_usage(FILE* o, char* argv0) {
char* ps = lhmss_get(default_pses, filefmt);
fprintf(o, " %-12s %-8s %-8s %s\n", filefmt, rebackslash(rs), rebackslash(fs), rebackslash(ps));
}
}
static void main_usage_csv_options(FILE* o, char* argv0) {
fprintf(o, "Relevant to CSV/CSV-lite input only:\n");
fprintf(o, " --implicit-csv-header Use 1,2,3,... as field labels, rather than from line 1\n");
fprintf(o, " of input files. Tip: combine with \"label\" to recreate\n");
fprintf(o, " missing headers.\n");
}
static void main_usage_double_quoting(FILE* o, char* argv0) {
fprintf(o, "Double-quoting for CSV output:\n");
fprintf(o, " --quote-all Wrap all fields in double quotes\n");
fprintf(o, " --quote-none Do not wrap any fields in double quotes, even if they have \n");
@ -296,15 +310,27 @@ static void main_usage(FILE* o, char* argv0) {
fprintf(o, " in them (default)\n");
fprintf(o, " --quote-numeric Wrap fields in double quotes only if they have numbers\n");
fprintf(o, " in them\n");
}
static void main_usage_numerical_formatting(FILE* o, char* argv0) {
fprintf(o, "Numerical formatting:\n");
fprintf(o, " --ofmt {format} E.g. %%.18lf, %%.0lf. Please use sprintf-style codes for\n");
fprintf(o, " double-precision. Applies to verbs which compute new\n");
fprintf(o, " values, e.g. put, stats1, stats2. See also the fmtnum\n");
fprintf(o, " function within mlr put (mlr --help-all-functions).\n");
}
static void main_usage_other_options(FILE* o, char* argv0) {
fprintf(o, "Other options:\n");
fprintf(o, " --seed {n} with n of the form 12345678 or 0xcafefeed. For put/filter urand().\n");
}
static void main_usage_then_chaining(FILE* o, char* argv0) {
fprintf(o, "Output of one verb may be chained as input to another using \"then\", e.g.\n");
fprintf(o, " %s stats1 -a min,mean,max -f flag,u,v -g color then sort -f color\n", argv0);
}
static void main_usage_see_also(FILE* o, char* argv0) {
fprintf(o, "For more information please see http://johnkerl.org/miller/doc and/or\n");
fprintf(o, "http://github.com/johnkerl/miller.");
#ifdef HAVE_CONFIG_H
@ -314,6 +340,26 @@ static void main_usage(FILE* o, char* argv0) {
#endif // HAVE_CONFIG_H
}
// ----------------------------------------------------------------
static void main_usage(FILE* o, char* argv0) {
main_usage_synopsis(o, argv0);
list_all_verbs(o);
fprintf(o, "Example: %s --csv --rs lf --fs tab cut -f hostname,uptime file1.csv file2.csv\n", argv0);
main_usage_help_options(o, argv0);
fprintf(o, "\n");
main_usage_functions(o, argv0);
fprintf(o, "\n");
main_usage_data_format_options(o, argv0);
main_usage_separator_options(o, argv0);
main_usage_csv_options(o, argv0);
main_usage_double_quoting(o, argv0);
main_usage_numerical_formatting(o, argv0);
main_usage_other_options(o, argv0);
main_usage_then_chaining(o, argv0);
main_usage_see_also(o, argv0);
}
// ----------------------------------------------------------------
static void usage_all_verbs(char* argv0) {
char* separator = "================================================================";

View file

@ -37,7 +37,7 @@ static void mapper_cut_usage(FILE* o, char* argv0, char* verb) {
fprintf(o, "-f {a,b,c} Field names to include for cut.\n");
fprintf(o, "-o Retain fields in the order specified here in the argument list.\n");
fprintf(o, " Default is to retain them in the order found in the input data.\n");
fprintf(o, "-x|--complement Exclude, rather that include, field names specified by -f.\n");
fprintf(o, "-x|--complement Exclude, rather than include, field names specified by -f.\n");
fprintf(o, "-r Treat field names as regular expressions. \"ab\", \"a.*b\" will\n");
fprintf(o, " match any field name containing the substring \"ab\" or matching\n");
fprintf(o, " \"a.*b\", respectively; anchors of the form \"^ab$\", \"^a.*b$\" may\n");

View file

@ -1,5 +1,7 @@
#!/usr/bin/env ruby
# xxx note about why: mindeps
# ----------------------------------------------------------------
def main
@ -10,6 +12,10 @@ def main
"Miller is like sed, awk, cut, join, and sort for name-indexed data such as CSV."
])
print make_section('SYNOPSIS', [
"mlr [I/O options] {verb} [verb-dependent options ...] {zero or more file names}"
])
print make_section('DESCRIPTION', [
"""This is something the Unix toolkit always could have done, and arguably always
should have done. It operates on key-value-pair data while the familiar
@ -45,16 +51,12 @@ separator, --ors the output record separator, and --rs sets both the input and
output separator to the given value."""
])
print make_subsection('SEPARATOR', [
"""asdfasdfadf"""
])
print make_code_block(`mlr -h`)
# xxx do better than backtick -- trap $?
verbs = `mlr --list-all-verbs-raw`
print make_subsection('VERBS', [
"""asdfasdfadf"""
""
])
verbs = verbs.strip.split("\n")
for verb in verbs
@ -91,7 +93,7 @@ end
# ----------------------------------------------------------------
# xxx temp
def make_subsection(title, paragraphs)
retval = ".SH \"#{title}\"\n"
retval = ".SS \"#{title}\"\n"
paragraphs.each do |paragraph|
retval += ".sp\n"
retval += groff_encode(paragraph) + "\n"
@ -102,7 +104,8 @@ end
# ----------------------------------------------------------------
# xxx temp
def make_subsubsection(title, paragraphs)
retval = ".SH \"#{title}\"\n"
retval = ".sp\n";
retval += "\\fB#{title}\\fR\n"
paragraphs.each do |paragraph|
retval += ".sp\n"
retval += groff_encode(paragraph) + "\n"
@ -113,10 +116,10 @@ end
# ----------------------------------------------------------------
def make_code_block(block)
retval = ".if n \\{\\\n"
retval += ".RS 4\n"
retval += ".RS 0\n"
retval += ".\\}\n"
retval += ".nf\n"
retval += block
retval += block.gsub('\\', '\e')
retval += ".fi\n"
retval += ".if n \\{\\\n"
retval += ".RE\n"
@ -124,203 +127,13 @@ end
# ----------------------------------------------------------------
def groff_encode(line)
line = line.gsub(/'/, '\(cq')
line = line.gsub(/"/, '\(dq')
#line = line.gsub(/'/, '\(cq')
#line = line.gsub(/"/, '\(dq')
line = line.gsub(/\./, '\&')
line = line.gsub(/-/, '\-')
#line = line.gsub(/-/, '\-')
line = line.gsub(/\\/, '\e')
line
end
# ================================================================
main
# ================================================================
# .TH "MILLER" "1" "09/14/2015" "\ \&" "\ \&"
# .\" -----------------------------------------------------------------
# .\" * Define some portability stuff
# .\" -----------------------------------------------------------------
# .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# .\" http://bugs.debian.org/507673
# .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
# .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# .ie \n(.g .ds Aq \(aq
# .el .ds Aq '
# .\" -----------------------------------------------------------------
# .\" * set default formatting
# .\" -----------------------------------------------------------------
# .\" disable hyphenation
# .nh
# .\" disable justification (adjust text to left margin only)
# .ad l
# .\" -----------------------------------------------------------------
# .\" * MAIN CONTENT STARTS HERE *
# .\" -----------------------------------------------------------------
# .SH "NAME"
# miller \- sed, awk, cut, join, and sort for name\-indexed data such as CSV
# .\" ----------------------------------------------------------------
# .SH "SYNOPSIS"
# .sp
# .\" ----------------------------------------------------------------
# .SH "DESCRIPTION"
# .sp
# Description text with backslash ampersand period\&. Also \-\- backslash dash.
# Also \(cq for single quote.
# Also \(dq for double quote.
# Also \*(Aq for single quote.
# .\" ----------------------------------------------------------------
# .SH "EXAMPLES"
# .sp
# .if n \{\
# .RS 4
# .\}
# .nf
# Here is a code block
# Here is a code block
# Here is a code block
# .fi
# .if n \{\
# .RE
# .\}
# .\" ----------------------------------------------------------------
# .SH "OPTIONS"
# .sp
# In the following option flags, the version with "i" designates the input stream, "o" the output stream, and the version without prefix sets the option for both input and output stream\&. For example: \-\-irs sets the input record separator, \-\-ors the output record separator, and \-\-rs sets both the input and output separator to the given value\&.
# .SS "SEPARATOR"
# .PP
# \-\-rs, \-\-irs, \-\-ors
# .RS 4
# Record separators, defaulting to newline
# .RE
# .PP
# \-\-fs, \-\-ifs, \-\-ofs, \-\-repifs
# .RS 4
# Field separators, defaulting to ","
# .RE
# .PP
# \-\-ps, \-\-ips, \-\-ops
# .RS 4
# Pair separators, defaulting to "="
# .RE
# .SS "DATA\-FORMAT"
# .PP
# \-\-dkvp, \-\-idkvp, \-\-odkvp
# .RS 4
# Delimited key\-value pairs, e\&.g "a=1,b=2" (default)
# .RE
# .PP
# \-\-nidx, \-\-inidx, \-\-onidx
# .RS 4
# Implicitly\-integer\-indexed fields (Unix\-toolkit style)
# .RE
# .PP
# \-\-csv, \-\-icsv, \-\-ocsv
# .RS 4
# Comma\-separated value (or tab\-separated with \-\-fs tab, etc\&.)
# .RE
# .PP
# \-\-pprint, \-\-ipprint, \-\-opprint, \-\-right
# .RS 4
# Pretty\-printed tabular (produces no output until all input is in)
# .RE
# .PP
# \-\-pprint, \-\-ipprint, \-\-opprint, \-\-right
# .RS 4
# Pretty\-printed tabular (produces no output until all input is in)
# .RE
# .sp
# \-p is a keystroke\-saver for \-\-nidx \-\-fs space \-\-repifs
# .SS "NUMERICAL FORMAT"
# .PP
# .RS 4
# Sets the numerical format given a printf\-style format string\&.
# .RE
# .SS "OTHER"
# .PP
# .RS 4
# Seeds the random number generator used for put/filter
# urand()
# with a number n of the form 12345678 or 0xcafefeed\&.
# .RE
# .SS "VERBS"
# .sp
# .it 1 an-trap
# .nr an-no-space-flag 1
# .nr an-break-flag 1
# .br
# .ps +1
# \fBcut\fR
# .RS 4
# .sp
# Usage: mlr cut [options]
# .sp
# Passes through input records with specified fields included/excluded\&.
# .PP
# \-f {a,b,c}
# .RS 4
# Field names to include for cut\&.
# .RE
# .PP
# \-o
# .RS 4
# Retain fields in the order specified here in the argument list\&. Default is to retain them in the order found in the input data\&.
# .RE
# .PP
# \-x|\-\-complement
# .RS 4
# Exclude, rather that include, field names specified by \-f\&.
# .RE
# .RE
# .sp
# .it 1 an-trap
# .nr an-no-space-flag 1
# .nr an-break-flag 1
# .br
# .ps +1
# \fBfilter\fR
# .RS 4
# .sp
# prints the AST (abstract syntax tree) for the expression, which gives full transparency on the precedence and associativity rules of Miller\(cqs grammar\&. Please use a dollar sign for field names and double\-quotes for string literals\&. Miller built\-in variables are NF, NR, FNR, FILENUM, FILENAME, PI, E\&.
# .sp
# Examples:
# .sp
# .if n \{\
# .RS 4
# .\}
# .nf
# mlr filter \*(Aqlog10($count) > 4\&.0\*(Aq
# mlr filter \*(AqFNR == 2 (second record in each file)\*(Aq
# mlr filter \*(Aqurand() < 0\&.001\*(Aq (subsampling)
# mlr filter \*(Aq$color != "blue" && $value > 4\&.2\*(Aq
# mlr filter \*(Aq($x<\&.5 && $y<\&.5) || ($x>\&.5 && $y>\&.5)\*(Aq
# .fi
# .if n \{\
# .RE
# .\}
# .sp
# Please see http://johnkerl\&.org/miller/doc/reference\&.html for more information including function list\&.
# .RE
# .sp
# .it 1 an-trap
# .nr an-no-space-flag 1
# .nr an-break-flag 1
# .br
# .ps +1
# .\" ----------------------------------------------------------------
# .RE
# .RE
# .\" ----------------------------------------------------------------
# .SH "AUTHOR"
# .sp
# miller is written by John Kerl <kerl\&.john\&.r@gmail\&.com>\&.
# .sp
# This manual page has been composed from miller\(cqs help output by Eric MSP Veith <eveith@veith\-m\&.de>\&.
# .SH "SEE ALSO"
# .sp
# sed(1), awk(1), cut(1), join(1), sort(1), RFC 4180: Common Format and MIME Type for Comma\-Separated Values (CSV) Files, the miller website http://johnkerl\&.org/miller/doc