Exemplo n.º 1
0
def indexhtml(doc):
    """Generate HTML index for title page"""
    keys = sorted(doc.toc.keys(), key=placekey)

    def depth(key):
        return key.count(".")

    HTML = fr"""<ul>"""
    for k in keys:
        e = doc.toc[k]
        title = e["title"]
        file = os.path.splitext(e["filename"])[0]
        base = doc.get_metadata("binarybaseurl", "")
        if depth(k) > 0:
            continue
        entry = dedent(fr"""
                <li><a href="{file+'.html'}"><b>Chapter {k}:</b> {title}</a>
                <small>(<a href="{base+'/'+file+'.pdf'}"><i class="fas fa-file-pdf"></i>PDF: best formatting</a> ,
                <a href="{base+'/'+file+'.docx'}"><i class="fas fa-file-word"></i>Word: buggy</a>)</small>
                </li>
                """)
        HTML += entry
    HTML += r"""</ul>"""
    doc.metadata["indexcontents"] = pf.MetaBlocks(
        pf.RawBlock(HTML, format="html"))
Exemplo n.º 2
0
def tochtml(toc, title=""):
    """Generate HTML from toc"""
    keys = sorted(toc.keys(), key=placekey)

    def depth(key):
        return key.count(".")

    d = 0
    HTML = dedent(fr"""
        <ul class="summary">
        <li><a href="./">{title}</a></li>
        <li class="divider"></li>
        """)
    first = True
    for k in keys:
        e = toc[k]
        title = e["title"]
        file = e["filename"]
        ref = "#" + e["href"] if e["href"] else ""
        entry = ""
        if depth(k) == d and not first:
            entry = r"</li>"
        first = False
        if depth(k) > d:
            entry = r"<ul>" + r"<li><ul>" * (depth(k) - d - 1)
        if depth(k) < d:
            entry = r"</li>" + r"</ul></li>" * (d - depth(k))
        entry += dedent(fr"""
            <li class="chapter" data-level="{k}" data-path="{file}"><a href="{file}{ref}"><i class="fa fa-check"></i><b>{k}</b> {title}</a>
            """)
        HTML += entry
        d = depth(k)
    entry = r"</li>" + r"</ul></li>" * d
    HTML += entry + dedent(r"""
        <li class="divider"></li>
        </ul>
        """)
    return HTML
Exemplo n.º 3
0
def h_pseudocode(e, doc):
    if not isinstance(e, pf.CodeBlock) or not "algorithm" in e.classes:
        return None
    content = e.text
    if e.identifier:
        doc.label_descriptions[e.identifier] = "Algorithm"
    label = labelref(e, doc)
    _, number_, _ = get_full_label(label, doc)
    if number_ and number_ != "??":
        i = number_.rfind(".")
        number = int(number_[i + 1:]) if i > -1 else int(number_)
    else:
        number = 0
    title = e.attributes.get("title", "")
    if doc.format == "latex":
        textitle = f"[{title}]" if title else ""
        result = (dedent(rf"""
        \begin{{algorithm}}{textitle}
        \label[algorithm]{{{label}}} ~ \\ \noindent
        \begin{{algorithmic}}[1]
        """) + "\n" + format_pseudocode(content) + dedent(fr"""
        \end{{algorithmic}}
        \end{{algorithm}}
        """))
        return pf.RawBlock(result, format="latex")
    if doc.format == "html":
        result = htmlpseudocode(label, number, title,
                                format_pseudocode(content))
        return pf.RawBlock(result, format="html")

    if doc.format == "-html":
        textitle = f"\caption{{{title}}}" if title else ""
        uid = str(uuid.uuid4())
        content = (format_pseudocode(content).replace(
            "\\INPUT", "\\REQUIRE").replace("\\OUTPUT", "\\ENSURE"))
        result = (dedent(rf"""
            <pre id="{uid}" class="pseudocodetext" style="display:none;">
            \begin{{algorithm}}
            {textitle}
            \begin{{algorithmic}}
            """) + "\n" + content + dedent(fr"""
            \end{{algorithmic}}
            \end{{algorithm}}
            </pre>
            <div id="{uid}result" class="pseudocodeoutput" ></div>

            <script>
            document.addEventListener('readystatechange', event => {{
            if (event.target.readyState === "complete") {{
                var code = document.getElementById('{uid}').textContent;
                var resultEl = document.getElementById('{uid}result');
                resultEl.innerHTML = '';
                var options = {{
                    captionCount: {number-1},
                    lineNumber: true
                }};
                pseudocode.render(code, resultEl, options);
            }}
            }});
            </script>
            """))
        return pf.RawBlock(result, format="html")
    return None
Exemplo n.º 4
0
def htmlpseudocode(id, number, title, code):
    """Takes formatted code and makes it into HTML"""
    code = code.replace("<", "&lt;").replace(">", "&gt;")
    bm = r'<span class="math inline">\('
    em = r'\)</span>'
    prefix = dedent(f'''
        <div  class="pseudocodeoutput">
        <div class="ps-root">
        <div class="ps-algorithm with-caption" id = {id}>
        <p class="ps-line" style="text-indent:-1.2em;padding-left:1.2em;">
        <span class="ps-keyword">Algorithm {number} </span>{math2unicode(title)}</p>
        <div class="ps-algorithmic">
    ''')  # dropped with-linenum
    postfix = dedent('''
    </div>
    </div>
    </div>
    </div>
    ''')
    main = ""
    keywordsother = {
        "INPUT": "Input:",
        "OUTPUT": "Output:",
        "ENSURE": "Output:",
        "REQUIRE": "Input:",
        "ELSE": "else",
        "ELSIF": "elsif",
        "RETURN": "return",
        "LELSE": "else"
    }

    keywordsbeg = {
        "PROCEDURE": "Procedure",
        "WHILE": "while",
        "FOR": "for",
        "FUNCTION": "Function",
        "IF": "if",
        "LIF": "if"
    }

    keywordsend = {
        "ENDPROCEDURE": "endproc",
        "ENDWHILE": "endwhile",
        "ENDFOR": "endfor",
        "ENDFUNCTION": "endfunc",
        "ENDIF": "endif",
        "LENDIF": "endif"
    }
    keywords = {}
    keywords.update(keywordsbeg)
    keywords.update(keywordsend)
    keywords.update(keywordsother)
    for line in code.split('\n'):
        afterline = ""
        for k in keywordsbeg:
            if line.find("\\" + k) >= 0:
                afterline += dedent(''' 
                <div class="ps-block" style="margin-left:1.2em;">
                ''')
        for k in keywordsend:
            if line.find("\\" + k) >= 0:
                main += "\n" + r"</div>"
        line = re.sub(r"\\PROCEDURE\{(\w+)\}\{([^\}]*)\}",
                      r"\\PROCEDURE" + bm + r"\\mathsf{\1}" + em + "(\2)",
                      line)
        for k in keywords:
            line = line.replace(
                f"\\{k}", f'<span class="ps-keyword">{keywords[k]}</span>')
        temp = ""
        while len(line) and line.find("$") >= 0:
            i = line.find("$")
            j = line[i + 1:].find("$")
            if j < 0: break
            temp += f"{line[:i]}{em}{line[i+1:j]}{bm}"
            line = line[j + 1:]
        temp += line
        line = re.sub(r"\\CALL\{(\w+)\}\{([^\}]*)\}", r"\\mathsf{\1}(\2)",
                      line)
        line = line.replace("\\STATE", "")
        t = line.find("\\COMMENT")
        if t >= 0:
            rest = line[t + len("\\COMMENT{"):]
            rest = rest[:rest.find("}")]
            line = line[:t] + rf'<span class="ps-comment"><i># {rest}</i></span>'
        main += dedent(f'''
            <p class="ps-line" style="text-indent:-1.2em;padding-left:1.2em;">{line}
        ''') + afterline
    res = prefix + main + postfix
    res += "</div>" * (res.count("<div>") - res.count("</div>"))
    return res
Exemplo n.º 5
0
    def __init__(self,projparams,llcrnrlon,llcrnrlat,
                      urcrnrlon,urcrnrlat,urcrnrislatlon=True):
        """
        initialize a Proj class instance.

        Input 'projparams' is a dictionary containing proj map
        projection control parameter key/value pairs.
        See the proj documentation (http://www.remotesensing.org/proj/)
        for details.

        llcrnrlon,llcrnrlat are lon and lat (in degrees) of lower
        left hand corner of projection region.

        urcrnrlon,urcrnrlat are lon and lat (in degrees) of upper
        right hand corner of projection region if urcrnrislatlon=True
        (default). Otherwise, urcrnrlon,urcrnrlat are x,y in projection
        coordinates (units meters), assuming the lower left corner is x=0,y=0.
        """
        self.projparams = projparams
        self.projection = projparams['proj']
        # rmajor is the semi-major axis.
        # rminor is the semi-minor axis.
        # esq is eccentricity squared.
        try:
            self.rmajor = projparams['a']
            self.rminor = projparams['b']
        except:
            try:
                self.rmajor = projparams['R']
            except:
                self.rmajor = projparams['bR_a']
            self.rminor = self.rmajor
        if self.rmajor == self.rminor:
            self.ellipsoid = False
        else:
            self.ellipsoid = True
        self.flattening = (self.rmajor-self.rminor)/self.rmajor
        self.esq = (self.rmajor**2 - self.rminor**2)/self.rmajor**2
        self.llcrnrlon = llcrnrlon
        self.llcrnrlat = llcrnrlat
        if self.projection == 'cyl':
            llcrnrx = llcrnrlon
            llcrnry = llcrnrlat
        elif self.projection == 'ob_tran':
            self._proj4 = pyproj.Proj(projparams)
            llcrnrx,llcrnry = self(llcrnrlon,llcrnrlat)
            llcrnrx = _rad2dg*llcrnrx; llcrnry = _rad2dg*llcrnry
            if llcrnrx < 0: llcrnrx = llcrnrx + 360
        elif self.projection in 'ortho':
            if (llcrnrlon == -180 and llcrnrlat == -90 and
                urcrnrlon == 180 and urcrnrlat == 90):
                self._fulldisk = True
                self._proj4 = pyproj.Proj(projparams)
                llcrnrx = -self.rmajor
                llcrnry = -self.rmajor
                self._width = 0.5*(self.rmajor+self.rminor)
                self._height = 0.5*(self.rmajor+self.rminor)
                urcrnrx = -llcrnrx
                urcrnry = -llcrnry
            else:
                self._fulldisk = False
                self._proj4 = pyproj.Proj(projparams)
                llcrnrx, llcrnry = self(llcrnrlon,llcrnrlat)
                if llcrnrx > 1.e20 or llcrnry > 1.e20:
                    raise ValueError(_lower_left_out_of_bounds)
        elif self.projection == 'aeqd' and\
             (llcrnrlon == -180 and llcrnrlat == -90  and urcrnrlon == 180 and\
             urcrnrlat == 90):
            self._fulldisk = True
            self._proj4 = pyproj.Proj(projparams)
            # raise an exception for ellipsoids - there appears to be a bug
            # in proj4 that causes the inverse transform to fail for points
            # more than 90 degrees of arc away from center point for ellipsoids
            # (works fine for spheres) - below is an example
            #from pyproj import Proj
            #p1 = Proj(proj='aeqd',a=6378137.00,b=6356752.3142,lat_0=0,lon_0=0)
            #x,y= p1(91,0)
            #lon,lat = p1(x,y,inverse=True) # lon is 89 instead of 91
            if self.ellipsoid:
                msg = dedent("""
                full disk (whole world) Azimuthal Equidistant projection can
                only be drawn for a perfect sphere""")
                raise ValueError(msg)
            llcrnrx = -np.pi*self.rmajor
            llcrnry = -np.pi*self.rmajor
            self._width = -llcrnrx
            self._height = -llcrnry
            urcrnrx = -llcrnrx
            urcrnry = -llcrnry
        elif self.projection == 'geos':
            self._proj4 = pyproj.Proj(projparams)
            # find major and minor axes of ellipse defining map proj region.
            # h is measured from surface of earth at equator.
            h = projparams['h'] + self.rmajor
            # latitude of horizon on central meridian
            lonmax = 90.-(180./np.pi)*np.arcsin(self.rmajor/h)
            # longitude of horizon on equator
            latmax = 90.-(180./np.pi)*np.arcsin(self.rminor/h)
            # truncate to nearest hundredth of a degree (to make sure
            # they aren't slightly over the horizon)
            latmax = int(100*latmax)/100.
            lonmax = int(100*lonmax)/100.
            # width and height of visible projection
            P = pyproj.Proj(proj='geos',a=self.rmajor,\
                            b=self.rminor,lat_0=0,lon_0=0,h=projparams['h'])
            x1,y1 = P(0.,latmax); x2,y2 = P(lonmax,0.)
            width = x2; height = y1
            self._height = height
            self._width = width
            if (llcrnrlon == -180 and llcrnrlat == -90 and
                urcrnrlon == 180 and urcrnrlat == 90):
                self._fulldisk = True
                llcrnrx = -width
                llcrnry = -height
                urcrnrx = -llcrnrx
                urcrnry = -llcrnry
            else:
                self._fulldisk = False
                llcrnrx, llcrnry = self(llcrnrlon,llcrnrlat)
                if llcrnrx > 1.e20 or llcrnry > 1.e20:
                    raise ValueError(_lower_left_out_of_bounds)
        elif self.projection == 'nsper':
            self._proj4 = pyproj.Proj(projparams)
            # find major and minor axes of ellipse defining map proj region.
            # h is measured from surface of earth at equator.
            h = projparams['h'] + self.rmajor
            # latitude of horizon on central meridian
            lonmax = 90.-(180./np.pi)*np.arcsin(self.rmajor/h)
            # longitude of horizon on equator
            latmax = 90.-(180./np.pi)*np.arcsin(self.rmajor/h)
            # truncate to nearest hundredth of a degree (to make sure
            # they aren't slightly over the horizon)
            latmax = int(100*latmax)/100.
            lonmax = int(100*lonmax)/100.
            # width and height of visible projection
            P = pyproj.Proj(proj='nsper',a=self.rmajor,\
                            b=self.rminor,lat_0=0,lon_0=0,h=projparams['h'])
            x1,y1 = P(0.,latmax); x2,y2 = P(lonmax,0.)
            width = x2; height = y1
            self._height = height
            self._width = width
            if (llcrnrlon == -180 and llcrnrlat == -90 and
                urcrnrlon == 180 and urcrnrlat == 90):
                self._fulldisk = True
                llcrnrx = -width
                llcrnry = -height
                urcrnrx = -llcrnrx
                urcrnry = -llcrnry
            else:
                self._fulldisk = False
                llcrnrx, llcrnry = self(llcrnrlon,llcrnrlat)
                if llcrnrx > 1.e20 or llcrnry > 1.e20:
                    raise ValueError(_lower_left_out_of_bounds)
        elif self.projection in _pseudocyl:
            self._proj4 = pyproj.Proj(projparams)
            xtmp,urcrnry = self(projparams['lon_0'],90.)
            urcrnrx,xtmp = self(projparams['lon_0']+180.,0)
            llcrnrx = -urcrnrx
            llcrnry = -urcrnry
            if self.ellipsoid and self.projection in ['kav7','eck4','mbtfpq']:
                msg = "this projection can only be drawn for a perfect sphere"
                raise ValueError(msg)
        else:
            self._proj4 = pyproj.Proj(projparams)
            llcrnrx, llcrnry = self(llcrnrlon,llcrnrlat)
            if self.projection == 'aeqd': self._fulldisk=False
        # compute x_0, y_0 so ll corner of domain is x=0,y=0.
        # note that for 'cyl' x,y == lon,lat
        if self.projection != 'ob_tran':
            self.projparams['x_0']=-llcrnrx
            self.projparams['y_0']=-llcrnry
        # reset with x_0, y_0.
        if self.projection not in ['cyl','ob_tran']:
            self._proj4 = pyproj.Proj(projparams)
            llcrnry = 0.
            llcrnrx = 0.
        elif self.projection != 'ob_tran':
            llcrnrx = llcrnrlon
            llcrnry = llcrnrlat
        if urcrnrislatlon:
            self.urcrnrlon = urcrnrlon
            self.urcrnrlat = urcrnrlat
            if self.projection not in ['ortho','geos','nsper','aeqd'] + _pseudocyl:
                urcrnrx,urcrnry = self(urcrnrlon,urcrnrlat)
                if self.projection == 'ob_tran':
                    urcrnrx = _rad2dg*urcrnrx; urcrnry = _rad2dg*urcrnry
                    if urcrnrx < 0: urcrnrx = urcrnrx + 360
            elif self.projection in ['ortho','geos','nsper','aeqd']:
                if self._fulldisk:
                    urcrnrx = 2.*self._width
                    urcrnry = 2.*self._height
                else:
                    urcrnrx,urcrnry = self(urcrnrlon,urcrnrlat)
                    if urcrnrx > 1.e20 or urcrnry > 1.e20:
                        raise ValueError(_upper_right_out_of_bounds)
            elif self.projection in _pseudocyl:
                xtmp,urcrnry = self(projparams['lon_0'],90.)
                urcrnrx,xtmp = self(projparams['lon_0']+180.,0)
        else:
            urcrnrx = urcrnrlon
            urcrnry = urcrnrlat
            urcrnrlon, urcrnrlat = self(urcrnrx, urcrnry, inverse=True)
            self.urcrnrlon = urcrnrlon
            self.urcrnrlat = urcrnrlat

        # corners of domain.
        self.llcrnrx = llcrnrx
        self.llcrnry = llcrnry
        self.urcrnrx = urcrnrx
        self.urcrnry = urcrnry
        if urcrnrx > llcrnrx:
            self.xmin = llcrnrx
            self.xmax = urcrnrx
        else:
            self.xmax = llcrnrx
            self.xmin = urcrnrx
        if urcrnry > llcrnry:
            self.ymin = llcrnry
            self.ymax = urcrnry
        else:
            self.ymax = llcrnry
            self.ymin = urcrnry
Exemplo n.º 6
0
    def param(func):
        new_sig = None
        # signature is since 3.3 and wrapped since 3.2, but we support 3.4+.
        python_has_signature = python_has_wrapped = six.PY3

        # if in a legacy version of python and IPython is already imported
        # try to use their back-ported signature
        if not python_has_signature and 'IPython' in sys.modules:
            try:
                import IPython.utils.signatures
                signature = IPython.utils.signatures.signature
                Parameter = IPython.utils.signatures.Parameter
            except ImportError:
                pass
            else:
                python_has_signature = True
        else:
            if python_has_signature:
                signature = inspect.signature
                Parameter = inspect.Parameter

        if not python_has_signature:
            arg_spec = inspect.getargspec(func)
            _arg_names = arg_spec.args
            _has_varargs = arg_spec.varargs is not None
            _has_varkwargs = arg_spec.keywords is not None
        else:
            sig = signature(func)
            _has_varargs = False
            _has_varkwargs = False
            _arg_names = []
            params = list(sig.parameters.values())
            for p in params:
                if p.kind is Parameter.VAR_POSITIONAL:
                    _has_varargs = True
                elif p.kind is Parameter.VAR_KEYWORD:
                    _has_varkwargs = True
                else:
                    _arg_names.append(p.name)
            data_param = Parameter('data',
                                   Parameter.KEYWORD_ONLY,
                                   default=None)
            if _has_varkwargs:
                params.insert(-1, data_param)
            else:
                params.append(data_param)
            new_sig = sig.replace(parameters=params)
        # Import-time check: do we have enough information to replace *args?
        arg_names_at_runtime = False
        # there can't be any positional arguments behind *args and no
        # positional args can end up in **kwargs, so only *varargs make
        # problems.
        # http://stupidpythonideas.blogspot.de/2013/08/arguments-and-parameters.html
        if not _has_varargs:
            # all args are "named", so no problem
            # remove the first "ax" / self arg
            arg_names = _arg_names[1:]
        else:
            # Here we have "unnamed" variables and we need a way to determine
            # whether to replace a arg or not
            if replace_names is None:
                # all argnames should be replaced
                arg_names = None
            elif len(replace_names) == 0:
                # No argnames should be replaced
                arg_names = []
            elif len(_arg_names) > 1 and (positional_parameter_names is None):
                # we got no manual parameter names but more than an 'ax' ...
                if len(replace_names - set(_arg_names[1:])) == 0:
                    # all to be replaced arguments are in the list
                    arg_names = _arg_names[1:]
                else:
                    msg = ("Got unknown 'replace_names' and wrapped function "
                           "'%s' uses '*args', need "
                           "'positional_parameter_names'!")
                    raise AssertionError(msg % func.__name__)
            else:
                if positional_parameter_names is not None:
                    if callable(positional_parameter_names):
                        # determined by the function at runtime
                        arg_names_at_runtime = True
                        # so that we don't compute the label_pos at import time
                        arg_names = []
                    else:
                        arg_names = positional_parameter_names
                else:
                    if replace_all_args:
                        arg_names = []
                    else:
                        msg = ("Got 'replace_names' and wrapped function "
                               "'%s' uses *args, need "
                               "'positional_parameter_names' or "
                               "'replace_all_args'!")
                        raise AssertionError(msg % func.__name__)

        # compute the possible label_namer and label position in positional
        # arguments
        label_pos = 9999  # bigger than all "possible" argument lists
        label_namer_pos = 9999  # bigger than all "possible" argument lists
        if (label_namer and  # we actually want a label here ...
                arg_names and  # and we can determine a label in *args ...
                (label_namer in arg_names)):  # and it is in *args
            label_namer_pos = arg_names.index(label_namer)
            if "label" in arg_names:
                label_pos = arg_names.index("label")

        # Check the case we know a label_namer but we can't find it the
        # arg_names... Unfortunately the label_namer can be in **kwargs,
        # which we can't detect here and which results in a non-set label
        # which might surprise the user :-(
        if label_namer and not arg_names_at_runtime and not _has_varkwargs:
            if not arg_names:
                msg = ("label_namer '%s' can't be found as the parameter "
                       "without 'positional_parameter_names'.")
                raise AssertionError(msg % label_namer)
            elif label_namer not in arg_names:
                msg = ("label_namer '%s' can't be found in the parameter "
                       "names (known argnames: %s).")
                raise AssertionError(msg % (label_namer, arg_names))
            else:
                # this is the case when the name is in arg_names
                pass

        @functools.wraps(func)
        def inner(ax, *args, **kwargs):
            # this is needed because we want to change these values if
            # arg_names_at_runtime==True, but python does not allow assigning
            # to a variable in a outer scope. So use some new local ones and
            # set them to the already computed values.
            _label_pos = label_pos
            _label_namer_pos = label_namer_pos
            _arg_names = arg_names

            label = None

            data = kwargs.pop('data', None)

            if data is None:  # data validation
                args = tuple(_sanitize_sequence(a) for a in args)
            else:
                if arg_names_at_runtime:
                    # update the information about replace names and
                    # label position
                    _arg_names = positional_parameter_names(args, data)
                    if (label_namer and  # we actually want a label here ...
                            _arg_names and  # and we can find a label in *args
                            (label_namer in _arg_names)):  # and it is in *args
                        _label_namer_pos = _arg_names.index(label_namer)
                        if "label" in _arg_names:
                            _label_pos = arg_names.index("label")

                # save the current label_namer value so that it can be used as
                # a label
                if _label_namer_pos < len(args):
                    label = args[_label_namer_pos]
                else:
                    label = kwargs.get(label_namer, None)
                # ensure a string, as label can't be anything else
                if not isinstance(label, six.string_types):
                    label = None

                if (replace_names is None) or (replace_all_args is True):
                    # all should be replaced
                    args = tuple(_replacer(data, a) for
                                 j, a in enumerate(args))
                else:
                    # An arg is replaced if the arg_name of that position is
                    #   in replace_names ...
                    if len(_arg_names) < len(args):
                        raise RuntimeError(
                            "Got more args than function expects")
                    args = tuple(_replacer(data, a)
                                 if _arg_names[j] in replace_names else a
                                 for j, a in enumerate(args))

                if replace_names is None:
                    # replace all kwargs ...
                    kwargs = dict((k, _replacer(data, v))
                                  for k, v in six.iteritems(kwargs))
                else:
                    # ... or only if a kwarg of that name is in replace_names
                    kwargs = dict((k, _replacer(data, v)
                                   if k in replace_names else v)
                                  for k, v in six.iteritems(kwargs))

            # replace the label if this func "wants" a label arg and the user
            # didn't set one. Note: if the user puts in "label=None", it does
            # *NOT* get replaced!
            user_supplied_label = (
                (len(args) >= _label_pos) or  # label is included in args
                ('label' in kwargs)  # ... or in kwargs
            )
            if (label_namer and not user_supplied_label):
                if _label_namer_pos < len(args):
                    kwargs['label'] = _get_label(args[_label_namer_pos], label)
                elif label_namer in kwargs:
                    kwargs['label'] = _get_label(kwargs[label_namer], label)
                else:
                    import warnings
                    msg = ("Tried to set a label via parameter '%s' in "
                           "func '%s' but couldn't find such an argument. \n"
                           "(This is a programming error, please report to "
                           "the matplotlib list!)")
                    warnings.warn(msg % (label_namer, func.__name__),
                                  RuntimeWarning, stacklevel=2)
            return func(ax, *args, **kwargs)
        pre_doc = inner.__doc__
        if pre_doc is None:
            pre_doc = ''
        else:
            pre_doc = dedent(pre_doc)
        _repl = ""
        if replace_names is None:
            _repl = "* All positional and all keyword arguments."
        else:
            if len(replace_names) != 0:
                _repl = "* All arguments with the following names: '{names}'."
            if replace_all_args:
                _repl += "\n    * All positional arguments."
            _repl = _repl.format(names="', '".join(sorted(replace_names)))
        inner.__doc__ = (pre_doc +
                         _DATA_DOC_APPENDIX.format(replaced=_repl))
        if not python_has_wrapped:
            inner.__wrapped__ = func
        if new_sig is not None:
            inner.__signature__ = new_sig
        return inner