Return the docstrings for all states. Optionally, specify a state or a
    function to narrow the selection.

    The strings are aggregated into a single document on the master for easy
    reading.

    Multiple states/functions can be specified.

    .. versionadded:: 2014.7.0

    CLI Example:

    .. code-block:: bash

        salt '*' sys.state_doc
        salt '*' sys.state_doc service
        salt '*' sys.state_doc service.running
        salt '*' sys.state_doc service.running ipables.append

    State names can be specified as globs.

    .. versionadded:: 2015.5.0

    .. code-block:: bash

        salt '*' sys.state_doc 'service.*' 'iptables.*'

def state_doc(*args):
    '''
    Return the docstrings for all states. Optionally, specify a state or a
    function to narrow the selection.

    The strings are aggregated into a single document on the master for easy
    reading.

    Multiple states/functions can be specified.

    .. versionadded:: 2014.7.0

    CLI Example:

    .. code-block:: bash

        salt '*' sys.state_doc
        salt '*' sys.state_doc service
        salt '*' sys.state_doc service.running
        salt '*' sys.state_doc service.running ipables.append

    State names can be specified as globs.

    .. versionadded:: 2015.5.0

    .. code-block:: bash

        salt '*' sys.state_doc 'service.*' 'iptables.*'

    '''
    st_ = salt.state.State(__opts__)

    docs = {}
    if not args:
        for fun in st_.states:
            state = fun.split('.')[0]
            if state not in docs:
                if hasattr(st_.states[fun], '__globals__'):
                    docs[state] = st_.states[fun].__globals__['__doc__']
            docs[fun] = st_.states[fun].__doc__
        return _strip_rst(docs)

    for module in args:
        _use_fnmatch = False
        if '*' in module:
            target_mod = module
            _use_fnmatch = True
        elif module:
            # allow both "sys" and "sys." to match sys, without also matching
            # sysctl
            target_mod = module + '.' if not module.endswith('.') else module
        else:
            target_mod = ''
        if _use_fnmatch:
            for fun in fnmatch.filter(st_.states, target_mod):
                state = fun.split('.')[0]
                if hasattr(st_.states[fun], '__globals__'):
                    docs[state] = st_.states[fun].__globals__['__doc__']
                docs[fun] = st_.states[fun].__doc__
        else:
            for fun in st_.states:
                if fun == module or fun.startswith(target_mod):
                    state = module.split('.')[0]
                    if state not in docs:
                        if hasattr(st_.states[fun], '__globals__'):
                            docs[state] = st_.states[fun].__globals__['__doc__']
                    docs[fun] = st_.states[fun].__doc__
    return _strip_rst(docs)