Tener el mismo README tanto en Markdown como en reStructuredText

116

Tengo un proyecto alojado en GitHub. Para esto, he escrito mi README usando la sintaxis de Markdown para tenerlo bien formateado en GitHub.

Como mi proyecto está en Python, también planeo subirlo a PyPi . La sintaxis utilizada para READMEs en PyPi es reStructuredText.

Me gustaría evitar tener que manejar dos archivos README que contienen aproximadamente el mismo contenido; así que busqué una rebaja para el traductor RST (o al revés), pero no pude encontrar ninguna.

La otra solución que veo es realizar un markdown / HTML y luego una traducción HTML / RST. Encontré algunos recursos para esto aquí y aquí, así que supongo que debería ser posible.

¿Tiene alguna idea que pueda encajar mejor con lo que quiero hacer?

jlengrand
fuente
21
¡Github se renderizará README.rst!
u0b34a0f6ae
Esto es nuevo entonces :) Pero es bueno saberlo, ¡lo intentaré!
jlengrand
6
Si desea que PyPI admita readmes en Markdown, comente sobre la solicitud de función en bitbucket.org/pypa/pypi/issue/148/support-markdown-for-readmes
Colonel Panic

Respuestas:

88

Recomendaría Pandoc , la "navaja suiza para convertir archivos de un formato de marcado a otro" (consulte el diagrama de conversiones admitidas en la parte inferior de la página, es bastante impresionante). Pandoc permite la reducción a la traducción reStructuredText directamente. También hay un editor en línea aquí que le permite probarlo, por lo que simplemente podría usar el editor en línea para convertir sus archivos README.

Chris
fuente
45
La invocación mágica es: pandoc --from=markdown --to=rst --output=README.rst README.md
Jonathan Eunice
47

Como sugirió @Chris, puede usar Pandoc para convertir Markdown a RST. Esto se puede automatizar simplemente usando el módulo pypandoc y algo de magia en 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=[]
)

Esto convertirá automáticamente README.md a RST para la descripción larga usando en PyPi. Cuando pypandoc no está disponible, simplemente lee README.md sin la conversión, para no obligar a otros a instalar pypandoc cuando solo quieren construir el módulo, no subirlo a PyPi.

Por lo tanto, puede escribir en Markdown como de costumbre y ya no le importa el desorden de RST. ;)

Jakub Jirutka
fuente
Esto realmente no resuelve el problema, ya que si el usuario no tiene pypandoc instalado (que probablemente no lo hará), arrojará un error, ya que PyPI espera que el campo long_description sea RST. Si pypandoc no está disponible, debe establecer long_description en None o una cadena vacía.
Cerin
7
No, solo es necesario cuando se cargan los metadatos en PyPi (que solo lo hace el desarrollador del módulo, no los usuarios). No arroja ningún error cuando el usuario instala el módulo y no tiene instalado pypandoc. He verificado este caso de uso.
Jakub Jirutka
Esto también puede generar un error en tiempo de ejecución. Para estar seguro, recomiendo hacerlo try-excepten la función.
varepsilon
1
¡Perfecto! Solo una cosa: estaba obteniendo una RuntimeError: Missing format!excepción hasta que cambié la lambda a read_md = lambda f: convert(f, 'rst', 'md'). La razón es (supongo) que le di una cadena y no un archivo (por lo que no hay extensión de archivo).
viernes
@frnhr Tu conjetura es correcta. Pandoc puede detectar automáticamente el formato de origen a partir de una extensión de archivo, pero cuando le proporcionó una cadena, debe especificar el formato explícitamente.
Jakub Jirutka
30

Actualización 2019

¡PyPI Warehouse ahora también admite la renderización de Markdown! Solo necesita actualizar la configuración de su paquete y agregarlo long_description_content_type='text/markdown'. p.ej:

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

Por lo tanto, ya no es necesario mantener el archivo README en dos formatos.

Puedes encontrar más información al respecto en la documentación. .

Respuesta anterior:

El marcado biblioteca de que usa GitHub admite reStructuredText. Esto significa que puede escribir un archivo README.rst.

Incluso admiten el resaltado de color específico de la sintaxis mediante las directivas codey code-block( ejemplo )

Cesar Canassa
fuente
6

¡PyPI ahora admite Markdown para descripciones largas!

En setup.py, establezca long_descriptionuna cadena Markdown, agregue long_description_content_type="text/markdown"y asegúrese de que está utilizando herramientas recientes ( setuptools38.6.0+, twine1.11+).

Consulte la publicación del blog de Dustin Ingram para obtener más detalles.

Petr Viktorin
fuente
¡Que bueno escuchar eso! Es interesante ver cómo se avanza a lo largo del tiempo en la comunidad de Python al observar la historia de este problema :).
jlengrand
4

Para mis requisitos, no quería instalar Pandoc en mi computadora. Usé docverter. Docverter es un servidor de conversión de documentos con una interfaz HTTP que utiliza Pandoc para esto.

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
David Miró
fuente
3

También puede interesarle el hecho de que es posible escribir en un subconjunto común para que su documento salga de la misma manera cuando se procesa como rebaja o como reStructuredText: https://gist.github.com/dupuy/1855764

Zooko
fuente
1

Me encontré con este problema y lo resolví con los dos siguientes scripts de bash.

Tenga en cuenta que tengo LaTeX incluido en mi 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

También es útil convertir a 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

Espero que eso ayude

Chet
fuente
0

Usando la pandocherramienta sugerida por otros, creé una md2rstutilidad para crear los rstarchivos. A pesar de que esta solución significa que tiene un mdy otro rst, parece ser el menos invasivo y permitiría cualquier soporte de rebajas que se agregue en el futuro. Lo prefiero a alterar setup.pyy quizás tú también lo harías:

#!/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))
robar
fuente