Sustituciones dentro de enlaces en reST / Sphinx
-
22-07-2019 - |
Pregunta
Estoy usando Sphinx para documentar un servicio web que se implementará en diferentes servidores. La documentación está llena de ejemplos de URL para que el usuario haga clic y deberían funcionar. Mi problema es que el host, el puerto y la raíz de implementación variarán y la documentación tendrá que volver a generarse para cada implementación.
Intenté definir sustituciones como esta:
|base_url|/path
.. |base_url| replace:: http://localhost:8080
Pero el HTML generado no es lo que quiero (no incluye " / path " en el enlace generado):
<a href="http://localhost:8080">http://localhost:8080</a>/path
¿Alguien sabe cómo solucionar esto?
Solución
Nuevo en Sphinx v1.0:
sphinx.ext.extlinks & # 8211; Marcado para acortar enlaces externos
http://sphinx.pocoo.org/ext/extlinks.html
La extensión agrega un nuevo valor de configuración:
extlinks
Este valor de configuración debe ser un diccionario de sitios externos, asignando nombres de alias cortos únicos a una URL base y un prefijo. Por ejemplo, para crear un alias para los problemas mencionados anteriormente, agregaría
extlinks = {'issue':
('http://bitbucket.org/birkenfeld/sphinx/issue/%s', 'issue ')}
Ahora, puede usar el nombre de alias como una nueva función, p. :issue:`123`
. Esto luego inserta un enlace a http://bitbucket.org/birkenfeld/sphinx/issue/123. Como puede ver, el objetivo dado en el rol se sustituye en la URL base en lugar de %s
.
El título del enlace depende del segundo elemento de la tupla, el prefijo:
Si el prefijo es Ninguno, el título del enlace es la URL completa.
Si el prefijo es la cadena vacía, el título del enlace es la URL parcial dada en el contenido del rol (123 en este caso).
Si el prefijo es una cadena no vacía, el título del enlace es la URL parcial, precedida por el prefijo & # 8211; en el ejemplo anterior, el título del enlace sería el problema 123.
También puede usar el habitual & # 8220; título explícito & # 8221; sintaxis compatible con otros roles que generan enlaces, es decir, :issue:`this issue <123>`
. En este caso, el prefijo no es relevante.
Otros consejos
Ok, así es como lo hice. Primero, apilinks.py
(la extensión Sphinx):
from docutils import nodes, utils
def setup(app):
def api_link_role(role, rawtext, text, lineno, inliner, options={},
content=[]):
ref = app.config.apilinks_base + text
node = nodes.reference(rawtext, utils.unescape(ref), refuri=ref,
**options)
return [node], []
app.add_config_value('apilinks_base', 'http://localhost/', False)
app.add_role('apilink', api_link_role)
Ahora, en conf.py
, agregue 'apilinks'
a la lista de extensiones y establezca un valor apropiado para 'apilinks_base'
(de lo contrario, el valor predeterminado será 'http://localhost/'
). Mi archivo se ve así:
extensions = ['sphinx.ext.autodoc', 'apilinks']
# lots of other stuff
apilinks_base = 'http://host:88/base/'
Uso:
:apilink:`path`
Salida:
<a href="http://host:88/base/path">http://host:88/base/path</a>
Tuve un problema similar en el que necesitaba sustituir también las URL en los objetivos de la imagen.
extlinks
no se expande cuando se usa como valor del atributo de imagen :target:
.
Finalmente escribí una transformación de esfinge personalizada que reescribe las URL que comienzan con un prefijo dado, en mi caso, http://mybase/
. Aquí hay un código relevante para conf.py:
from sphinx.transforms import SphinxTransform
class ReplaceMyBase(SphinxTransform):
default_priority = 750
prefix = 'http://mybase/'
def apply(self):
from docutils.nodes import reference, Text
baseref = lambda o: (
isinstance(o, reference) and
o.get('refuri', '').startswith(self.prefix))
basetext = lambda o: (
isinstance(o, Text) and o.startswith(self.prefix))
base = self.config.mybase.rstrip('/') + '/'
for node in self.document.traverse(baseref):
target = node['refuri'].replace(self.prefix, base, 1)
node.replace_attr('refuri', target)
for t in node.traverse(basetext):
t1 = Text(t.replace(self.prefix, base, 1), t.rawsource)
t.parent.replace(t, t1)
return
# end of class
def setup(app):
app.add_config_value('mybase', 'https://en.wikipedia.org/wiki', 'env')
app.add_transform(ReplaceMyBase)
return
Esto expande la siguiente primera fuente para apuntar a la wikipedia en inglés.
Cuando conf.py establece mybase="https://es.wikipedia.org/wiki"
los enlaces apuntan a la wiki en español.
* inline link http://mybase/Helianthus
* `link with text <http://mybase/Helianthus>`_
* `link with separate definition`_
* image link |flowerimage|
.. _link with separate definition: http://mybase/Helianthus
.. |flowerimage| image:: https://upload.wikimedia.org/wikipedia/commons/f/f1/Tournesol.png
:target: http://mybase/Helianthus
Puede escribir una extensión Sphinx que crea una rol like
:apilink:`path`
y genera el enlace a partir de eso. Nunca hice esto, así que no puedo evitar más que dar este puntero, lo siento. Debería tratar de ver cómo se implementan los diversos roles. Muchos son muy similares a lo que necesitas, creo.