Exhale Utils Module

exhale.utils.AVAILABLE_KINDS = ['class', 'define', 'dir', 'enum', 'enumvalue', 'file', 'function', 'group', 'namespace', 'struct', 'typedef', 'union', 'variable', 'page']

All potential input kind values coming from Doxygen.

The "group" and "enumvalue" kinds are currently detected, but unused.

exhale.utils.LEAF_LIKE_KINDS = ['define', 'enum', 'function', 'class', 'struct', 'typedef', 'union', 'variable']

All kinds that can be generated using ExhaleRoot.generateSingleNodeRST.

This more or less corresponds to the kinds that Exhale uses a Breathe directive. This is everything in AVAILABLE_KINDS, except for

  • "enumvalue" and "group" (unused in framework), and

  • "dir", "file", and "namespace" since they require special treatment.

exhale.utils.contentsDirectiveOrNone(kind)[source]

Generates a string .. contents:: directives according to the rules outlined in the Using Contents Directives section.

Parameters
kind (str)

The kind of the compound (one of AVAILABLE_KINDS).

Return
str or None

If this kind should have a .. contents:: directive, it returns the string that can be written to file. Otherwise, None is returned.

Breathe Customization Support

exhale.utils.makeCustomSpecificationsMapping(func)[source]

Creates the “pickleable” dictionary that will be used with customSpecificationsMapping supplied to exhale_args in your conf.py.

Parameters
func (types.FunctionType)

A callable function that takes as input a string from AVAILABLE_KINDS and returns a list of strings.

The empty list [] indicates to use the Breathe defaults.

Return
dict

A dictionary where the keys are every value in AVAILABLE_KINDS, and the values are the list returns of the input func.

Note

To help ensure the dictionary has everything it needs for the rest of Exhale to function, a “secret” key-value pair is inserted to the returned dictionary.

Unsorted Misc

Todo

cleanup / reorder these

exhale.utils.heading_mark(title, char)[source]

Given an input title and character, creates the reStructuredText underline according to the length of the title.

Parameters
title (str)

The title that is being underlined, length assumed to be >= 1.

char (str)

The single character being used for this heading, e.g. SECTION_HEADING_CHAR.

Return
str

Returns len(title) * char.

exhale.utils.nodeCompoundXMLContents(node)[source]
exhale.utils.qualifyKind(kind)[source]

Qualifies the breathe kind and returns an qualifier string describing this to be used for the text output (e.g. in generated file headings and link names).

The output for a given kind is as follows:

Input Kind

Output Qualifier

“class”

“Class”

“define”

“Define”

“enum”

“Enum”

“enumvalue”

“Enumvalue”

“file”

“File”

“function”

“Function”

“group”

“Group”

“namespace”

“Namespace”

“struct”

“Struct”

“typedef”

“Typedef”

“union”

“Union”

“variable”

“Variable”

The following breathe kinds are ignored:

  • “autodoxygenfile”

  • “doxygenindex”

  • “autodoxygenindex”

Note also that although a return value is generated, neither “enumvalue” nor “group” are actually used.

Parameters
kind (str)

The return value of a Breathe compound object’s get_kind() method.

Return (str)

The qualifying string that will be used to build the reStructuredText titles and other qualifying names. If the empty string is returned then it was not recognized.

exhale.utils.kindAsBreatheDirective(kind)[source]

Returns the appropriate breathe restructured text directive for the specified kind. The output for a given kind is as follows:

Input Kind

Output Directive

“class”

“doxygenclass”

“define”

“doxygendefine”

“enum”

“doxygenenum”

“enumvalue”

“doxygenenumvalue”

“file”

“doxygenfile”

“function”

“doxygenfunction”

“group”

“doxygengroup”

“namespace”

“doxygennamespace”

“struct”

“doxygenstruct”

“typedef”

“doxygentypedef”

“union”

“doxygenunion”

“variable”

“doxygenvariable”

“page”

“doxygenpage”

The following breathe kinds are ignored:

  • “autodoxygenfile”

  • “doxygenindex”

  • “autodoxygenindex”

Note also that although a return value is generated, neither “enumvalue” nor “group” are actually used.

Parameters
kind (str)

The kind of the breathe compound / ExhaleNode object (same values).

Return (str)

The directive to be used for the given kind. The empty string is returned for both unrecognized and ignored input values.

exhale.utils.specificationsForKind(kind)[source]

Todo

update docs for new list version rather than string returns

class exhale.utils.AnsiColors[source]

A simple wrapper class for convenience definitions of common ANSI formats to enable colorizing output in various formats. The definitions below only affect the foreground color of the text, but you can easily change the background color too. See ANSI color codes for a concise overview of how to use the ANSI color codes.

exhale.utils.indent(text, prefix, predicate=None)[source]

This is a direct copy of textwrap.indent for availability in Python 2.

Their documentation:

Adds ‘prefix’ to the beginning of selected lines in ‘text’. If ‘predicate’ is provided, ‘prefix’ will only be added to the lines where ‘predicate(line)’ is True. If ‘predicate’ is not provided, it will default to adding ‘prefix’ to all non-empty lines that do not consist solely of whitespace characters.

exhale.utils.prefix(token, msg)[source]

Wrapper call to indent() with an always-true predicate so that empty lines (e.g. n) still get indented by the token.

Parameters
token (str)

What to indent the message by (e.g. "(!) ").

msg (str)

The message to get indented by token.

Return
str

The message msg, indented by the token.

exhale.utils.exclaim(err_msg)[source]
exhale.utils.colorize(msg, ansi_fmt)[source]
exhale.utils._use_color(msg, ansi_fmt, output_stream)[source]

Based on alwaysColorize, returns the colorized or non-colorized output when output_stream is not a TTY (e.g. redirecting to a file).

Parameters
msg (str)

The message that is going to be printed by the caller of this method.

ansi_fmt (str)

The ANSI color format to use when coloring is supposed to happen.

output_stream (file)

Assumed to be either sys.stdout or sys.stderr.

Return
str

The message msg in color, or not, depending on both alwaysColorize and whether or not the output_stream is a TTY.

exhale.utils.progress(msg, ansi_fmt='32;1m', output_stream=<_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>)[source]
exhale.utils.info(msg, ansi_fmt='34;1m', output_stream=<_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>)[source]
exhale.utils.critical(msg, ansi_fmt='31;1m', output_stream=<_io.TextIOWrapper name='<stderr>' mode='w' encoding='utf-8'>)[source]
exhale.utils.verbose_log(msg, ansi_fmt=None)[source]
exhale.utils.__fancy(text, language, fmt)[source]
exhale.utils.fancyErrorString(lex)[source]
exhale.utils.fancyError(critical_msg=None, lex='py3tb', singleton_hook=None)[source]
exhale.utils.LANG_TO_LEX = {'C': 'c', 'C#': 'csharp', 'C++': 'cpp', 'D': 'd', 'Fortran': 'fortran', 'FortranFixed': 'fortranfixed', 'FortranFree': 'fortran', 'IDL': 'idl', 'Java': 'java', 'Javascript': 'js', 'Markdown': 'markdown', 'Objecive-C': 'objective-c', 'PHP': 'php', 'Python': 'py', 'VHDL': 'vhdl', 'Verilog': 'verilog'}
LANG_TO_LEX = {
    "IDL":          "idl",
    "Java":         "java",
    "Javascript":   "js",
    "C#":           "csharp",
    "C":            "c",
    "C++":          "cpp",
    "D":            "d",
    "PHP":          "php",
    "Objecive-C":   "objective-c",
    "Python":       "py",
    "Fortran":      "fortran",
    "FortranFree":  "fortran",
    "FortranFixed": "fortranfixed",
    "VHDL":         "vhdl",
    "Verilog":      "verilog",
    "Markdown":     "markdown"
}

Mapping of language="xxx" from the Doxygen programlisting to Pygments Lexers. This mapping is used in doxygenLanguageToPygmentsLexer().

From the Doxygen documentation on EXTENSION_MAPPING:

IDL, Java, Javascript, C#, C, C++, D, PHP, Objective-C, Python,Fortran (fixed format Fortran: FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran: Fortran. In the later case the parser tries to guess whether the code is fixed or free formatted code, this is the default for Fortran type files), VHDL.

We need to take each one of those, and map them to their corresponding Pygments Lexer.

Note

Feel free to make a pull request adding more lanugages here. For example, the Verilog support comes from doxygen-verilog.

exhale.utils.doxygenLanguageToPygmentsLexer(location, language)[source]

Given an input location and language specification, acquire the Pygments lexer to use for this file.

  1. If configs.lexerMapping has been specified, then configs._compiled_lexer_mapping will be queried first using the location parameter.

  2. If no matching was found, then the appropriate lexer defined in LANG_TO_LEX is used.

  3. If no matching language is found, "none" is returned (indicating to Pygments that no syntax highlighting should occur).

exhale.utils.sanitize(name)[source]

Sanitize the specified name for use with breathe directives.

Parameters

name (str)

The name to be sanitized.

Return

str

The input name sanitized to use with breathe directives (primarily for use with .. doxygenfunction::). Replacements such as "&lt;" -> "<" are performed, as well as removing spaces "< " -> "<" must be done. Breathe is particularly sensitive with respect to whitespace.

exhale.utils.sanitize_all(names)[source]

Convenience function to sanitize() all provided names.

Parameters
names (list of str)

A list of strings to sanitize.

Return
list of str

Each name in names sanitized: [sanitize(n) for n in names].

Template Parsing

exhale.utils.tokenize_template(node_name: str) list[typing.Union[list, str]][source]

Transform node_name into a list representing the templates.

Note

This method may not support all C++ templates, it is only used in exhale to parse when templates occur in the doxygen name. This happens with template structs / classes and specializations.

In order to represent templates (and nested templates), any < template > is tokenized to create a nested list of template parameters (and remove the < and > characters). Some examples:

Input node_name

Returned Tokens

""

[]

"foo"

["foo"]

Depth 1

"foo< 12 >"

["foo", ["12"]]

"ns::foo< int, 66 >"

["ns::foo", ["int", "66"]]

Depth 2

"foo< std::array< int > >"

["foo", ["std::array", ["int"]]]

"bar< Cls< x, y, z > >"

["bar", ["Cls", ["x", "y", "z"]]]

Depth 3

"rawr< A< B< C > > >"

["rawr", ["A", ["B", ["C"]]]]

The function will transform any duplicate whitespace to a single space in the final output, as well as remove any leading or trailing whitespace for a given token. To transform back to a string, use join_template_tokens().

Parameters

node_name (str)

The name of the node to tokenize. It is assumed that this is valid C++, if it is not the results are undefined.

exhale.utils.join_template_tokens(tokens: list[typing.Union[list, str]]) str[source]

Return a C++ type using the output from tokenize_template().

Note

The original input to tokenize_template() and the return of this function are not guaranteed to be equivalent. Whitespace variations will occur.

Parameters

tokens (list[Union[list, str]])

The tokens to re-join together as a C++ template.

exhale.utils._join_template_args(idx: int, item: Union[str, list[typing.Union[list, str]]], stream: TextIO)[source]

Internal helper function for join_template_tokens().

Recursively writes each item to stream in order, expanding the list to the original C++ template definition.

Parameters

idx (int)

Recursive item depth level (not recursion call-stack depth). This is element index for when a parent calling function is iterating a list, when greater than 0 a , is needed to be inserted.

item (Union[str, list[Union[list, str]]])

The current item to write to stream. When a str, it is written directly. When a list, the item represents an inner template – < is written, followed by recursive joining of elements in the list, followed by >.

stream (TextIO)

The stream to write the results to.