add doxygen files
This commit is contained in:
@@ -1,566 +1,378 @@
|
||||
/* The standard CSS for doxygen
|
||||
|
||||
modified by RossCairns.com
|
||||
*/
|
||||
/* Google's standard stylesheet for publishing to developers.google.com */
|
||||
/* Settings in this file add to or override settings in the default stylesheet */
|
||||
/* Specify this filename with the HTML_EXTRA_STYLESHEET setting in Doxyfile */
|
||||
|
||||
body, table, div, p, dl {
|
||||
font-family: Lucida Grande, Verdana, Geneva, Arial, sans-serif;
|
||||
font-size: 12px;
|
||||
/* author: doog@google.com */
|
||||
|
||||
/* Limitations due to HTML and id design: */
|
||||
/* * The paramtype and param padding styles affect both the top and bottom */
|
||||
/* spacing of method prototypes that have no parameters */
|
||||
/* (e.g. closeActiveNativeShareDialog in Google+ API), and also spacing */
|
||||
/* in between parameters (e.g. handleURL). I would like to make the */
|
||||
/* shaded rectangle slightly larger for prototypes with no parameter, */
|
||||
/* but keep the parameter lines withini a single prototype tight. */
|
||||
/* */
|
||||
/* * Property detail prototype has a one-cell table for the name */
|
||||
/* (e.g. delegate) instead of a two-cell table for both the name and */
|
||||
/* arguments. This makes the style definitions complicated. */
|
||||
|
||||
|
||||
/* OVERVIEW PAGE (index.html) */
|
||||
|
||||
.icon, .icona {
|
||||
display: none;
|
||||
}
|
||||
|
||||
p, div, dl {
|
||||
color:#3E3E3E;
|
||||
.directory {
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
div.contents p {
|
||||
|
||||
font-family:Monaco, courier;
|
||||
|
||||
/* Set gray background on all rows (not just even) but does NOT work */
|
||||
.directory tr.even, .directory td.entry, .directory td.desc {
|
||||
}
|
||||
|
||||
/* @group Heading Levels */
|
||||
|
||||
h1 {
|
||||
margin-bottom: 10px;
|
||||
font-size: 30px;
|
||||
padding: 0px 0px 20px 0px ;
|
||||
|
||||
border-bottom:1px dotted #E0E0E0;
|
||||
}
|
||||
|
||||
h2 {
|
||||
padding-top: 30px;
|
||||
font-size: 17px;
|
||||
color:#42657B;
|
||||
font-family: Lucida Grande, Verdana, Geneva, Arial, sans-serif;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 17px;
|
||||
font-family: Lucida Grande, Verdana, Geneva, Arial, sans-serif;
|
||||
}
|
||||
|
||||
dt {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
div.multicol {
|
||||
-moz-column-gap: 1em;
|
||||
-webkit-column-gap: 1em;
|
||||
-moz-column-count: 3;
|
||||
-webkit-column-count: 3;
|
||||
}
|
||||
|
||||
p.startli, p.startdd, p.starttd {
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
p.endli {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
p.enddd {
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
p.endtd {
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
/* @end */
|
||||
|
||||
caption {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
span.legend {
|
||||
font-size: 70%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
h3.version {
|
||||
font-size: 90%;
|
||||
padding-bottom:10px;
|
||||
border-bottom:1px dotted #E0E0E0;
|
||||
}
|
||||
|
||||
div.qindex, div.navtab{
|
||||
background-color: #e8eef2;
|
||||
border: 1px solid #84b0c7;
|
||||
text-align: center;
|
||||
margin: 2px;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
div.qindex, div.navpath {
|
||||
width: 100%;
|
||||
line-height: 140%;
|
||||
}
|
||||
|
||||
div.navtab {
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
/* @group Link Styling */
|
||||
|
||||
a {
|
||||
color: #153788;
|
||||
font-weight: normal;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.contents a:visited {
|
||||
color: #1b77c5;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
a.qindex {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
a.qindexHL {
|
||||
font-weight: bold;
|
||||
background-color: #6666cc;
|
||||
color: #ffffff;
|
||||
border: 1px double #9295C2;
|
||||
}
|
||||
|
||||
.contents a.qindexHL:visited {
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
a.el {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
a.elRef {
|
||||
}
|
||||
|
||||
a.code {
|
||||
color: #3030f0;
|
||||
}
|
||||
|
||||
a.codeRef {
|
||||
color: #3030f0;
|
||||
}
|
||||
|
||||
/* @end */
|
||||
|
||||
dl.el {
|
||||
margin-left: -1cm;
|
||||
.directory td.entry {
|
||||
font-weight: bold;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.fragment {
|
||||
font-family: monospace, fixed;
|
||||
font-size: 105%;
|
||||
white-space: pre;
|
||||
font: 14px/20px Roboto Mono,monospace;
|
||||
color: #37474f;
|
||||
background: #f7f7f7;
|
||||
margin: 16px 0;
|
||||
padding: 8px;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
pre.fragment {
|
||||
border: 1px solid #CCCCCC;
|
||||
background-color: #f5f5f5;
|
||||
padding: 4px 6px;
|
||||
margin: 4px 8px 4px 2px;
|
||||
overflow: auto;
|
||||
word-wrap: break-word;
|
||||
font-size: 9pt;
|
||||
line-height: 125%;
|
||||
}
|
||||
/* TOP OF CLASS PAGES */
|
||||
|
||||
div.ah {
|
||||
background-color: black;
|
||||
font-weight: bold;
|
||||
color: #ffffff;
|
||||
margin-bottom: 3px;
|
||||
margin-top: 3px
|
||||
div.summary {
|
||||
margin-top: -1em;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
div.groupHeader {
|
||||
margin-left: 16px;
|
||||
margin-top: 12px;
|
||||
margin-bottom: 6px;
|
||||
font-weight: bold;
|
||||
div.headertitle {
|
||||
display: none;
|
||||
}
|
||||
|
||||
div.groupText {
|
||||
margin-left: 16px;
|
||||
font-style: italic;
|
||||
div.textblock p {
|
||||
margin-bottom: 0.6em;
|
||||
}
|
||||
|
||||
body {
|
||||
background: white;
|
||||
color: black;
|
||||
margin-right: 20px;
|
||||
margin-left: 20px;
|
||||
}
|
||||
/* ALL TABLES */
|
||||
|
||||
td.indexkey {
|
||||
background-color: #F1F5F9;
|
||||
font-weight: bold;
|
||||
border: 1px solid #CCCCCC;
|
||||
margin: 2px 0px 2px 0;
|
||||
padding: 2px 10px;
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border: none;
|
||||
}
|
||||
|
||||
td.indexvalue {
|
||||
background-color: #F1F5F9;
|
||||
border: 1px solid #CCCCCC;
|
||||
padding: 2px 10px;
|
||||
margin: 2px 0px;
|
||||
table tr.heading {
|
||||
border: none;
|
||||
}
|
||||
|
||||
tr.memlist {
|
||||
background-color: #f0f0f0;
|
||||
table tr.heading td {
|
||||
border: none;
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
p.formulaDsp {
|
||||
text-align: center;
|
||||
table td.memSeparator {
|
||||
display: none;
|
||||
}
|
||||
|
||||
img.formulaDsp {
|
||||
|
||||
table td {
|
||||
border: none;
|
||||
}
|
||||
|
||||
img.formulaInl {
|
||||
vertical-align: middle;
|
||||
table {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
div.center {
|
||||
text-align: center;
|
||||
margin-top: 0px;
|
||||
margin-bottom: 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
div.center img {
|
||||
border: 0px;
|
||||
}
|
||||
/* CLASS PAGE - SUMMARY TABLES */
|
||||
|
||||
img.footer {
|
||||
border: 0px;
|
||||
vertical-align: middle;
|
||||
.groupheader {
|
||||
padding-left: 8px;
|
||||
}
|
||||
|
||||
/* @group Code Colorization */
|
||||
|
||||
span.keyword {
|
||||
color: #008000
|
||||
table td.memItemLeft {
|
||||
width: 10%;
|
||||
text-align: right;
|
||||
padding-top: 7px;
|
||||
padding-right: 3px;
|
||||
padding-bottom: 0;
|
||||
padding-left: 10px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
span.keywordtype {
|
||||
color: #604020
|
||||
table td.memItemRight {
|
||||
font-weight: bold;
|
||||
padding-top: 7px;
|
||||
padding-right: 3px;
|
||||
padding-bottom: 0;
|
||||
padding-left: 9px;
|
||||
}
|
||||
|
||||
span.keywordflow {
|
||||
color: #e08000
|
||||
table td.mdescLeft {
|
||||
padding-top: 0;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
span.comment {
|
||||
color: #800000
|
||||
table td.mdescRight {
|
||||
padding-left: 20px;
|
||||
padding-top: 0;
|
||||
padding-bottom: 6px;
|
||||
}
|
||||
|
||||
span.preprocessor {
|
||||
color: #806020
|
||||
table.memberdecls tr {
|
||||
border: none;
|
||||
}
|
||||
|
||||
span.stringliteral {
|
||||
color: #002080
|
||||
table.memberdecls h2 {
|
||||
font: 400 24px/32px Roboto,sans-serif;
|
||||
}
|
||||
|
||||
span.charliteral {
|
||||
color: #008080
|
||||
}
|
||||
|
||||
span.vhdldigit {
|
||||
color: #ff00ff
|
||||
}
|
||||
/* CLASS PAGE - DETAILED SECTION */
|
||||
|
||||
span.vhdlchar {
|
||||
color: #000000
|
||||
div.memproto {
|
||||
margin-top: 22px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
span.vhdlkeyword {
|
||||
color: #700070
|
||||
table.memname {
|
||||
border: none;
|
||||
}
|
||||
|
||||
span.vhdllogic {
|
||||
color: #ff0000
|
||||
table.memname tr {
|
||||
border: none;
|
||||
}
|
||||
|
||||
/* @end */
|
||||
|
||||
.search {
|
||||
color: #003399;
|
||||
font-weight: bold;
|
||||
table.memname td {
|
||||
font: 400 16px/24px Roboto,sans-serif;
|
||||
border: none;
|
||||
}
|
||||
|
||||
form.search {
|
||||
margin-bottom: 0px;
|
||||
margin-top: 0px;
|
||||
table.memname td.memname,
|
||||
table.memname td.paramkey {
|
||||
font-size: 17px;
|
||||
font-weight: bold;
|
||||
text-align: right;
|
||||
padding-top: 0px;
|
||||
padding-right: 0px;
|
||||
padding-bottom: 2px;
|
||||
white-space: nowrap;
|
||||
width: 85px;
|
||||
}
|
||||
|
||||
input.search {
|
||||
font-size: 75%;
|
||||
color: #000080;
|
||||
font-weight: normal;
|
||||
background-color: #F1F5F9;
|
||||
table.memname td.paramtype {
|
||||
padding-left: 0;
|
||||
padding-top: 0;
|
||||
width: 85px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
td.tiny {
|
||||
font-size: 75%;
|
||||
table.memname td.paramname {
|
||||
min-width: 170px;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.dirtab {
|
||||
padding: 4px;
|
||||
border-collapse: collapse;
|
||||
border: 1px solid #84b0c7;
|
||||
table.memname tr:first-child td.memname {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
th.dirtab {
|
||||
background: #F1F5F9;
|
||||
font-weight: bold;
|
||||
table.memname tr:first-child td.memname,
|
||||
table.memname tr:first-child td.paramtype,
|
||||
table.memname tr:first-child td.paramname {
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
hr {
|
||||
height: 0;
|
||||
border: none;
|
||||
border-top: 1px solid #666;
|
||||
div.memdoc p {
|
||||
margin-left: 35px;
|
||||
margin-bottom: 0.7em;
|
||||
}
|
||||
|
||||
/* @group Member Descriptions */
|
||||
|
||||
.mdescLeft, .mdescRight,
|
||||
.memItemLeft, .memItemRight,
|
||||
.memTemplItemLeft, .memTemplItemRight, .memTemplParams {
|
||||
background-color: #FAFAFA;
|
||||
border: none;
|
||||
margin: 4px;
|
||||
padding: 1px 0 0 8px;
|
||||
div.memdoc dl.since {
|
||||
margin-left: 35px;
|
||||
}
|
||||
|
||||
.mdescLeft, .mdescRight {
|
||||
padding: 0px 8px 4px 8px;
|
||||
color: #555;
|
||||
dl.since dt,
|
||||
dl.since dd {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.memItemLeft, .memItemRight, .memTemplParams {
|
||||
border-top: 1px solid #ccc;
|
||||
background-color: #F9F9F9;
|
||||
dl.deprecated {
|
||||
padding-left: 35px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.memItemLeft, .memTemplItemLeft {
|
||||
white-space: nowrap;
|
||||
dl.deprecated dt,
|
||||
dl.deprecated dd {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.memTemplParams {
|
||||
color: #606060;
|
||||
white-space: nowrap;
|
||||
dl.deprecated dd {
|
||||
padding-left: 12px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
/* @end */
|
||||
|
||||
/* @group Member Details */
|
||||
|
||||
/* Styles for detailed member documentation */
|
||||
|
||||
.memtemplate {
|
||||
font-size: 80%;
|
||||
color: #606060;
|
||||
font-weight: normal;
|
||||
margin-left: 3px;
|
||||
/* Make unneeded links black in detail tables */
|
||||
td.memname a.el,
|
||||
td.memname a:visited.el {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.memnav {
|
||||
background-color: #F1F5F9;
|
||||
border: 1px solid #84b0c7;
|
||||
text-align: center;
|
||||
margin: 2px;
|
||||
margin-right: 15px;
|
||||
padding: 2px;
|
||||
dl.params, dl.return {
|
||||
padding-left: 35px;
|
||||
}
|
||||
|
||||
.memitem {
|
||||
padding: 0;
|
||||
margin-bottom: 30px;
|
||||
dl.params dt, dl.return dt {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.memname {
|
||||
white-space: nowrap;
|
||||
font-weight: bold;
|
||||
color:#42657B;
|
||||
padding:3px 5px;
|
||||
dl.params dd, dl.return dd {
|
||||
padding-left: 0px;
|
||||
}
|
||||
|
||||
.memproto, .memdoc {
|
||||
border: 1px dotted #E0E0E0;
|
||||
}
|
||||
|
||||
.memproto {
|
||||
padding: 0;
|
||||
background-color: #F9F9F9;
|
||||
font-weight: bold;
|
||||
-webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
|
||||
-moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px;
|
||||
/* CLASS FILE - PROPERTY DETAILS */
|
||||
|
||||
td.mlabels-left td.memname {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.memdoc {
|
||||
padding: 2px 20px 20px;
|
||||
background-color: #FFFFFF;
|
||||
border-top-width: 0;
|
||||
-webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
|
||||
-moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px;
|
||||
table.memname {
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.paramkey {
|
||||
text-align: right;
|
||||
table.mlabels {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.paramtype {
|
||||
white-space: nowrap;
|
||||
table.mlabels, table.memname {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.paramname {
|
||||
color: #885656;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.paramname em {
|
||||
font-style: normal;
|
||||
table.mlabels tr {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
/* @end */
|
||||
|
||||
/* @group Directory (tree) */
|
||||
|
||||
/* for the tree view */
|
||||
|
||||
.ftvtree {
|
||||
font-family: sans-serif;
|
||||
margin: 0.5em;
|
||||
table.mlabels td.mlabels-left {
|
||||
font-size: 17px/24px;
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
width: 125px;
|
||||
}
|
||||
|
||||
/* these are for tree view when used as main index */
|
||||
|
||||
.directory {
|
||||
font-size: 9pt;
|
||||
font-weight: bold;
|
||||
table.mlabels td.mlabels-right {
|
||||
font-size: 17px/24px;
|
||||
margin-bottom: 0;
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
vertical-align: middle;
|
||||
width: 600px;
|
||||
}
|
||||
|
||||
.directory h3 {
|
||||
margin: 0px;
|
||||
margin-top: 1em;
|
||||
font-size: 11pt;
|
||||
}
|
||||
|
||||
/*
|
||||
The following two styles can be used to replace the root node title
|
||||
with an image of your choice. Simply uncomment the next two styles,
|
||||
specify the name of your image and be sure to set 'height' to the
|
||||
proper pixel height of your image.
|
||||
*/
|
||||
|
||||
/*
|
||||
.directory h3.swap {
|
||||
height: 61px;
|
||||
background-repeat: no-repeat;
|
||||
background-image: url("yourimage.gif");
|
||||
table.mlabels span.mlabel {
|
||||
padding-left: 2px;
|
||||
padding-right: 8px;
|
||||
}
|
||||
.directory h3.swap span {
|
||||
display: none;
|
||||
}
|
||||
*/
|
||||
|
||||
.directory > h3 {
|
||||
margin-top: 0;
|
||||
}
|
||||
/* OLD DESIGN COMPATIBILITY */
|
||||
|
||||
.directory p {
|
||||
margin: 0px;
|
||||
white-space: nowrap;
|
||||
body.docs table {
|
||||
border-collapse: collapse;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.directory div {
|
||||
display: none;
|
||||
margin: 0px;
|
||||
body.docs table tr.heading td {
|
||||
border: none;
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.directory img {
|
||||
vertical-align: -30%;
|
||||
body.docs table td.memSeparator {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* these are for tree view when not used as main index */
|
||||
|
||||
.directory-alt {
|
||||
font-size: 100%;
|
||||
font-weight: bold;
|
||||
body.docs table td {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.directory-alt h3 {
|
||||
margin: 0px;
|
||||
margin-top: 1em;
|
||||
font-size: 11pt;
|
||||
body.docs table {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.directory-alt > h3 {
|
||||
margin-top: 0;
|
||||
body.docs table td.memItemLeft {
|
||||
background-color: #F9FAFC;
|
||||
width: 10%;
|
||||
text-align: right;
|
||||
padding-top: 7px;
|
||||
padding-right: 3px;
|
||||
padding-bottom: 0;
|
||||
padding-left: 10px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.directory-alt p {
|
||||
margin: 0px;
|
||||
white-space: nowrap;
|
||||
body.docs table td.memItemRight {
|
||||
background-color: #F9FAFC;
|
||||
font-weight: bold;
|
||||
padding-top: 7px;
|
||||
padding-right: 3px;
|
||||
padding-bottom: 0;
|
||||
padding-left: 9px;
|
||||
}
|
||||
|
||||
.directory-alt div {
|
||||
display: none;
|
||||
margin: 0px;
|
||||
body.docs table td.mdescLeft {
|
||||
background-color: #F9FAFC;
|
||||
padding-top: 0;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
.directory-alt img {
|
||||
vertical-align: -30%;
|
||||
body.docs table td.mdescRight {
|
||||
background-color: #F9FAFC;
|
||||
padding-left: 20px;
|
||||
padding-top: 0;
|
||||
padding-bottom: 6px;
|
||||
}
|
||||
|
||||
/* @end */
|
||||
|
||||
address {
|
||||
font-style: normal;
|
||||
color: #333;
|
||||
body.docs table.memname {
|
||||
border: none;
|
||||
}
|
||||
|
||||
table.doxtable {
|
||||
border-collapse:collapse;
|
||||
body.docs table.memname td {
|
||||
background-color: #E2E8F2;
|
||||
border: none;
|
||||
}
|
||||
|
||||
table.doxtable td, table.doxtable th {
|
||||
border: 1px solid #153788;
|
||||
padding: 3px 7px 2px;
|
||||
body.docs table.memname td.memname,
|
||||
body.docs table.memname td.paramkey {
|
||||
font-weight: bold;
|
||||
text-align: right;
|
||||
padding-top: 0px;
|
||||
padding-right: 0px;
|
||||
padding-bottom: 2px;
|
||||
white-space: nowrap;
|
||||
width: 85px;
|
||||
}
|
||||
|
||||
table.doxtable th {
|
||||
background-color: #254798;
|
||||
color: #FFFFFF;
|
||||
font-size: 110%;
|
||||
padding-bottom: 4px;
|
||||
padding-top: 5px;
|
||||
text-align:left;
|
||||
body.docs table.memname td.paramtype {
|
||||
padding-left: 0;
|
||||
padding-top: 0px;
|
||||
padding-bottom: 2px;
|
||||
width: 85px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
|
||||
hr {
|
||||
border-top:1px dotted #E0E0E0;
|
||||
border-bottom:1px dotted #E0E0E0;
|
||||
margin-top:30px;
|
||||
padding-top:10px;
|
||||
body.docs table.memname td.paramname {
|
||||
min-width: 330px;
|
||||
padding-top: 0px;
|
||||
padding-bottom: 2px;
|
||||
}
|
||||
|
||||
.contents {
|
||||
padding-top: 30px;
|
||||
body.docs td.mlabels-left td.memname {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin-top:0;
|
||||
}
|
||||
.contents .dynsection {
|
||||
margin-top:10px;
|
||||
}
|
||||
/* END OF OLD DESIGN COMPATIBILITY */
|
||||
|
||||
@@ -1,408 +1,209 @@
|
||||
#! /usr/bin/python2.4
|
||||
#
|
||||
# Copyright 2010-2014 Google
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
# This here steaming pile of Python works as a Doxygen input filter which
|
||||
# automatically translates the C++ code with doxygen /// comments into
|
||||
# the format Doxygen wants, complete
|
||||
#!/usr/bin/python
|
||||
|
||||
"""Doxygen pre-filter script for ion.
|
||||
|
||||
This filter processes code and adds Doxygen-compatible markup in various places
|
||||
to enable Doxygen to read the docs more fully. Unlike some other Doxygen
|
||||
filters, it is designed to work with Doxygen's newer markdown syntax.
|
||||
|
||||
In order to ensure proper syntax coloring of indented code blocks, make sure
|
||||
there is a blank (commented) line both above and below the block. For example:
|
||||
|
||||
// Comment comment comment.
|
||||
//
|
||||
// int CodeBlock() {
|
||||
// Goes here;
|
||||
// }
|
||||
//
|
||||
// More comment.
|
||||
"""
|
||||
|
||||
|
||||
import re
|
||||
import sys
|
||||
|
||||
# Class which reads from an input file one line at a time and allows you to
|
||||
# match that line against regexes.
|
||||
class Reader:
|
||||
def __init__(self, file):
|
||||
self.file = file
|
||||
self.line = file.readline()
|
||||
|
||||
def Eof(self):
|
||||
return self.line == ""
|
||||
class DoxygenFormatter(object):
|
||||
"""Transforms lines of a source file to make them doxygen-friendly."""
|
||||
|
||||
def LookingAt(self, pattern):
|
||||
return re.match(pattern, self.line) != None
|
||||
ANYWHERE = 'anywhere'
|
||||
COMMENT = 'comment'
|
||||
|
||||
def ConsumeAndWrite(self, out):
|
||||
out.write(self.line)
|
||||
self.line = self.file.readline()
|
||||
def __init__(self, outfile):
|
||||
# The file-like object to which we will write lines.
|
||||
self.out = outfile
|
||||
|
||||
def Consume(self):
|
||||
line = self.line
|
||||
self.line = self.file.readline()
|
||||
# A buffer for storing empty lines which we can use later if we need to
|
||||
# retroactively insert markup without causing line number offset problems.
|
||||
self.empty_line_buffer = []
|
||||
|
||||
# Whether we are currently inside an indented code block.
|
||||
self.in_code_block = False
|
||||
|
||||
self.CompileExpressions()
|
||||
|
||||
def CompileExpressions(self):
|
||||
"""Pre-compiles frequently used regexps for improved performance.
|
||||
|
||||
The regexps are arranged as a list of 3-tuples, where the second value is
|
||||
the replacement string (which may include backreferences) and the third
|
||||
value is one of the context constants ANYWHERE or COMMENT. This is a list
|
||||
of tuples instead of a dictionary because order matters: earlier regexps
|
||||
will be applied first, and the resulting text (not the original) will be
|
||||
what is seen by subsequent regexps.
|
||||
"""
|
||||
self.comment_regex = re.compile(r'^\s*//')
|
||||
|
||||
self.substitutions = [
|
||||
# Remove copyright lines.
|
||||
(re.compile(r'^\s*//\s*[Cc]opyright.*Google.*'), r'', self.ANYWHERE),
|
||||
|
||||
# Remove any comment lines that consist of only punctuation (banners).
|
||||
# We only allow a maximum of two spaces before the punctuation so we
|
||||
# don't accidentally get rid of code examples with bare braces and
|
||||
# whatnot.
|
||||
(re.compile(r'(^\s*)//\s{0,2}[-=#/]+$'), r'\1//\n', self.ANYWHERE),
|
||||
|
||||
# If we find something that looks like a list item that is indented four
|
||||
# or more spaces, pull it back to the left so doxygen's Markdown engine
|
||||
# doesn't treat it like a code block.
|
||||
(re.compile(r'(^\s*)//\s{4,}([-\d*].*)'), r'\1 \2', self.COMMENT),
|
||||
|
||||
# Replace TODO(someone) in a comment with @todo (someone)
|
||||
(re.compile(r'TODO'), r'@todo ', self.COMMENT),
|
||||
|
||||
# Replace leading 'Note:' or 'Note that' in a comment with @note
|
||||
(re.compile(r'(\/\/\s+)Note(?:\:| that)', re.I), r'\1@note',
|
||||
self.COMMENT),
|
||||
|
||||
# Replace leading 'Warning:' in a comment with @warning
|
||||
(re.compile(r'(\/\/\s+)Warning:', re.I), r'\1@warning', self.COMMENT),
|
||||
|
||||
# Replace leading 'Deprecated' in a comment with @deprecated
|
||||
(re.compile(r'(\/\/\s+)Deprecated[^\w\s]*', re.I), r'\1@deprecated',
|
||||
self.COMMENT),
|
||||
|
||||
# Replace pipe-delimited parameter names with backtick-delimiters
|
||||
(re.compile(r'\|(\w+)\|'), r'`\1`', self.COMMENT),
|
||||
|
||||
# Convert standalone comment lines to Doxygen style.
|
||||
(re.compile(r'(^\s*)//(?=[^/])'), r'\1///', self.ANYWHERE),
|
||||
|
||||
# Strip trailing comments from preprocessor directives.
|
||||
(re.compile(r'(^#.*)//.*'), r'\1', self.ANYWHERE),
|
||||
|
||||
# Convert remaining trailing comments to doxygen style, unless they are
|
||||
# documenting the end of a block.
|
||||
(re.compile(r'([^} ]\s+)//(?=[^/])'), r'\1///<', self.ANYWHERE),
|
||||
]
|
||||
|
||||
def Transform(self, line):
|
||||
"""Performs the regexp transformations defined by self.substitutions.
|
||||
|
||||
Args:
|
||||
line: The line to transform.
|
||||
|
||||
Returns:
|
||||
The resulting line.
|
||||
"""
|
||||
for (regex, repl, where) in self.substitutions:
|
||||
if where is self.COMMENT and not self.comment_regex.match(line):
|
||||
return line
|
||||
line = regex.sub(repl, line)
|
||||
return line
|
||||
|
||||
def GetIndent(self):
|
||||
return re.match(" *", self.line).end()
|
||||
def AppendToBufferedLine(self, text):
|
||||
"""Appends text to the last buffered empty line.
|
||||
|
||||
# If we insert additional lines into the output, we will want to remove lines
|
||||
# somewhere else so that definitions generally appear on the line number they
|
||||
# were on originally. Otherwise, when Doxygen links into the orignial headers,
|
||||
# it links to the wrong line numbers. "offset" counts the number of lines we
|
||||
# need to make up.
|
||||
class OffsetTrackingFile:
|
||||
def __init__(self, file):
|
||||
self.file = file
|
||||
self.offset = 0
|
||||
def write(self, text):
|
||||
self.file.write(text)
|
||||
def writelines(self, lines):
|
||||
self.file.writelines(lines)
|
||||
Empty lines are buffered rather than being written out directly. This lets
|
||||
us retroactively rewrite buffered lines to include markup that affects the
|
||||
following line, while avoiding the line number offset that would result from
|
||||
inserting a line that wasn't in the original source.
|
||||
|
||||
# This class keeps tracks of what member groups we've opened, so that we can
|
||||
# write their end tags later on. Doxygen does not allow nested groups, though
|
||||
# nested classes can have their own groups. Thus, we can keep track of groups
|
||||
# according to their indentation levels.
|
||||
class GroupTracker:
|
||||
def __init__(self):
|
||||
self.levels = []
|
||||
Args:
|
||||
text: The text to append to the line.
|
||||
|
||||
# Start a new group indented by the given number of spaces.
|
||||
def StartGroup(self, indent, out):
|
||||
self.EndGroupsDeeperThan(indent - 1, out)
|
||||
out.write(" " * indent + "/// @{\n")
|
||||
out.offset += 1
|
||||
self.levels.append(indent)
|
||||
|
||||
# Write end tags for all open groups who are indented more than the given
|
||||
# number of spaces.
|
||||
def EndGroupsDeeperThan(self, indent, out):
|
||||
while self.levels and self.levels[-1] > indent:
|
||||
out.write(" " * self.levels[-1] + "/// @}\n")
|
||||
out.offset += 1
|
||||
self.levels.pop()
|
||||
|
||||
# Converts a regular comment block into a Doxygen-format comment block and
|
||||
# writes it to the output.
|
||||
#
|
||||
# Other than converting all the "//"s to "///"s, we also try to detect code
|
||||
# fragments embedded inside comments. Throughout the comments in net/proto2,
|
||||
# such fragments are always indented two spaces, e.g. like this:
|
||||
# // Here is a code fragment:
|
||||
# // int foo = Foo();
|
||||
# // // A comment within the code fragment.
|
||||
# // Bar(foo);
|
||||
# // That was a code fragment!
|
||||
# We try to detect this and put the fragment in a @code block so that Doxygen
|
||||
# will format it nicely. However, not everything which is indented is a code
|
||||
# block. Another common case is lists, which look like:
|
||||
# // Here is a list:
|
||||
# // * List item 1.
|
||||
# // This is still part of list item 1.
|
||||
# // Notice the indent.
|
||||
# // * List item 2.
|
||||
# // The list is over now.
|
||||
# So, we want to detect lists and *not* interpret them as code.
|
||||
def FormatDocComment(comment, out):
|
||||
min_indent_for_code = 3
|
||||
in_code = False
|
||||
empty_lines = []
|
||||
for line in comment:
|
||||
# Doxygen gets confused when it sees "*/" inside a // comment and silently
|
||||
# fails to parse anything in the file. Thanks, Doxygen.
|
||||
line = line.replace("*/", "* /")
|
||||
|
||||
# Separate the comment text from the pre-comment indent.
|
||||
(outer_indent, content) = line.split("//", 1)
|
||||
if content.strip() == "":
|
||||
# The line was empty. Buffer it for now.
|
||||
empty_lines.append(outer_indent + "///" + content)
|
||||
continue
|
||||
|
||||
# How many spaces is this line indented *after* the comment start? E.g.
|
||||
# the line " // foo" has a two-space outer indent and a one-space
|
||||
# inner_indent.
|
||||
inner_indent = re.match(" *", content).end()
|
||||
|
||||
if inner_indent >= min_indent_for_code:
|
||||
# Content is indented enough to be a code fragment.
|
||||
if not in_code:
|
||||
# Begin a code block.
|
||||
# Flush empty lines first.
|
||||
out.writelines(empty_lines)
|
||||
empty_lines = []
|
||||
out.write("%s///%s@code\n" %
|
||||
(outer_indent, " " * (min_indent_for_code - 2)))
|
||||
out.offset += 1
|
||||
in_code = True
|
||||
|
||||
# Doxygen takes all the raw bytes between @code and @encode and copies
|
||||
# them directly into the final web page. It does not look for newlines
|
||||
# in this range at all. So, if you have something reasonable like:
|
||||
# /// @code
|
||||
# /// int foo = 1;
|
||||
# /// @endcode
|
||||
# Your code fragment ends up being:
|
||||
# /// int foo = 1;
|
||||
# ///
|
||||
# That is, it includes the stupid "///"s, which obviously aren't supposed
|
||||
# to be part of the fragment. Instead, you have to do:
|
||||
# /// @code
|
||||
# int foo = 1;
|
||||
# @endcode
|
||||
# Which is, of course, totally invalid C++. But luckily we don't need
|
||||
# this to compile as C++. We just need Doxygen to read it.
|
||||
#
|
||||
# Before you ask, yes, I tried doing this:
|
||||
# /** @code
|
||||
# int foo = 1;
|
||||
# @endcode */
|
||||
# For whatever reason, Doxygen didn't like it.
|
||||
out.write("\n" * len(empty_lines))
|
||||
empty_lines = []
|
||||
out.write(content[min_indent_for_code:])
|
||||
Returns:
|
||||
True if there was an available empty line to which text could be
|
||||
appended, and False otherwise.
|
||||
"""
|
||||
if self.empty_line_buffer:
|
||||
last_line = self.empty_line_buffer.pop().rstrip()
|
||||
last_line += text + '\n'
|
||||
self.empty_line_buffer.append(last_line)
|
||||
return True
|
||||
else:
|
||||
if in_code:
|
||||
# End a code block. Do not flush empty lines; we don't want to
|
||||
# include them in the block.
|
||||
out.write("@endcode\n")
|
||||
out.offset += 1
|
||||
in_code = False
|
||||
return False
|
||||
|
||||
# Replace '*' bullet style with '-', since Doxygen only recognizes the
|
||||
# latter.
|
||||
content = re.sub("^( +)[*] ", "\\1- ", content)
|
||||
def ConvertCodeBlock(self, line):
|
||||
"""Converts any code block that may begin or end on this line.
|
||||
|
||||
if re.match(" +- ", content):
|
||||
# This line starts a bullet list. Subsequent lines will be indented,
|
||||
# but should not be code.
|
||||
min_indent_for_code = inner_indent + 4
|
||||
elif re.match(".*\\w.*:.*\\w.*$", content):
|
||||
# This line starts a note. Subsequent lines will be indented, but
|
||||
# should not be code.
|
||||
#
|
||||
# Note: "Note" comments look like this. They start with a word
|
||||
# followed by a colon (e.g. "Note:", "TODO(kenton):", etc.). A
|
||||
# line which merely ends with a colon, however, should *not* be
|
||||
# considered a note, because indented code blocks are often
|
||||
# preceeded by such lines.
|
||||
min_indent_for_code = inner_indent + 4
|
||||
else:
|
||||
# Nothing special here. If the next line is indented then we will
|
||||
# put it in a code block.
|
||||
min_indent_for_code = inner_indent + 2
|
||||
Doxygen has (at least) two kinds of code blocks. Any block indented at
|
||||
least four spaces gets formatted as code, but (for some reason) no syntax
|
||||
highlighting is applied. Any block surrounded by "~~~" on both sides is
|
||||
also treated as code, but these are syntax highlighted intelligently
|
||||
depending on the file type. We typically write code blocks in the former
|
||||
style, but we'd like them to be highlighted, so this function converts them
|
||||
to the latter style by adding in the ~~~ lines.
|
||||
|
||||
out.writelines(empty_lines)
|
||||
empty_lines = []
|
||||
out.write(outer_indent + "///" + content)
|
||||
To make this a bit more complicated, we would really prefer not to insert
|
||||
new lines into the file, since that will make the line numbers shown in
|
||||
doxygen not match the line numbers in the actual source code. For this
|
||||
reason, we only perform the conversion if at least one "blank" line (empty
|
||||
comment line) appears before the start of the code block. If we get down to
|
||||
the bottom of the block and there's no blank line after it, we will be
|
||||
forced to add a line, since we can't go back and undo what we already did.
|
||||
|
||||
if in_code:
|
||||
# End a code block. Do not flush empty lines; we don't want to
|
||||
# include them in the block.
|
||||
out.write("@endcode\n")
|
||||
out.offset += 1
|
||||
# Now flush empty lines.
|
||||
out.writelines(empty_lines)
|
||||
Args:
|
||||
line: The line to process.
|
||||
|
||||
# Reads a comment block. Returns a list of lines.
|
||||
def ReadComment(reader):
|
||||
assert reader.LookingAt(" *//")
|
||||
comment = []
|
||||
while (reader.LookingAt(" *//") or
|
||||
reader.LookingAt("#ifndef PROTO2_OPENSOURCE") or
|
||||
reader.LookingAt("#endif // !PROTO2_OPENSOURCE")):
|
||||
if reader.LookingAt(" *//"):
|
||||
comment.append(reader.Consume())
|
||||
Returns:
|
||||
The converted line.
|
||||
"""
|
||||
if not self.in_code_block and re.match(r'\s*///\s{4,}', line):
|
||||
if self.AppendToBufferedLine(' ~~~'):
|
||||
# If this fails, we'll just leave it un-highlighted.
|
||||
self.in_code_block = True
|
||||
elif self.in_code_block and not re.match(r'\s*///\s{4,}', line):
|
||||
if not self.AppendToBufferedLine(' ~~~'):
|
||||
# This is bad. We don't have a buffered line to use to end the code
|
||||
# block, so we'll have to insert one. This will cause the line
|
||||
# numbers to stop matching the original source, unfortunately.
|
||||
line = '/// ~~~\n' + line
|
||||
self.in_code_block = False
|
||||
return line
|
||||
|
||||
def ProcessLine(self, line):
|
||||
"""Processes a line.
|
||||
|
||||
If the line is an empty line inside a comment, we buffer it for possible
|
||||
rewriting later on. Otherwise, we transform it using our regexps and
|
||||
write it (as well as any buffered blank lines) out to the output.
|
||||
|
||||
Args:
|
||||
line: The line to process.
|
||||
"""
|
||||
line = self.Transform(line)
|
||||
|
||||
if line.strip() == '///':
|
||||
# We may repurpose this empty line later, so don't write it out yet.
|
||||
self.empty_line_buffer.append(line)
|
||||
else:
|
||||
# Replace PROTO2_OPENSOURCE ifdef with a blank comment line. These
|
||||
# ifdefs are used to hide google-internal parts of doc comments from
|
||||
# the open source release. The directives will actually be stripped
|
||||
# entirely from the released code, so if we're seeing them, then we
|
||||
# must be running against the internal code. This means we should
|
||||
# include the comments they are guarding. We replace it with a
|
||||
# blank comment that is indented equally to the previous comment line.
|
||||
comment.append(" " * comment[-1].index("//") + "//\n")
|
||||
reader.Consume()
|
||||
return comment
|
||||
line = self.ConvertCodeBlock(line)
|
||||
# Flush the line buffer and write this line as well.
|
||||
for buffered_line in self.empty_line_buffer:
|
||||
self.out.write(buffered_line)
|
||||
self.empty_line_buffer = []
|
||||
self.out.write(line)
|
||||
|
||||
# Reads a comment block and writes it to the output. If the comment appears to
|
||||
# be documenting something, translates it to Doxygen format in the process.
|
||||
def HandleComment(reader, out, group_tracker):
|
||||
if reader.Eof(): return
|
||||
|
||||
comment = ReadComment(reader)
|
||||
def main(argv):
|
||||
sourcefile = argv[1]
|
||||
with open(sourcefile, 'r') as infile:
|
||||
formatter = DoxygenFormatter(sys.stdout)
|
||||
for line in infile:
|
||||
formatter.ProcessLine(line)
|
||||
|
||||
# Figure out what to do with it.
|
||||
if ((comment[0].count("----") > 0 or comment[0].count("====") > 0) and
|
||||
comment[0].startswith(" ")):
|
||||
# The comment is a divider. Put everything under it into a group.
|
||||
group_tracker.StartGroup(comment[0].index("//"), out)
|
||||
|
||||
# Remove the -'s and ='s.
|
||||
comment[0] = comment[0].rstrip(" -=\r\n") + "\n";
|
||||
if comment[0] == "//":
|
||||
# The first line is entirely composed of -'s or ='s. Remove it.
|
||||
comment = comment[1:]
|
||||
# We know the offset is at least 1 from the StartGroup() call, so we
|
||||
# should be able to decrement it.
|
||||
assert out.offset > 0
|
||||
out.offset -= 1
|
||||
else:
|
||||
comment[0] = comment[0].replace("//", "// @name")
|
||||
|
||||
# If the comment is non-empty, we want to write it even if it is not
|
||||
# followed by any content, since it documents the group.
|
||||
if comment:
|
||||
FormatDocComment(comment, out)
|
||||
# We need to ensure there is a blank line here so that the group's
|
||||
# doc comment doesn't run up against the doc comment for the first thing
|
||||
# in it.
|
||||
out.write("\n")
|
||||
out.offset += 1
|
||||
elif (# A line with alphanumeric characters is considered to be content.
|
||||
reader.LookingAt(".*\\w.*") and
|
||||
# Unless all the characters are in a comment.
|
||||
not reader.LookingAt("\\W*//") and
|
||||
# Also, class forward-declarations, namespace decls, and preprocessor
|
||||
# directives should not be documented.
|
||||
not reader.LookingAt(" *class +\\w+ *;") and
|
||||
not reader.LookingAt(" *namespace +\\w+ *{") and
|
||||
not reader.LookingAt(" *#") and
|
||||
# And neither should inline method definitions declared outside
|
||||
# the class definition.
|
||||
not reader.LookingAt("[^ ].*\w+::\w+ *\\(\\)")):
|
||||
# Line contains content. Transform the comment into a doc comment and
|
||||
# write it.
|
||||
if reader.LookingAt(".*typedef"):
|
||||
# If a group contains a typedef, Doxygen annoyingly places that group
|
||||
# above all other groups, rather than placing it in declaration order
|
||||
# like normal. So, don't let typedefs be in groups.
|
||||
group_tracker.EndGroupsDeeperThan(reader.GetIndent() - 1, out)
|
||||
FormatDocComment(comment, out)
|
||||
else:
|
||||
# No content. The comment is not a doc comment. Just write it. But try
|
||||
# to make up some offset lines while we're here.
|
||||
if out.offset >= len(comment):
|
||||
# The comment is shorter than the offset, so don't write it at all.
|
||||
out.offset -= len(comment)
|
||||
else:
|
||||
out.writelines(comment[out.offset:])
|
||||
out.offset = 0
|
||||
|
||||
# Skips code lines until a comment block is encountered.
|
||||
def FindNextComment(reader, out, group_tracker):
|
||||
while not reader.LookingAt(" *//") and not reader.Eof():
|
||||
if (reader.LookingAt(".*[^ \n].*$") and
|
||||
not reader.LookingAt(" *#")):
|
||||
# This line containts some sort of content. End any groups which had
|
||||
# deeper indentation levels than this line.
|
||||
group_tracker.EndGroupsDeeperThan(reader.GetIndent(), out)
|
||||
|
||||
# By default, Doxygen puts class members into implicit groups like
|
||||
# "Public Member Functions" and "Public Fields". This script sometimes
|
||||
# produces explicit groups as well, in order to improve organization.
|
||||
# Unfortunately, Doxygen does not handle things very well when some things
|
||||
# are explicitly grouped and some aren't. In particular:
|
||||
# * If the SUBGROUPING option is on, then the explicit groups will be
|
||||
# nested within the implicit ones, but *only if* all members of the group
|
||||
# belong in the same implicit group (e.g. they are all methods, or all
|
||||
# fields, etc.). If you make an explicit group that crosses multiple
|
||||
# implicit groups, the explicit group becomes a top-level group and
|
||||
# sits along side the implicit ones. This is really confusing, because
|
||||
# it makes it look like these groups are different from the ones that
|
||||
# are nested.
|
||||
# * If the SUBGROUPING option is off, then explicit groups always appear
|
||||
# as peers to the implicit ones. Unfortunately, the explicit groups
|
||||
# seem to appear *above* the implicit ones, even if the members in the
|
||||
# implicit group are all defined before the explicit group.
|
||||
# Unfortunately, methods which are not in any particular group are almost
|
||||
# always more important than methods that are in groups, and thus
|
||||
# should appear first.
|
||||
# The only way we can solve both of these problems without giving up on
|
||||
# groups altogether is to force *all* members to be in explicit groups.
|
||||
# So, we start a group called "General Members" immediately after the
|
||||
# "public:" line to pick up ungrouped stuff.
|
||||
is_public_line = False
|
||||
public_line_indent = 0
|
||||
if reader.LookingAt(" *public:"):
|
||||
is_public_line = True
|
||||
public_line_indent = reader.GetIndent() + 1
|
||||
|
||||
if (reader.LookingAt(".*\\w.*//") and
|
||||
not reader.LookingAt(" *namespace ") and
|
||||
not reader.LookingAt(" *class +\\w+ *;") and
|
||||
not reader.LookingAt(" *#")):
|
||||
# This line has some content followed by a line comment, e.g.:
|
||||
# FOO, // The FOO enum value.
|
||||
# We want to convert the comment into a post-declaration comment, like:
|
||||
# FOO, ///< The FOO enum value.
|
||||
line = reader.Consume()
|
||||
out.write(line.replace("//", "///<", 1))
|
||||
# If subsequent lines have comments that are lined up with this one
|
||||
# and only whitespace before those comments, they must be part of this
|
||||
# comment.
|
||||
indent = line.index("//")
|
||||
while reader.LookingAt(" " * indent + "//"):
|
||||
out.write(reader.Consume().replace("//", "///<", 1))
|
||||
elif reader.LookingAt(".*ATTRIBUTE_ALWAYS_INLINE"):
|
||||
# Hide this from Doxygen. Otherwise it actually documents its presence,
|
||||
# which looks confusing.
|
||||
out.write(reader.Consume().replace("ATTRIBUTE_ALWAYS_INLINE", ""))
|
||||
elif out.offset > 0 and reader.LookingAt(" *$"):
|
||||
# Skip empty line to make up an offset line.
|
||||
out.offset -= 1
|
||||
reader.Consume()
|
||||
else:
|
||||
# Normal line; just print it.
|
||||
reader.ConsumeAndWrite(out)
|
||||
|
||||
# See the monstrous comment earlier in this function.
|
||||
if is_public_line:
|
||||
group_tracker.StartGroup(public_line_indent, out)
|
||||
out.write(" " * public_line_indent + "/// @name General Members\n\n")
|
||||
out.offset += 2
|
||||
|
||||
# Read the entire file and convert it to Doxygen format.
|
||||
def HandleFile(reader, out):
|
||||
out = OffsetTrackingFile(out)
|
||||
|
||||
if reader.LookingAt(".*[cC]opyright.*"):
|
||||
# Skip copyright comment.
|
||||
while reader.LookingAt("//..+$"):
|
||||
reader.ConsumeAndWrite(out)
|
||||
# Skip blank lines after copyright.
|
||||
while reader.LookingAt("//$"):
|
||||
reader.ConsumeAndWrite(out)
|
||||
|
||||
# Read the file-level docs.
|
||||
file_comment = []
|
||||
if (reader.LookingAt("//")):
|
||||
file_comment = ReadComment(reader)
|
||||
|
||||
# Write the file-level docs as a Doxygen comment. Even if the file had no
|
||||
# top-level comment, we want to write an empty Doxygen file comment.
|
||||
# Otherwise, Doxygen will not generate a page listing the contents of this
|
||||
# file, even if the contents are themselves documented. Silly Doxygen.
|
||||
out.write("/// @file\n")
|
||||
out.offset += 1
|
||||
if file_comment:
|
||||
FormatDocComment(file_comment, out)
|
||||
|
||||
# Loop through the rest of the file.
|
||||
group_tracker = GroupTracker()
|
||||
while not reader.Eof():
|
||||
FindNextComment(reader, out, group_tracker)
|
||||
HandleComment(reader, out, group_tracker)
|
||||
|
||||
# Doxygen expects an input filter to take the source file name as a
|
||||
# command-line argument and write the filtered text to stdout.
|
||||
if len(sys.argv) == 1:
|
||||
# No arguments given. Read from stdin. Useful for debugging.
|
||||
HandleFile(Reader(sys.stdin), sys.stdout)
|
||||
else:
|
||||
for filename in sys.argv[1:]:
|
||||
f = file(filename, "r")
|
||||
try:
|
||||
HandleFile(Reader(f), sys.stdout)
|
||||
finally:
|
||||
f.close()
|
||||
if __name__ == '__main__':
|
||||
main(sys.argv)
|
||||
|
||||
2511
tools/ortools.doxy
Normal file
2511
tools/ortools.doxy
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user