Avoir le même README à la fois dans Markdown et reStructuredText


116

J'ai un projet hébergé sur GitHub. Pour cela, j'ai écrit mon README en utilisant la syntaxe Markdown afin de l'avoir bien formaté sur GitHub.

Comme mon projet est en Python, je prévois également de le télécharger sur PyPi . La syntaxe utilisée pour les README sur PyPi est reStructuredText.

Je voudrais éviter d'avoir à gérer deux README contenant à peu près le même contenu; J'ai donc cherché un traducteur Markdown to RST (ou l'inverse), mais je n'en ai trouvé aucun.

L'autre solution que je vois est d'effectuer une démarque / HTML puis une traduction HTML / RST. J'ai trouvé des ressources pour ça ici et ici donc je suppose que ça devrait être possible.

Auriez-vous une idée qui pourrait mieux correspondre à ce que je veux faire?


21
Github rendra README.rst!
u0b34a0f6ae

C'est nouveau alors :) Mais bon à savoir, je vais essayer!
jlengrand

6
Si vous souhaitez que PyPI prenne en charge les readmes dans Markdown, veuillez commenter la demande de fonctionnalité sur bitbucket.org/pypa/pypi/issue/148/support-markdown-for-readmes
Colonel Panic

Réponses:


88

Je recommanderais Pandoc , le "couteau suisse pour convertir des fichiers d'un format de balisage dans un autre" (consultez le diagramme des conversions supportées en bas de page, c'est assez impressionnant). Pandoc permet au démarque de traduire directement la traduction reStructuredText. Il existe également un éditeur en ligne ici qui vous permet de l'essayer, vous pouvez donc simplement utiliser l'éditeur en ligne pour convertir vos fichiers README.


45
L'invocation magique est: pandoc --from=markdown --to=rst --output=README.rst README.md
Jonathan Eunice

47

Comme @Chris l'a suggéré, vous pouvez utiliser Pandoc pour convertir Markdown en RST. Cela peut être simplement automatisé en utilisant le module pypandoc et un peu de magie dans setup.py:

from setuptools import setup
try:
    from pypandoc import convert
    read_md = lambda f: convert(f, 'rst')
except ImportError:
    print("warning: pypandoc module not found, could not convert Markdown to RST")
    read_md = lambda f: open(f, 'r').read()

setup(
    # name, version, ...
    long_description=read_md('README.md'),
    install_requires=[]
)

Cela convertira automatiquement README.md en RST pour la longue description en utilisant PyPi. Quand pypandoc n'est pas disponible, il lit simplement README.md sans la conversion - pour ne pas forcer les autres à installer pypandoc quand ils veulent simplement construire le module, pas le télécharger sur PyPi.

Vous pouvez donc écrire dans Markdown comme d'habitude et ne plus vous soucier du désordre RST. ;)


Cela ne résout pas vraiment le problème, car si l'utilisateur n'a pas installé pypandoc (ce qu'il ne fera probablement pas), cela produira une erreur, car PyPI s'attend à ce que le champ long_description soit RST. Si pypandoc n'est pas disponible, vous devez définir long_description sur None ou sur une chaîne vide.
Cerin

7
Non, cela n'est nécessaire que lors du téléchargement des métadonnées sur PyPi (ce qui ne concerne que le développeur du module, pas les utilisateurs). Il ne génère aucune erreur lorsque l'utilisateur installe le module et n'a pas installé pypandoc. J'ai vérifié ce cas d'utilisation.
Jakub Jirutka

Cela peut également générer une erreur d'exécution. Afin de rester du bon côté, je recommande de faire try-exceptdans la fonction.
varepsilon

1
Parfait! Juste une chose - je recevais une RuntimeError: Missing format!exception jusqu'à ce que je change le lambda en read_md = lambda f: convert(f, 'rst', 'md'). La raison étant (je suppose) que je lui ai donné une chaîne et non un fichier (donc pas d'extension de fichier).
frnhr

@frnhr Votre estimation est correcte. Pandoc est capable de détecter automatiquement le format source à partir d'une extension de fichier, mais lorsque vous lui avez fourni une chaîne, vous devez spécifier le format explicitement.
Jakub Jirutka

30

Mise à jour 2019

L'entrepôt PyPI prend désormais également en charge le rendu Markdown! Il vous suffit de mettre à jour la configuration de votre package et d'y ajouter le long_description_content_type='text/markdown'. par exemple:

setup(
    name='an_example_package',
    # other arguments omitted
    long_description=long_description,
    long_description_content_type='text/markdown'
)

Par conséquent, il n'est plus nécessaire de conserver le README dans deux formats.

Vous pouvez trouver plus d'informations à ce sujet dans la documentation .

Ancienne réponse:

La bibliothèque de balisage utilisée par GitHub prend en charge reStructuredText. Cela signifie que vous pouvez écrire un fichier README.rst.

Ils prennent même en charge la mise en évidence des couleurs spécifiques à la syntaxe à l'aide des directives codeet code-block( exemple )


6

PyPI prend désormais en charge Markdown pour les longues descriptions!

Dans setup.py, définissez long_descriptionsur une chaîne Markdown, ajoutez long_description_content_type="text/markdown"et assurez-vous que vous utilisez des outils récents ( setuptools38.6.0+, twine1.11+).

Voir l'article de blog de Dustin Ingram pour plus de détails.


Bon de l'entendre! Il est intéressant de voir comment les progrès sont réalisés au fil du temps dans la communauté python en regardant l'historique de ce problème :).
jlengrand

4

Pour mes besoins, je ne voulais pas installer Pandoc sur mon ordinateur. J'ai utilisé docverter. Docverter est un serveur de conversion de documents avec une interface HTTP utilisant Pandoc pour cela.

import requests
r = requests.post(url='http://c.docverter.com/convert',
                  data={'to':'rst','from':'markdown'},
                  files={'input_files[]':open('README.md','rb')})
if r.ok:
    print r.content

3

Vous pourriez également être intéressé par le fait qu'il est possible d'écrire dans un sous-ensemble commun afin que votre document ressorte de la même manière lorsqu'il est rendu en tant que markdown ou rendu en tant que reStructuredText: https://gist.github.com/dupuy/1855764


1

J'ai rencontré ce problème et l'ai résolu avec les deux scripts bash suivants.

Notez que j'ai LaTeX intégré dans mon Markdown.

#!/usr/bin/env bash

if [ $# -lt 1 ]; then
  echo "$0 file.md"
  exit;
fi

filename=$(basename "$1")
extension="${filename##*.}"
filename="${filename%.*}"

if [ "$extension" = "md" ]; then
  rst=".rst"
  pandoc $1 -o $filename$rst
fi

Il est également utile de convertir en HTML. md2html:

#!/usr/bin/env bash

if [ $# -lt 1 ]; then
  echo "$0 file.md <style.css>"
  exit;
fi

filename=$(basename "$1")
extension="${filename##*.}"
filename="${filename%.*}"

if [ "$extension" = "md" ]; then
  html=".html"
  if [ -z $2 ]; then
    # if no css
    pandoc -s -S --mathjax --highlight-style pygments $1 -o $filename$html
  else
    pandoc -s -S --mathjax --highlight-style pygments -c $2 $1 -o $filename$html
  fi
fi

J'espère que ça aide


0

En utilisant le pandoc outil suggéré par d'autres, j'ai créé un md2rstutilitaire pour créer les rstfichiers. Même si cette solution signifie que vous avez à la fois un mdet un, rstelle semble être la moins invasive et permettrait tout support de démarque ajouté. Je préfère cela à la modification setup.pyet peut-être que vous le feriez aussi:

#!/usr/bin/env python

'''
Recursively and destructively creates a .rst file for all Markdown
files in the target directory and below.

Created to deal with PyPa without changing anything in setup based on
the idea that getting proper Markdown support later is worth waiting
for rather than forcing a pandoc dependency in sample packages and such.

Vote for
(https://bitbucket.org/pypa/pypi/issue/148/support-markdown-for-readmes)

'''

import sys, os, re

markdown_sufs = ('.md','.markdown','.mkd')
markdown_regx = '\.(md|markdown|mkd)$'

target = '.'
if len(sys.argv) >= 2: target = sys.argv[1]

md_files = []
for root, dirnames, filenames in os.walk(target):
    for name in filenames:
        if name.endswith(markdown_sufs):
            md_files.append(os.path.join(root, name))

for md in md_files:
    bare = re.sub(markdown_regx,'',md)
    cmd='pandoc --from=markdown --to=rst "{}" -o "{}.rst"'
    print(cmd.format(md,bare))
    os.system(cmd.format(md,bare))
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.