Замены внутри ссылок в reST / Sphinx
-
22-07-2019 - |
Вопрос
Я использую Sphinx для документирования веб-сервиса, который будет развернут на разных серверах.Документация полна примеров URL-адресов, по которым пользователь может щелкнуть, и они должны просто работать.Моя проблема в том, что хост, порт и корневой каталог развертывания будут отличаться, и документацию придется создавать заново для каждого развертывания.
Я попытался определить замены следующим образом:
|base_url|/path
.. |base_url| replace:: http://localhost:8080
Но сгенерированный HTML - это не то, что я хочу (не включает "/ path" в сгенерированную ссылку):
<a href="http://localhost:8080">http://localhost:8080</a>/path
Кто-нибудь знает, как обойти это?
Решение
Новое в Sphinx версии v1.0:
sphinx.ext.extlinks – Разметка для сокращения внешних ссылок
http://sphinx.pocoo.org/ext/extlinks.html
Расширение добавляет одно новое значение конфигурации:
дополнительные ссылки
Это конфигурационное значение должно быть словарем внешних сайтов, сопоставляющим уникальные короткие псевдонимы базовому URL и префиксу.Например, чтобы создать псевдоним для вышеупомянутых проблем, вы бы добавили
extlinks = {'issue':
('http://bitbucket.org/birkenfeld/sphinx/issue/%s', 'issue ')}
Теперь вы можете использовать псевдоним в качестве новой роли, например :issue:`123`
.Затем при этом будет вставлена ссылка на http://bitbucket.org/birkenfeld/sphinx/issue/123.Как вы можете видеть, цель, указанная в роли, подставляется в базовый URL-адрес вместо %s
.
Заголовок ссылки зависит от второго элемента в кортеже, префикса:
Если префикс равен None, заголовок ссылки является полным URL-адресом.Если префикс является пустой строкой, заголовок ссылки представляет собой частичный URL-адрес, указанный в содержимом роли (в данном случае 123).)
Если префикс является непустой строкой, заголовок ссылки представляет собой частичный URL-адрес, перед которым добавляется префикс – в приведенном выше примере заголовок ссылки будет проблемой 123.Вы также можете использовать обычный синтаксис “явного заголовка”, поддерживаемый другими ролями, которые генерируют ссылки, т.е. :issue:`this issue <123>`
.В данном случае префикс не имеет значения.
Другие советы
Хорошо, вот как я это сделал.Первый, apilinks.py
(продолжение "Сфинкс"):
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)
Теперь, в conf.py
, добавить 'apilinks'
перейдите в список расширений и установите соответствующее значение для 'apilinks_base'
(в противном случае по умолчанию будет установлено значение 'http://localhost/'
).Мой файл выглядит примерно так:
extensions = ['sphinx.ext.autodoc', 'apilinks']
# lots of other stuff
apilinks_base = 'http://host:88/base/'
Использование:
:apilink:`path`
Выходной сигнал:
<a href="http://host:88/base/path">http://host:88/base/path</a>
У меня была похожая проблема, когда мне нужно было заменить URL-адреса в целевых изображениях.
extlinks
не раскрываются при использовании в качестве значения атрибута image :target:
.
В конце концов я написал собственное преобразование сфинкса, которое переписывает URL, которые начинаются с заданного префикса, в моем случае, http://mybase/
. Вот соответствующий код для 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
Это расширяет следующий первый источник, чтобы указать на английскую википедию.
Когда conf.py устанавливает mybase="https://es.wikipedia.org/wiki"
, ссылки указывают на испанскую вики.
* 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
Вы можете написать расширение Sphinx , которое создает role like
:apilink:`path`
и генерирует ссылку из этого. Я никогда не делал этого, поэтому я не могу помочь больше, чем дать этот указатель, извините. Вы должны попытаться посмотреть, как реализованы различные роли. Я думаю, многие из них очень похожи на то, что вам нужно.