summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2016-01-18 12:50:12 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2016-01-18 12:52:25 +0200
commit5a01a260c368d3045f0870cc09620a772027e911 (patch)
tree504d6d3d1504d0c8e180d1f36eed17b2a3fff07a
parent650ea3bd3bac1fa50f9c8566d5def774c5eb2fee (diff)
Initial support for plain text documentation (--generate-txt)
Support for option documentation generation is still a TODO.
-rw-r--r--cli/buildfile2
-rw-r--r--cli/generator.cxx47
-rw-r--r--cli/makefile1
-rw-r--r--cli/options.cli66
-rw-r--r--cli/options.cxx109
-rw-r--r--cli/options.hxx44
-rw-r--r--cli/options.ixx66
-rw-r--r--cli/source.cxx121
-rw-r--r--cli/txt.cxx268
-rw-r--r--cli/txt.hxx44
10 files changed, 638 insertions, 130 deletions
diff --git a/cli/buildfile b/cli/buildfile
index d221237..95f5d14 100644
--- a/cli/buildfile
+++ b/cli/buildfile
@@ -5,6 +5,6 @@ trav = traversal/{class elements namespace option unit}
exe{cli}: cxx{cli generator html lexer name-processor parser runtime-inline \
source context header inline man options runtime-header runtime-source \
-option-types $sema $trav} $libs
+txt option-types $sema $trav} $libs
cxx.poptions += -I$out_base -I$src_base
diff --git a/cli/generator.cxx b/cli/generator.cxx
index b086089..486c793 100644
--- a/cli/generator.cxx
+++ b/cli/generator.cxx
@@ -23,6 +23,7 @@
#include "man.hxx"
#include "html.hxx"
+#include "txt.hxx"
#include "context.hxx"
#include "generator.hxx"
@@ -122,8 +123,9 @@ generate (options const& ops, semantics::cli_unit& unit, path const& p)
bool gen_cxx (ops.generate_cxx ());
bool gen_man (ops.generate_man ());
bool gen_html (ops.generate_html ());
+ bool gen_txt (ops.generate_txt ());
- if (!gen_cxx && !gen_man && !gen_html)
+ if (!gen_cxx && !gen_man && !gen_html && !gen_txt)
gen_cxx = true;
if (ops.stdout_ ())
@@ -134,9 +136,11 @@ generate (options const& ops, semantics::cli_unit& unit, path const& p)
throw failed ();
}
- if (gen_man && gen_html)
+ if ((gen_man && gen_html) ||
+ (gen_man && gen_txt) ||
+ (gen_html && gen_txt))
{
- cerr << "error: --stdout cannot be used with man and html output"
+ cerr << "error: --stdout cannot only be used with one output format"
<< endl;
throw failed ();
}
@@ -463,6 +467,43 @@ generate (options const& ops, semantics::cli_unit& unit, path const& p)
append (os, ops.html_epilogue (), ops.html_epilogue_file (), unit);
}
+ // txt output
+ //
+ if (gen_txt)
+ {
+ ofstream txt;
+
+ if (!ops.stdout_ ())
+ {
+ path txt_path (pfx + base + sfx + ops.txt_suffix ());
+
+ if (!ops.output_dir ().empty ())
+ txt_path = path (ops.output_dir ()) / txt_path;
+
+ txt.open (txt_path.string ().c_str ());
+
+ if (!txt.is_open ())
+ {
+ cerr << "error: unable to open '" << txt_path << "' in write mode"
+ << endl;
+ throw failed ();
+ }
+
+ auto_rm.add (txt_path);
+ }
+
+ // The explicit cast helps VC++ 8.0 overcome its issues.
+ //
+ ostream& os (ops.stdout_ () ? cout : static_cast<ostream&> (txt));
+
+ append (os, ops.txt_prologue (), ops.txt_prologue_file (), unit);
+
+ context ctx (os, unit, ops);
+ generate_txt (ctx);
+
+ append (os, ops.txt_epilogue (), ops.txt_epilogue_file (), unit);
+ }
+
auto_rm.cancel ();
}
catch (const generation_failed&)
diff --git a/cli/makefile b/cli/makefile
index 3b29fdc..3c99e19 100644
--- a/cli/makefile
+++ b/cli/makefile
@@ -19,6 +19,7 @@ runtime-inline.cxx \
runtime-source.cxx \
man.cxx \
html.cxx \
+txt.cxx \
generator.cxx \
name-processor.cxx
diff --git a/cli/options.cli b/cli/options.cli
index 32a2794..20e1987 100644
--- a/cli/options.cli
+++ b/cli/options.cli
@@ -92,8 +92,8 @@ class options
bool --generate-cxx
{
- "Generate C++ code. If neither \cb{--generate-man} nor \cb{--generate-html}
- is specified, this mode is assumed by default."
+ "Generate C++ code. If neither \cb{--generate-man}, \cb{--generate-html},
+ nor \cb{--generate-txt} is specified, this mode is assumed by default."
};
bool --generate-man
@@ -106,6 +106,11 @@ class options
"Generate documentation in the HTML format."
};
+ bool --generate-txt
+ {
+ "Generate documentation in the plain text format, similar to usage."
+ };
+
bool --stdout
{
"Write output to STDOUT instead of a file. This option is not valid
@@ -198,23 +203,24 @@ class options
class <name>. The <name> value should be a fully-qualified class name,
for example, \cb{app::options}. The <kind> value can be \cb{short},
\cb{long}, or \cb{exclude}. If the value is \cb{exclude}, then the
- class documentation is excluded from usage and man/HTML output. For
+ class documentation is excluded from usage and man/HTML/text output. For
usage, the \cb{short} and \cb{long} values determine which usage
function will be called when the class is used as base or as part of
- the page usage (see \cb{--page-usage}). For man/HTML, these values
+ the page usage (see \cb{--page-usage}). For man/HTML/text, these values
determine which documentation strings are used in the output."
};
std::vector<std::string> --class
{
"<name>",
- "Generate the man page or HTML documentation only for the options class
- <name>. The <name> value should be a fully-qualified options class name,
- for example, \cb{app::options}. To generate documentation for multiple
- classes, repeat this option and the documentation will be produced in
- the order specified. This functionality is useful if you need to assemble
- documentation from multiple classes in a specific order or to insert
- custom documentation between options belonging to different classes."
+ "Generate the man page, HTML, or text documentation only for the options
+ class <name>. The <name> value should be a fully-qualified options class
+ name, for example, \cb{app::options}. To generate documentation for
+ multiple classes, repeat this option and the documentation will be
+ produced in the order specified. This functionality is useful if you need
+ to assemble documentation from multiple classes in a specific order or to
+ insert custom documentation between options belonging to different
+ classes."
};
std::map<std::string, std::string> --docvar|-v
@@ -260,6 +266,12 @@ class options
"Insert <text> at the beginning of the generated HTML file."
};
+ std::vector<std::string> --txt-prologue
+ {
+ "<text>",
+ "Insert <text> at the beginning of the generated text file."
+ };
+
// Epilogues.
//
std::vector<std::string> --hxx-epilogue
@@ -283,13 +295,19 @@ class options
std::vector<std::string> --man-epilogue
{
"<text>",
- "Insert <text> at the end of the generated man page text."
+ "Insert <text> at the end of the generated man page file."
};
std::vector<std::string> --html-epilogue
{
"<text>",
- "Insert <text> at the end of the generated HTML text."
+ "Insert <text> at the end of the generated HTML file."
+ };
+
+ std::vector<std::string> --txt-epilogue
+ {
+ "<text>",
+ "Insert <text> at the end of the generated text file."
};
// Prologue files.
@@ -329,6 +347,13 @@ class options
file."
};
+ std::string --txt-prologue-file
+ {
+ "<file>",
+ "Insert the content of <file> at the beginning of the generated text
+ file."
+ };
+
// Epilogue files.
//
std::string --hxx-epilogue-file
@@ -364,6 +389,14 @@ class options
"Insert the content of <file> at the end of the generated HTML file."
};
+ std::string --txt-epilogue-file
+ {
+ "<file>",
+ "Insert the content of <file> at the end of the generated text file."
+ };
+
+ // Output.
+ //
std::string --output-prefix
{
"<prefix>",
@@ -413,6 +446,13 @@ class options
of the generated HTML file."
};
+ std::string --txt-suffix = ".txt"
+ {
+ "<suffix>",
+ "Use <suffix> instead of the default \cb{.txt} to construct the name of
+ the generated text file."
+ };
+
std::string --option-prefix = "-"
{
"<prefix>",
diff --git a/cli/options.cxx b/cli/options.cxx
index 118d8ee..0be47dc 100644
--- a/cli/options.cxx
+++ b/cli/options.cxx
@@ -582,6 +582,7 @@ options ()
generate_cxx_ (),
generate_man_ (),
generate_html_ (),
+ generate_txt_ (),
stdout__ (),
suppress_undocumented_ (),
suppress_usage_ (),
@@ -610,6 +611,8 @@ options ()
man_prologue_specified_ (false),
html_prologue_ (),
html_prologue_specified_ (false),
+ txt_prologue_ (),
+ txt_prologue_specified_ (false),
hxx_epilogue_ (),
hxx_epilogue_specified_ (false),
ixx_epilogue_ (),
@@ -620,6 +623,8 @@ options ()
man_epilogue_specified_ (false),
html_epilogue_ (),
html_epilogue_specified_ (false),
+ txt_epilogue_ (),
+ txt_epilogue_specified_ (false),
hxx_prologue_file_ (),
hxx_prologue_file_specified_ (false),
ixx_prologue_file_ (),
@@ -630,6 +635,8 @@ options ()
man_prologue_file_specified_ (false),
html_prologue_file_ (),
html_prologue_file_specified_ (false),
+ txt_prologue_file_ (),
+ txt_prologue_file_specified_ (false),
hxx_epilogue_file_ (),
hxx_epilogue_file_specified_ (false),
ixx_epilogue_file_ (),
@@ -640,6 +647,8 @@ options ()
man_epilogue_file_specified_ (false),
html_epilogue_file_ (),
html_epilogue_file_specified_ (false),
+ txt_epilogue_file_ (),
+ txt_epilogue_file_specified_ (false),
output_prefix_ (),
output_prefix_specified_ (false),
output_suffix_ (),
@@ -654,6 +663,8 @@ options ()
man_suffix_specified_ (false),
html_suffix_ (".html"),
html_suffix_specified_ (false),
+ txt_suffix_ (".txt"),
+ txt_suffix_specified_ (false),
option_prefix_ ("-"),
option_prefix_specified_ (false),
option_separator_ ("--"),
@@ -697,6 +708,7 @@ options (int& argc,
generate_cxx_ (),
generate_man_ (),
generate_html_ (),
+ generate_txt_ (),
stdout__ (),
suppress_undocumented_ (),
suppress_usage_ (),
@@ -725,6 +737,8 @@ options (int& argc,
man_prologue_specified_ (false),
html_prologue_ (),
html_prologue_specified_ (false),
+ txt_prologue_ (),
+ txt_prologue_specified_ (false),
hxx_epilogue_ (),
hxx_epilogue_specified_ (false),
ixx_epilogue_ (),
@@ -735,6 +749,8 @@ options (int& argc,
man_epilogue_specified_ (false),
html_epilogue_ (),
html_epilogue_specified_ (false),
+ txt_epilogue_ (),
+ txt_epilogue_specified_ (false),
hxx_prologue_file_ (),
hxx_prologue_file_specified_ (false),
ixx_prologue_file_ (),
@@ -745,6 +761,8 @@ options (int& argc,
man_prologue_file_specified_ (false),
html_prologue_file_ (),
html_prologue_file_specified_ (false),
+ txt_prologue_file_ (),
+ txt_prologue_file_specified_ (false),
hxx_epilogue_file_ (),
hxx_epilogue_file_specified_ (false),
ixx_epilogue_file_ (),
@@ -755,6 +773,8 @@ options (int& argc,
man_epilogue_file_specified_ (false),
html_epilogue_file_ (),
html_epilogue_file_specified_ (false),
+ txt_epilogue_file_ (),
+ txt_epilogue_file_specified_ (false),
output_prefix_ (),
output_prefix_specified_ (false),
output_suffix_ (),
@@ -769,6 +789,8 @@ options (int& argc,
man_suffix_specified_ (false),
html_suffix_ (".html"),
html_suffix_specified_ (false),
+ txt_suffix_ (".txt"),
+ txt_suffix_specified_ (false),
option_prefix_ ("-"),
option_prefix_specified_ (false),
option_separator_ ("--"),
@@ -815,6 +837,7 @@ options (int start,
generate_cxx_ (),
generate_man_ (),
generate_html_ (),
+ generate_txt_ (),
stdout__ (),
suppress_undocumented_ (),
suppress_usage_ (),
@@ -843,6 +866,8 @@ options (int start,
man_prologue_specified_ (false),
html_prologue_ (),
html_prologue_specified_ (false),
+ txt_prologue_ (),
+ txt_prologue_specified_ (false),
hxx_epilogue_ (),
hxx_epilogue_specified_ (false),
ixx_epilogue_ (),
@@ -853,6 +878,8 @@ options (int start,
man_epilogue_specified_ (false),
html_epilogue_ (),
html_epilogue_specified_ (false),
+ txt_epilogue_ (),
+ txt_epilogue_specified_ (false),
hxx_prologue_file_ (),
hxx_prologue_file_specified_ (false),
ixx_prologue_file_ (),
@@ -863,6 +890,8 @@ options (int start,
man_prologue_file_specified_ (false),
html_prologue_file_ (),
html_prologue_file_specified_ (false),
+ txt_prologue_file_ (),
+ txt_prologue_file_specified_ (false),
hxx_epilogue_file_ (),
hxx_epilogue_file_specified_ (false),
ixx_epilogue_file_ (),
@@ -873,6 +902,8 @@ options (int start,
man_epilogue_file_specified_ (false),
html_epilogue_file_ (),
html_epilogue_file_specified_ (false),
+ txt_epilogue_file_ (),
+ txt_epilogue_file_specified_ (false),
output_prefix_ (),
output_prefix_specified_ (false),
output_suffix_ (),
@@ -887,6 +918,8 @@ options (int start,
man_suffix_specified_ (false),
html_suffix_ (".html"),
html_suffix_specified_ (false),
+ txt_suffix_ (".txt"),
+ txt_suffix_specified_ (false),
option_prefix_ ("-"),
option_prefix_specified_ (false),
option_separator_ ("--"),
@@ -933,6 +966,7 @@ options (int& argc,
generate_cxx_ (),
generate_man_ (),
generate_html_ (),
+ generate_txt_ (),
stdout__ (),
suppress_undocumented_ (),
suppress_usage_ (),
@@ -961,6 +995,8 @@ options (int& argc,
man_prologue_specified_ (false),
html_prologue_ (),
html_prologue_specified_ (false),
+ txt_prologue_ (),
+ txt_prologue_specified_ (false),
hxx_epilogue_ (),
hxx_epilogue_specified_ (false),
ixx_epilogue_ (),
@@ -971,6 +1007,8 @@ options (int& argc,
man_epilogue_specified_ (false),
html_epilogue_ (),
html_epilogue_specified_ (false),
+ txt_epilogue_ (),
+ txt_epilogue_specified_ (false),
hxx_prologue_file_ (),
hxx_prologue_file_specified_ (false),
ixx_prologue_file_ (),
@@ -981,6 +1019,8 @@ options (int& argc,
man_prologue_file_specified_ (false),
html_prologue_file_ (),
html_prologue_file_specified_ (false),
+ txt_prologue_file_ (),
+ txt_prologue_file_specified_ (false),
hxx_epilogue_file_ (),
hxx_epilogue_file_specified_ (false),
ixx_epilogue_file_ (),
@@ -991,6 +1031,8 @@ options (int& argc,
man_epilogue_file_specified_ (false),
html_epilogue_file_ (),
html_epilogue_file_specified_ (false),
+ txt_epilogue_file_ (),
+ txt_epilogue_file_specified_ (false),
output_prefix_ (),
output_prefix_specified_ (false),
output_suffix_ (),
@@ -1005,6 +1047,8 @@ options (int& argc,
man_suffix_specified_ (false),
html_suffix_ (".html"),
html_suffix_specified_ (false),
+ txt_suffix_ (".txt"),
+ txt_suffix_specified_ (false),
option_prefix_ ("-"),
option_prefix_specified_ (false),
option_separator_ ("--"),
@@ -1053,6 +1097,7 @@ options (int start,
generate_cxx_ (),
generate_man_ (),
generate_html_ (),
+ generate_txt_ (),
stdout__ (),
suppress_undocumented_ (),
suppress_usage_ (),
@@ -1081,6 +1126,8 @@ options (int start,
man_prologue_specified_ (false),
html_prologue_ (),
html_prologue_specified_ (false),
+ txt_prologue_ (),
+ txt_prologue_specified_ (false),
hxx_epilogue_ (),
hxx_epilogue_specified_ (false),
ixx_epilogue_ (),
@@ -1091,6 +1138,8 @@ options (int start,
man_epilogue_specified_ (false),
html_epilogue_ (),
html_epilogue_specified_ (false),
+ txt_epilogue_ (),
+ txt_epilogue_specified_ (false),
hxx_prologue_file_ (),
hxx_prologue_file_specified_ (false),
ixx_prologue_file_ (),
@@ -1101,6 +1150,8 @@ options (int start,
man_prologue_file_specified_ (false),
html_prologue_file_ (),
html_prologue_file_specified_ (false),
+ txt_prologue_file_ (),
+ txt_prologue_file_specified_ (false),
hxx_epilogue_file_ (),
hxx_epilogue_file_specified_ (false),
ixx_epilogue_file_ (),
@@ -1111,6 +1162,8 @@ options (int start,
man_epilogue_file_specified_ (false),
html_epilogue_file_ (),
html_epilogue_file_specified_ (false),
+ txt_epilogue_file_ (),
+ txt_epilogue_file_specified_ (false),
output_prefix_ (),
output_prefix_specified_ (false),
output_suffix_ (),
@@ -1125,6 +1178,8 @@ options (int start,
man_suffix_specified_ (false),
html_suffix_ (".html"),
html_suffix_specified_ (false),
+ txt_suffix_ (".txt"),
+ txt_suffix_specified_ (false),
option_prefix_ ("-"),
option_prefix_specified_ (false),
option_separator_ ("--"),
@@ -1169,6 +1224,7 @@ options (::cli::scanner& s,
generate_cxx_ (),
generate_man_ (),
generate_html_ (),
+ generate_txt_ (),
stdout__ (),
suppress_undocumented_ (),
suppress_usage_ (),
@@ -1197,6 +1253,8 @@ options (::cli::scanner& s,
man_prologue_specified_ (false),
html_prologue_ (),
html_prologue_specified_ (false),
+ txt_prologue_ (),
+ txt_prologue_specified_ (false),
hxx_epilogue_ (),
hxx_epilogue_specified_ (false),
ixx_epilogue_ (),
@@ -1207,6 +1265,8 @@ options (::cli::scanner& s,
man_epilogue_specified_ (false),
html_epilogue_ (),
html_epilogue_specified_ (false),
+ txt_epilogue_ (),
+ txt_epilogue_specified_ (false),
hxx_prologue_file_ (),
hxx_prologue_file_specified_ (false),
ixx_prologue_file_ (),
@@ -1217,6 +1277,8 @@ options (::cli::scanner& s,
man_prologue_file_specified_ (false),
html_prologue_file_ (),
html_prologue_file_specified_ (false),
+ txt_prologue_file_ (),
+ txt_prologue_file_specified_ (false),
hxx_epilogue_file_ (),
hxx_epilogue_file_specified_ (false),
ixx_epilogue_file_ (),
@@ -1227,6 +1289,8 @@ options (::cli::scanner& s,
man_epilogue_file_specified_ (false),
html_epilogue_file_ (),
html_epilogue_file_specified_ (false),
+ txt_epilogue_file_ (),
+ txt_epilogue_file_specified_ (false),
output_prefix_ (),
output_prefix_specified_ (false),
output_suffix_ (),
@@ -1241,6 +1305,8 @@ options (::cli::scanner& s,
man_suffix_specified_ (false),
html_suffix_ (".html"),
html_suffix_specified_ (false),
+ txt_suffix_ (".txt"),
+ txt_suffix_specified_ (false),
option_prefix_ ("-"),
option_prefix_specified_ (false),
option_separator_ ("--"),
@@ -1308,6 +1374,9 @@ print_usage (::std::ostream& os, ::cli::usage_para p)
os << "--generate-html Generate documentation in the HTML format." << ::std::endl;
+ os << "--generate-txt Generate documentation in the plain text format," << ::std::endl
+ << " similar to usage." << ::std::endl;
+
os << "--stdout Write output to STDOUT instead of a file." << ::std::endl;
os << "--suppress-undocumented Suppress the generation of documentation entries" << ::std::endl
@@ -1340,8 +1409,8 @@ print_usage (::std::ostream& os, ::cli::usage_para p)
os << "--class-doc <name>=<kind> Specify the documentation <kind> that should be" << ::std::endl
<< " used for the options class <name>." << ::std::endl;
- os << "--class <name> Generate the man page or HTML documentation only" << ::std::endl
- << " for the options class <name>." << ::std::endl;
+ os << "--class <name> Generate the man page, HTML, or text documentation" << ::std::endl
+ << " only for the options class <name>." << ::std::endl;
os << "--docvar|-v <name>=<val> Set documentation variable <name> to the value" << ::std::endl
<< " <val>." << ::std::endl;
@@ -1361,6 +1430,9 @@ print_usage (::std::ostream& os, ::cli::usage_para p)
os << "--html-prologue <text> Insert <text> at the beginning of the generated" << ::std::endl
<< " HTML file." << ::std::endl;
+ os << "--txt-prologue <text> Insert <text> at the beginning of the generated" << ::std::endl
+ << " text file." << ::std::endl;
+
os << "--hxx-epilogue <text> Insert <text> at the end of the generated C++" << ::std::endl
<< " header file." << ::std::endl;
@@ -1371,10 +1443,13 @@ print_usage (::std::ostream& os, ::cli::usage_para p)
<< " source file." << ::std::endl;
os << "--man-epilogue <text> Insert <text> at the end of the generated man page" << ::std::endl
- << " text." << ::std::endl;
+ << " file." << ::std::endl;
os << "--html-epilogue <text> Insert <text> at the end of the generated HTML" << ::std::endl
- << " text." << ::std::endl;
+ << " file." << ::std::endl;
+
+ os << "--txt-epilogue <text> Insert <text> at the end of the generated text" << ::std::endl
+ << " file." << ::std::endl;
os << "--hxx-prologue-file <file> Insert the content of <file> at the beginning of" << ::std::endl
<< " the generated C++ header file." << ::std::endl;
@@ -1391,6 +1466,9 @@ print_usage (::std::ostream& os, ::cli::usage_para p)
os << "--html-prologue-file <file> Insert the content of <file> at the beginning of" << ::std::endl
<< " the generated HTML file." << ::std::endl;
+ os << "--txt-prologue-file <file> Insert the content of <file> at the beginning of" << ::std::endl
+ << " the generated text file." << ::std::endl;
+
os << "--hxx-epilogue-file <file> Insert the content of <file> at the end of the" << ::std::endl
<< " generated C++ header file." << ::std::endl;
@@ -1406,6 +1484,9 @@ print_usage (::std::ostream& os, ::cli::usage_para p)
os << "--html-epilogue-file <file> Insert the content of <file> at the end of the" << ::std::endl
<< " generated HTML file." << ::std::endl;
+ os << "--txt-epilogue-file <file> Insert the content of <file> at the end of the" << ::std::endl
+ << " generated text file." << ::std::endl;
+
os << "--output-prefix <prefix> Add <prefix> at the beginning of the generated" << ::std::endl
<< " output file name(s)." << ::std::endl;
@@ -1427,6 +1508,9 @@ print_usage (::std::ostream& os, ::cli::usage_para p)
os << "--html-suffix <suffix> Use <suffix> instead of the default '.html' to" << ::std::endl
<< " construct the name of the generated HTML file." << ::std::endl;
+ os << "--txt-suffix <suffix> Use <suffix> instead of the default '.txt' to" << ::std::endl
+ << " construct the name of the generated text file." << ::std::endl;
+
os << "--option-prefix <prefix> Use <prefix> instead of the default '-' as an" << ::std::endl
<< " option prefix." << ::std::endl;
@@ -1508,6 +1592,8 @@ struct _cli_options_map_init
&::cli::thunk< options, bool, &options::generate_man_ >;
_cli_options_map_["--generate-html"] =
&::cli::thunk< options, bool, &options::generate_html_ >;
+ _cli_options_map_["--generate-txt"] =
+ &::cli::thunk< options, bool, &options::generate_txt_ >;
_cli_options_map_["--stdout"] =
&::cli::thunk< options, bool, &options::stdout__ >;
_cli_options_map_["--suppress-undocumented"] =
@@ -1557,6 +1643,9 @@ struct _cli_options_map_init
_cli_options_map_["--html-prologue"] =
&::cli::thunk< options, std::vector<std::string>, &options::html_prologue_,
&options::html_prologue_specified_ >;
+ _cli_options_map_["--txt-prologue"] =
+ &::cli::thunk< options, std::vector<std::string>, &options::txt_prologue_,
+ &options::txt_prologue_specified_ >;
_cli_options_map_["--hxx-epilogue"] =
&::cli::thunk< options, std::vector<std::string>, &options::hxx_epilogue_,
&options::hxx_epilogue_specified_ >;
@@ -1572,6 +1661,9 @@ struct _cli_options_map_init
_cli_options_map_["--html-epilogue"] =
&::cli::thunk< options, std::vector<std::string>, &options::html_epilogue_,
&options::html_epilogue_specified_ >;
+ _cli_options_map_["--txt-epilogue"] =
+ &::cli::thunk< options, std::vector<std::string>, &options::txt_epilogue_,
+ &options::txt_epilogue_specified_ >;
_cli_options_map_["--hxx-prologue-file"] =
&::cli::thunk< options, std::string, &options::hxx_prologue_file_,
&options::hxx_prologue_file_specified_ >;
@@ -1587,6 +1679,9 @@ struct _cli_options_map_init
_cli_options_map_["--html-prologue-file"] =
&::cli::thunk< options, std::string, &options::html_prologue_file_,
&options::html_prologue_file_specified_ >;
+ _cli_options_map_["--txt-prologue-file"] =
+ &::cli::thunk< options, std::string, &options::txt_prologue_file_,
+ &options::txt_prologue_file_specified_ >;
_cli_options_map_["--hxx-epilogue-file"] =
&::cli::thunk< options, std::string, &options::hxx_epilogue_file_,
&options::hxx_epilogue_file_specified_ >;
@@ -1602,6 +1697,9 @@ struct _cli_options_map_init
_cli_options_map_["--html-epilogue-file"] =
&::cli::thunk< options, std::string, &options::html_epilogue_file_,
&options::html_epilogue_file_specified_ >;
+ _cli_options_map_["--txt-epilogue-file"] =
+ &::cli::thunk< options, std::string, &options::txt_epilogue_file_,
+ &options::txt_epilogue_file_specified_ >;
_cli_options_map_["--output-prefix"] =
&::cli::thunk< options, std::string, &options::output_prefix_,
&options::output_prefix_specified_ >;
@@ -1623,6 +1721,9 @@ struct _cli_options_map_init
_cli_options_map_["--html-suffix"] =
&::cli::thunk< options, std::string, &options::html_suffix_,
&options::html_suffix_specified_ >;
+ _cli_options_map_["--txt-suffix"] =
+ &::cli::thunk< options, std::string, &options::txt_suffix_,
+ &options::txt_suffix_specified_ >;
_cli_options_map_["--option-prefix"] =
&::cli::thunk< options, std::string, &options::option_prefix_,
&options::option_prefix_specified_ >;
diff --git a/cli/options.hxx b/cli/options.hxx
index 9794732..1793343 100644
--- a/cli/options.hxx
+++ b/cli/options.hxx
@@ -457,6 +457,9 @@ class options
generate_html () const;
const bool&
+ generate_txt () const;
+
+ const bool&
stdout_ () const;
const bool&
@@ -541,6 +544,12 @@ class options
html_prologue_specified () const;
const std::vector<std::string>&
+ txt_prologue () const;
+
+ bool
+ txt_prologue_specified () const;
+
+ const std::vector<std::string>&
hxx_epilogue () const;
bool
@@ -570,6 +579,12 @@ class options
bool
html_epilogue_specified () const;
+ const std::vector<std::string>&
+ txt_epilogue () const;
+
+ bool
+ txt_epilogue_specified () const;
+
const std::string&
hxx_prologue_file () const;
@@ -601,6 +616,12 @@ class options
html_prologue_file_specified () const;
const std::string&
+ txt_prologue_file () const;
+
+ bool
+ txt_prologue_file_specified () const;
+
+ const std::string&
hxx_epilogue_file () const;
bool
@@ -631,6 +652,12 @@ class options
html_epilogue_file_specified () const;
const std::string&
+ txt_epilogue_file () const;
+
+ bool
+ txt_epilogue_file_specified () const;
+
+ const std::string&
output_prefix () const;
bool
@@ -673,6 +700,12 @@ class options
html_suffix_specified () const;
const std::string&
+ txt_suffix () const;
+
+ bool
+ txt_suffix_specified () const;
+
+ const std::string&
option_prefix () const;
bool
@@ -751,6 +784,7 @@ class options
bool generate_cxx_;
bool generate_man_;
bool generate_html_;
+ bool generate_txt_;
bool stdout__;
bool suppress_undocumented_;
bool suppress_usage_;
@@ -779,6 +813,8 @@ class options
bool man_prologue_specified_;
std::vector<std::string> html_prologue_;
bool html_prologue_specified_;
+ std::vector<std::string> txt_prologue_;
+ bool txt_prologue_specified_;
std::vector<std::string> hxx_epilogue_;
bool hxx_epilogue_specified_;
std::vector<std::string> ixx_epilogue_;
@@ -789,6 +825,8 @@ class options
bool man_epilogue_specified_;
std::vector<std::string> html_epilogue_;
bool html_epilogue_specified_;
+ std::vector<std::string> txt_epilogue_;
+ bool txt_epilogue_specified_;
std::string hxx_prologue_file_;
bool hxx_prologue_file_specified_;
std::string ixx_prologue_file_;
@@ -799,6 +837,8 @@ class options
bool man_prologue_file_specified_;
std::string html_prologue_file_;
bool html_prologue_file_specified_;
+ std::string txt_prologue_file_;
+ bool txt_prologue_file_specified_;
std::string hxx_epilogue_file_;
bool hxx_epilogue_file_specified_;
std::string ixx_epilogue_file_;
@@ -809,6 +849,8 @@ class options
bool man_epilogue_file_specified_;
std::string html_epilogue_file_;
bool html_epilogue_file_specified_;
+ std::string txt_epilogue_file_;
+ bool txt_epilogue_file_specified_;
std::string output_prefix_;
bool output_prefix_specified_;
std::string output_suffix_;
@@ -823,6 +865,8 @@ class options
bool man_suffix_specified_;
std::string html_suffix_;
bool html_suffix_specified_;
+ std::string txt_suffix_;
+ bool txt_suffix_specified_;
std::string option_prefix_;
bool option_prefix_specified_;
std::string option_separator_;
diff --git a/cli/options.ixx b/cli/options.ixx
index ed07f19..618d15f 100644
--- a/cli/options.ixx
+++ b/cli/options.ixx
@@ -338,6 +338,12 @@ generate_html () const
}
inline const bool& options::
+generate_txt () const
+{
+ return this->generate_txt_;
+}
+
+inline const bool& options::
stdout_ () const
{
return this->stdout__;
@@ -506,6 +512,18 @@ html_prologue_specified () const
}
inline const std::vector<std::string>& options::
+txt_prologue () const
+{
+ return this->txt_prologue_;
+}
+
+inline bool options::
+txt_prologue_specified () const
+{
+ return this->txt_prologue_specified_;
+}
+
+inline const std::vector<std::string>& options::
hxx_epilogue () const
{
return this->hxx_epilogue_;
@@ -565,6 +583,18 @@ html_epilogue_specified () const
return this->html_epilogue_specified_;
}
+inline const std::vector<std::string>& options::
+txt_epilogue () const
+{
+ return this->txt_epilogue_;
+}
+
+inline bool options::
+txt_epilogue_specified () const
+{
+ return this->txt_epilogue_specified_;
+}
+
inline const std::string& options::
hxx_prologue_file () const
{
@@ -626,6 +656,18 @@ html_prologue_file_specified () const
}
inline const std::string& options::
+txt_prologue_file () const
+{
+ return this->txt_prologue_file_;
+}
+
+inline bool options::
+txt_prologue_file_specified () const
+{
+ return this->txt_prologue_file_specified_;
+}
+
+inline const std::string& options::
hxx_epilogue_file () const
{
return this->hxx_epilogue_file_;
@@ -686,6 +728,18 @@ html_epilogue_file_specified () const
}
inline const std::string& options::
+txt_epilogue_file () const
+{
+ return this->txt_epilogue_file_;
+}
+
+inline bool options::
+txt_epilogue_file_specified () const
+{
+ return this->txt_epilogue_file_specified_;
+}
+
+inline const std::string& options::
output_prefix () const
{
return this->output_prefix_;
@@ -770,6 +824,18 @@ html_suffix_specified () const
}
inline const std::string& options::
+txt_suffix () const
+{
+ return this->txt_suffix_;
+}
+
+inline bool options::
+txt_suffix_specified () const
+{
+ return this->txt_suffix_specified_;
+}
+
+inline const std::string& options::
option_prefix () const
{
return this->option_prefix_;
diff --git a/cli/source.cxx b/cli/source.cxx
index 37058da..f8d367e 100644
--- a/cli/source.cxx
+++ b/cli/source.cxx
@@ -6,6 +6,7 @@
#include <iostream>
#include "source.hxx"
+#include "txt.hxx" // txt_size(), txt_wrap_lines()
using namespace std;
@@ -169,36 +170,6 @@ namespace
}
};
-
- // Return the number of "text characters", ignoring any escape sequences
- // (e.g., ANSI color).
- //
- static size_t
- text_size (const string& s, size_t p = 0, size_t n = string::npos)
- {
- size_t r (0);
-
- n = n == string::npos ? s.size () : n + p;
-
- // The start position (p) might be pointing half-way into the
- // escape sequence. So we always have to scan from the start.
- //
- for (size_t i (0), m (s.size ()); i < n; ++i)
- {
- if (s[i] == '\033') // ANSI escape: "\033[Nm"
- {
- i += 3;
- assert (i < m && s[i] == 'm');
- continue;
- }
-
- if (i >= p)
- ++r;
- }
-
- return r;
- }
-
static string
escape_str (string const& s)
{
@@ -234,88 +205,20 @@ namespace
return r;
}
- // This function assumes that the string opening part has already been
- // written. The 'first' argument is the number of characters already
- // written in the first line (e.g., an option name).
- //
- static void
+ inline void
wrap_lines (ostream& os,
const string& d,
size_t indent = 0,
size_t first = 0)
{
- assert (!d.empty ());
-
- os << string (indent - first, ' ');
-
- // Count the number of leading spaces at the beginning of each line.
- // Then use it as an extra indentation if we are breaking this line.
- // This makes multi-line definition lists look decent. Note that this
- // doesn't work for ordered/unordered lists because they start on the
- // same line as number/bullet. However, there is hack to make it work:
- // break the first line at the 80 characters boundary explicitly with
- // \n.
- //
- size_t wc (0), wi (0); // Count and count-based indentation.
- bool cws (true); // Count flag.
-
- size_t b (0), e (0), i (0);
- for (size_t n (d.size ()); i < n; ++i)
- {
- char c (d[i]);
-
- if (c == ' ' || c == '\n')
- e = i;
-
- if (c == '\n' || text_size (d, b, i - b) == 79 - indent - wi)
- {
- if (b != 0) // Not a first line.
- os << endl
- << " << \"" << string (indent + wi, ' ');
-
- string s (d, b, (e != b ? e : i) - b);
- os << escape_str (s) << "\" << ::std::endl";
-
- // Handle consecutive newlines (e.g., pre, paragraph separator).
- //
- if (c == '\n')
- {
- for (; i + 1 < n && d[i + 1] == '\n'; e = ++i)
- os << endl
- << " << ::std::endl";
- }
-
- b = e = (e != b ? e : i) + 1;
- wi = wc; // Start indent beginning with the next break.
- }
-
- if (c == '\n')
- {
- // Reset and start counting.
- //
- wc = wi = 0;
- cws = true;
- }
- else if (cws)
- {
- if (c == ' ')
- ++wc;
- else
- cws = false;
- }
- }
-
- // Flush the last line.
- //
- if (b != i)
- {
- if (b != 0)
- os << endl
- << " << \"" << string (indent + wi, ' ');
-
- string s (d, b, i - b);
- os << escape_str (s) << "\" << ::std::endl";
- }
+ txt_wrap_lines (os,
+ d,
+ indent,
+ first,
+ " << \"", // line_start
+ "\" << ::std::endl", // line_end
+ " << ::std::endl", // line_blank
+ &escape_str);
}
enum paragraph {para_unknown, para_text, para_option};
@@ -428,7 +331,7 @@ namespace
s = translate_arg (s, arg_set);
}
- l += text_size (format (ot_plain, s, false));
+ l += txt_size (format (ot_plain, s, false));
}
if (l > length_)
@@ -522,7 +425,7 @@ namespace
s = format (ot_plain, s, false);
os << escape_str (s);
- l += text_size (s);
+ l += txt_size (s);
}
// Figure out which documentation string we should use.
diff --git a/cli/txt.cxx b/cli/txt.cxx
new file mode 100644
index 0000000..c537c55
--- /dev/null
+++ b/cli/txt.cxx
@@ -0,0 +1,268 @@
+// file : cli/txt.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC
+// license : MIT; see accompanying LICENSE file
+
+#include <vector>
+#include <iostream>
+
+#include "txt.hxx"
+
+using namespace std;
+
+size_t
+txt_size (const string& s, size_t p, size_t n)
+{
+ size_t r (0);
+
+ n = n == string::npos ? s.size () : n + p;
+
+ // The start position (p) might be pointing half-way into the
+ // escape sequence. So we always have to scan from the start.
+ //
+ for (size_t i (0), m (s.size ()); i < n; ++i)
+ {
+ if (s[i] == '\033') // ANSI escape: "\033[Nm"
+ {
+ i += 3;
+ assert (i < m && s[i] == 'm');
+ continue;
+ }
+
+ if (i >= p)
+ ++r;
+ }
+
+ return r;
+}
+
+void
+txt_wrap_lines (ostream& os,
+ const string& d,
+ size_t indent,
+ size_t first,
+ const char* line_start,
+ const char* line_end,
+ const char* line_blank,
+ string (*escape) (string const&))
+{
+ assert (!d.empty ());
+
+ os << string (indent - first, ' ');
+
+ // Count the number of leading spaces at the beginning of each line.
+ // Then use it as an extra indentation if we are breaking this line.
+ // This makes multi-line definition lists look decent. Note that this
+ // doesn't work for ordered/unordered lists because they start on the
+ // same line as number/bullet. However, there is hack to make it work:
+ // break the first line at the 80 characters boundary explicitly with
+ // \n.
+ //
+ size_t wc (0), wi (0); // Count and count-based indentation.
+ bool cws (true); // Count flag.
+
+ size_t b (0), e (0), i (0);
+ for (size_t n (d.size ()); i < n; ++i)
+ {
+ char c (d[i]);
+
+ if (c == ' ' || c == '\n')
+ e = i;
+
+ if (c == '\n' || txt_size (d, b, i - b) == 79 - indent - wi)
+ {
+ if (b != 0) // Not a first line.
+ os << endl
+ << line_start << string (indent + wi, ' ');
+
+ string s (d, b, (e != b ? e : i) - b);
+
+ if (escape != 0)
+ s = escape (s);
+
+ os << s << line_end;
+
+ // Handle consecutive newlines (e.g., pre, paragraph separator).
+ //
+ if (c == '\n')
+ {
+ for (; i + 1 < n && d[i + 1] == '\n'; e = ++i)
+ os << endl
+ << line_blank;
+ }
+
+ b = e = (e != b ? e : i) + 1;
+ wi = wc; // Start indent beginning with the next break.
+ }
+
+ if (c == '\n')
+ {
+ // Reset and start counting.
+ //
+ wc = wi = 0;
+ cws = true;
+ }
+ else if (cws)
+ {
+ if (c == ' ')
+ ++wc;
+ else
+ cws = false;
+ }
+ }
+
+ // Flush the last line.
+ //
+ if (b != i)
+ {
+ if (b != 0)
+ os << endl
+ << line_start << string (indent + wi, ' ');
+
+ string s (d, b, i - b);
+
+ if (escape != 0)
+ s = escape (s);
+
+ os << s << line_end;
+ }
+}
+
+namespace
+{
+ struct doc: traversal::doc, context
+ {
+ doc (context& c, class_doc_type cd): context (c), cd_ (cd) {}
+
+ virtual void
+ traverse (type& ds)
+ {
+ if (ds.name ().compare (0, 3, "doc") != 0) // Ignore doc variables.
+ return;
+
+ // n = 1 - common doc string
+ // n = 2 - arg string, common doc string
+ // n > 2 - arg string, short string, long string
+ //
+ size_t n (ds.size ());
+ const string& d (
+ n == 1
+ ? (cd_ == cd_short ? first_sentence (ds[0]) : ds[0])
+ : (n == 2
+ ? (cd_ == cd_short ? first_sentence (ds[1]) : ds[1])
+ : ds[cd_ == cd_short ? 1 : 2]));
+
+ std::set<string> arg_set;
+ if (n > 1 && options.ansi_color ())
+ translate_arg (ds[0], arg_set);
+
+ string s (format (ot_plain, translate (d, arg_set), true));
+
+ if (s.empty ())
+ return;
+
+ txt_wrap_lines (os, s);
+ os << endl; //@@ ??
+ }
+
+ private:
+ class_doc_type cd_;
+ };
+
+ struct option: traversal::option, context
+ {
+ option (context& c, class_doc_type cd) : context (c), cd_ (cd) {}
+
+ virtual void
+ traverse (type& o)
+ {
+ using semantics::names;
+
+ semantics::doc_strings const& doc (o.doc ());
+
+ if (options.suppress_undocumented () && doc.empty ())
+ return;
+
+ //@@ TODO
+ }
+
+ private:
+ class_doc_type cd_;
+ };
+
+ //
+ //
+ struct class_: traversal::class_, context
+ {
+ class_ (context& c): context (c) {*this >> inherits_ >> *this;}
+
+ virtual void
+ traverse (type& c)
+ {
+ class_doc_type cd (class_doc (c));
+
+ if (cd == cd_exclude)
+ return;
+
+ if (!options.exclude_base () && !options.include_base_last ())
+ inherits (c);
+
+ doc dc (*this, cd);
+ option op (*this, cd);
+ traversal::names n;
+ n >> dc;
+ n >> op;
+ names (c, n);
+
+ if (!options.exclude_base () && options.include_base_last ())
+ inherits (c);
+ }
+
+ private:
+ traversal::inherits inherits_;
+ };
+}
+
+void
+generate_txt (context& ctx)
+{
+ traversal::cli_unit unit;
+ traversal::names unit_names;
+ traversal::namespace_ ns;
+ doc dc (ctx, cd_default);
+ class_ cl (ctx);
+ unit >> unit_names;
+ unit_names >> ns;
+ unit_names >> dc;
+ unit_names >> cl;
+
+ traversal::names ns_names;
+ ns >> ns_names;
+ ns_names >> ns;
+ ns_names >> dc;
+ ns_names >> cl;
+
+ if (ctx.options.class_ ().empty ())
+ unit.dispatch (ctx.unit);
+ else
+ {
+ for (vector<string>::const_iterator i (ctx.options.class_ ().begin ());
+ i != ctx.options.class_ ().end (); ++i)
+ {
+ string n (*i);
+
+ // Strip leading :: if present.
+ //
+ if (n.size () > 2 && n[0] == ':' && n[1] == ':')
+ n = string (n, 2, string::npos);
+
+ if (semantics::class_* c = ctx.unit.lookup<semantics::class_> ("", n))
+ cl.traverse (*c);
+ else
+ {
+ cerr << "error: class '" << *i << "' not found" << endl;
+ throw generation_failed ();
+ }
+ }
+ }
+}
diff --git a/cli/txt.hxx b/cli/txt.hxx
new file mode 100644
index 0000000..b0a667c
--- /dev/null
+++ b/cli/txt.hxx
@@ -0,0 +1,44 @@
+// file : cli/txt.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2009-2011 Code Synthesis Tools CC
+// license : MIT; see accompanying LICENSE file
+
+#ifndef CLI_TXT_HXX
+#define CLI_TXT_HXX
+
+#include <iosfwd> // ostream
+#include <string>
+#include <cstddef> // size_t
+
+#include "context.hxx"
+
+void
+generate_txt (context&);
+
+// Return the number of "text characters", ignoring any escape sequences
+// (e.g., ANSI color).
+//
+std::size_t
+txt_size (const std::string&,
+ std::size_t p = 0,
+ std::size_t n = std::string::npos);
+
+// This function assumes that the initial opening part has already been
+// written with the 'first' argument being the number of characters already
+// written in the first line (e.g., an option name). The 'indent' argument
+// specified how many spaces to indent each line. The 'escape' argument is
+// the optional escape function (e.g., for the string literal output). The
+// line_{start, end, blank} arguments specify optional extra text for the
+// start/end of the non-empty line as well as for the blank (empty) line.
+//
+void
+txt_wrap_lines (std::ostream& os,
+ const std::string&,
+ std::size_t indent = 0,
+ std::size_t first = 0,
+ const char* line_start = "",
+ const char* line_end = "",
+ const char* line_blank = "",
+ std::string (*escape) (std::string const&) = 0);
+
+#endif // CLI_TXT_HXX