¿Cómo convertir Markdown a PDF sin LaTeX?

Casi todos los md to PDF existentes pasan por LaTeX: kramdown, pandoc, multimarkdown, etc.

¿Existen las opciones que no lo hacen, en cualquier idioma, por ejemplo, usando un backend como Prawn , libharu o jsPDF ?

Hasta ahora solo he encontrado:

  • asciidoctor-pdf Este conversor asciidoc basado en gambas es bastante activo y tiene muchas estrellas.

    Markdown a Asciidoc con Pandoc y luego esta es la mejor opción que he visto hasta ahora.

    Sin embargo, no es perfecto hasta el punto de estar listo para la producción profesional, en particular:

    • flota como el código y la imagen no... flotan, por lo que obtienes espacios en blanco verticales en los saltos de línea cuando tienes grandes flotadores: https://github.com/asciidoctor/asciidoctor-pdf/issues/353
    • algunas líneas tienen muy pocas palabras, pero todavía están justificadas horizontalmente, lo que genera demasiado espacio en blanco entre las palabras. TODO buscar/crear ticket.
  • Gimli , pero no parece muy activo (último compromiso hace 7 meses). ¿Back-end?

  • markdown_prawn . No muchas estrellas. Última confirmación hace 3 años.

  • Convertidor experimental Kramdown Prawn . Experimental.

  • cmarkpdf : CommonMark a PDF a través de libharu por @jgm. Experimental.

  • Impresora Qt5 Q. Utilizado por el editor Retext a través de la API PyQt5 Python . Prueba TODO. Es probable que sea análogo a una solución similar a PhantomJS pero para Qt en lugar del navegador.

Si puede convertir bien el subconjunto HTML generado de Markdown a PDF, entonces esa es una solución, pero todavía tengo que encontrar un software gratuito que lo haga correctamente. Por ejemplo, las conversiones de PhantomJS rompen los enlaces de rebajas <http://a.com>, que se muestran como texto de estilo simple en el PDF, no como enlaces en los que se puede hacer clic que se abren en el navegador preferido, que se generan a través de conversiones de LaTeX.

Posibilidades no libres:

Relacionado: Ruby only SO question .

Por qué quiero esto: LaTeX es lento, produce horribles mensajes de error, es difícil de instalar y es demasiado complejo para el pequeño subconjunto necesario para Markdown.

Soluciones parciales:

¿Te importa qué sistema operativo/aplicación web? Además, ¿qué tal el precio?
@NickWilde Cuanto más libre, mejor, cuanto más cruzado, mejor. El soporte de Linux me haría feliz. Pero quiero escuchar todas las opciones =)
Ah, y olvidé preguntar qué tipo de interfaz desea: CLI o GUI. Si CLI tengo una opción que estoy bastante seguro de que no usa LaTex.
@NickWilde Prefiero CLI, pero una vez más, quiero conocerlos todos.
prefiero CLI, entonces eso es genial: D... la respuesta viene enseguida.
ReText es un editor de Markdown que tiene exportación de PDF incorporada. Funciona bastante bien en mi experiencia. Del sitio web: "Los usuarios de Debian y Ubuntu pueden instalar ReText usando el apt-get install retextcomando".
@David gracias por el consejo. Lo he investigado y usa Qt para hacer el trabajo. Agregado a la pregunta también.

Respuestas (7)

Node.js Package Markdown-PDF debería funcionar bien. He estado usando el paquete Grunt de eso , pero solo por el bien de una buena respuesta, simplemente ejecuté rápidamente el original a través de la línea de comando ; y sí, funciona muy bien.

Entonces, para usar la CLI de Markdown-PDF solo:

  1. Instale Node.js (si es necesario)
  2. Instale Markdown-PDF - desde cmdline simplemente ejecutenpm install -g markdown-pdf
  3. ejecutar markdown-pdf -o readme.pdf readme.md(o cualquier origen y destino y otras opciones que desee; consulte Opciones de CLI para obtener todos los detalles de lo que puede especificar).

Es de código abierto (con licencia MIT) y tiene un repositorio de Github , es gratuito y, por lo que he encontrado, es bastante rápido.

Puede haber un pequeño problema con la obtención de imágenes de los dominios https://, pero no he investigado qué hay allí: una de mis imágenes no se está cargando, por lo que es muy probable que sea algo divertido en mi md, pero hay un ligero posibilidad de que sea un error.

Un error importante : no se crean enlaces en los que se pueda hacer clic.

Backend: a HTML usando Marked, luego PhantomJS. @NickWilde: ¿sus <http://a.com>enlaces sobreviven en el PDF? Solo recibo imágenes. No estoy seguro si esto es posible con PhantomJS.
hmm... No tengo ningún enlace de tipo <link> - solo enlaces de tipo [name](link) o [name][id] y funcionan. Ambos tienen el texto del enlace después del enlace, que no es bonito, pero probablemente podría arreglarse con un pequeño ajuste. Se me olvidó mencionarlo.
¿Puedes hacer clic en el enlace una vez y se abre en el navegador? ¿Qué visor de PDF estás usando? Para Evince y Okular solo obtengo texto sin formato. He probado y lo mismo para [](), el texto aparece a la derecha, lo cual es un buen diseño ya que no se puede hacer clic en los enlaces (para mí).
Estoy en Windows (7)/Adobe Acrobat (XI): no se puede hacer clic en el título, el texto del enlace sí (y un clic se abre en el navegador preferido (después de la advertencia de seguridad de Adobe sobre la apertura de enlaces). Para mí, eso es menor, sin embargo, puedo vea que podría ser un problema de última hora para algunos casos de uso.
A ver si puedo solucionarlo luego
Investigado y parece que es el backend QT para phantomjs (como si no se pudiera arreglar fácilmente ). Así que editando un poco.

Yo personalmente soy un gran fan de pandoc.

Pandoc es la herramienta navaja del "ejército suizo" de conversiones de formato:

  • El formato de entrada de fuente central admitido es Markdown(incluido cualquiera de los principales "dialectos" de MD, como los sabores de GitHub y PHP, además de varias extensiones especiales). Otros formatos de entrada son: HTML, rST, Textile, DocBook XML, MediaWiki.
  • Como formatos de salida admite: ConTeXt, LaTeX, PDFy Beamer PDF(aunque requiere LaTeX en segundo plano), MediaWiki, DOCX, DocBook, rST, Textile, ASCIIDoc, texinfo, org(modo Emacs Org), S5(diapositivas HTML), Slidy(diapositivas HTML), Slideous(diapositivas HTML), ImpressJS(diapositivas HTML ), DZSlides(diapositivas HTML), HTML, HTML5, EPUB, EPUB3
    ...y: manpage(página de manual de GROFF) y ODT(Texto OpenDocument).

¿Sigues conmigo? Bien.

¿Te diste cuenta de los dos últimos, manpagey ODT?

Bueno, estos son los dos formatos de salida de los que personalmente "abuso" como formatos intermedios para llegar a PDF para documentos finales cuando no quiero que LaTeX esté involucrado.

He automatizado mi flujo de trabajo y cadena de procesos con la ayuda de un Makefile . Así que solo necesito escribir make mydoc.latexpdf, o make mydoc.odtpdf, o make mydoc.manpdf. El Makefile está configurado para buscar una entrada de mydoc.mmd, y luego activa los comandos apropiados: pandocpara crear el PDF directamente (que en segundo plano primero se convierte a LaTeX y luego se ejecuta pdflatexsolo), ODT o página de manual. Luego, el siguiente comando es crear el formato final:

  • Para mi .odtpdfobjetivo, ejecuta LibreOffice en modo sin cabeza. Estas son las líneas de comando básicas que uso para (estoy en OS X, por lo que para Linux o Windows tendrá que adaptar las rutas en consecuencia). Atención, el comando está en la sintaxis de Makefile; no se puede usar directamente en Shell sin una adaptación previa:

    (cd /Applications/LibreOffice.app/Contents/MacOS; \
    ./soffice "-env:UserInstallation=file:///tmp/LibO_Conversion__$(USER)" \
            --headless \
            --convert-to pdf:writer_pdf_Export \
            --outdir $(CURRDIR)/$(FINAL)  $(CURRDIR)/$(BUILD)/$(subst .odtpdf,.odt,$@) ; \
    cd - ; )
    
  • Para mi .manpdfobjetivo, lo usa man -tpara crear PostScript a partir del archivo de salida de la página de manual de Pandoc, luego usa Ghostscript para crear el PDF. Por lo tanto, ejecuta:

    man -t <pandoc's manpage output file> \
     | gs -o ${HOME}/<pandoc-sourcedoc-name>.pdf -sDEVICE=pdfwrite -
    

Personalice la apariencia de su salida ODT

La ruta sin LaTeX a PDF a través de ODT es la más "sexy" para mí...

  • ...porque Pandoc sabe cómo aplicar algunos buenos estilos personalizados a una ODT de destino si solo estos estilos se definen correctamente en un myreference.odtarchivo ! (Estos estilos, por supuesto, también se transferirán al PDF).

Luego puedo ejecutar el comando Pandoc (a través de Makefile o en Shell) para crear un ODT a mi gusto, completo con las fuentes, tamaños y colores que prefiero, con los tamaños de página y encabezados de página, pies de página o fondos que definí (nuevamente : ¡Sintaxis de Makefile!):

     pandoc \
            --toc \
            --toc-depth=4 \
            --to=odt \
            --chapters \
            --filter=pandoc-citeproc \
            --standalone \
            --reference-odt=$(RESOURCES)/myreference.odt \
            --from=markdown+mmd_title_block+pipe_tables+grid_tables+tex_math_dollars+raw_tex+footnotes+inline_notes+citations+link_attributes \
            --bibliography=$(RESOURCES)/my.bib \
            --csl=$(RESOURCES)/kp.csl \
            --number-sections \
            --output=./$(BUILD)/$@ \
            $<

El --from=markdown+...+...+parámetro le dice a Pandoc que acepte varias extensiones de sintaxis Markdown que me gusta usar en mis archivos fuente MD.

El dulce secreto para obtener los estilos en el documento ODT radica en el --reference-odt=/path/to/myreference.odtparámetro de línea de comando.

¡La salida ODT funciona incluso con referencias y bibliografía (si su entrada Markdown está escrita correctamente para esto) !


¿Usas Windows?

En principio, este flujo de trabajo también debería funcionar en Windows, porque Pandoc también se ejecuta en Windows. He ejecutado Pandoc en Windows antes, pero no he configurado un flujo de trabajo completamente automático, primero " Pandoc: Markdown -> ODT " , luego " .\soffice: ODT-> PDF " basado en un Makefile aquí, sin embargo...

Pero es posible que desee explorar otro camino en Windows :

  • primero cree una salida DOCX desde Pandoc;
  • luego convierta el DOCX a PDF (automáticamente o interactivamente a través de WinWord).

Sí, también puede personalizar los estilos de los archivos de salida DOCX usando el --reference-docx=my-reference.docxinterruptor. Simplemente cree my-reference.docxprimero un archivo que use exactamente los estilos que desea. ¡Pandoc luego los extraerá del documento de referencia y los aplicará al DOCX de salida que genera!

Desde allí, puede ver cómo convertir el archivo DOCX intermedio a PDF. Esto también se puede hacer automáticamente: también puede considerar OfficeToPDF.exe . Está alojado en CodePlex, licenciado con la licencia Apache 2.0 y disponible en binario y en código fuente.

Finalmente: asegúrese de usar la última y mejor versión de Pandoc (actualmente v1.17.0.3 o posterior ); se han agregado muchas funciones en los últimos meses, especialmente. cuando se trata de salida DOCX!

Mi archivo de rebajas contiene un carácter Unicode y bloques Pandoc. ¿Cómo podría arreglar eso?
Agregue --latex-engine=xelatexo --latex-engine=lualatexa su comando Pandoc. El motor (predeterminado) pdflatexno puede manejar Unicode.

He investigado otra opción. Comparado con Markdown-PDF :

  • Ventajas:
    • En realidad hace enlaces adecuados.
    • En realidad un poco más rápido de ejecutar
  • Contras:
    • No tan "bonito": excepto por los enlaces, todo se ve mejor con Markdown-PDF. Sin embargo, esto se solucionaría fácilmente agregando algo de CSS al HTML antes de la generación del PDF*.
    • La instalación es más complicada.

Esta también es una solución basada en Nodejs que utiliza los paquetes de nodos Marked y wkhtmltopdf .

Instalación:

  • Instala Nodejs .
  • Instalar Marcado - más fácil a través de la línea de comandos:npm -g install marked
  • Instale wkhtmltopdf NPM - más fácil a través de la línea de comandos:npm -g install wkhtmltopdf
  • Instale los archivos principales de wkhtmltopdf ; no hay ningún instalador disponible.
  • Agregue el directorio bin wkhtmltopdf a la RUTA

Uso:

Para usar toma dos llamadas CLI. Por supuesto, puede guardar esto como un archivo por lotes y ejecutarlo.

marked input.md -o output.html
wkhtmltopdf input.html output.pdf

* Debido a que los enlaces funcionan, puedo cambiar a este método en lugar de Markdown-PDF, en cuyo caso probablemente escribiré un contenedor para agregar algo de CSS (con la opción de agregar un valor predeterminado sensible o definido por el usuario). El contenedor también lo convertiría en una llamada en lugar de dos para ejecutar y probablemente podría convertirlo en un cmd de instalación npm en lugar de la instalación manual. Si/cuando lo haga, lo compartiré aquí.

Lo siguiente se basa en la parte superior de wkhtmltopdf: github.com/pdfkit/pdfkit . No lo he intentado, pero todavía tengo que entender qué hace que wkhtmltopdf no lo haga.
Parece que es un envoltorio Ruby para wkhtmltopdf
No lo he probado, así que no puedo revisar qué tan bien funciona, pero esto no funciona muy bien en el lado de la instalación: ¡el repositorio es de 1 Gb e incluye una bifurcación Qt de 0.5 Gb!
Er, supongo que debe ser para PDFKit en lugar de mi recomendación, porque mi recomendación tiene un tamaño de descarga total de menos de 30 mb - ~ 6 mb Nodejs, ~ 16 mb wkhtmltopdf y luego los envoltorios que son relativamente pequeños (node-wkhtmltopdf es 2.8kb ).
Ah, estaba hablando del repositorio wkhtmltopdf , pero tal vez incluyan toneladas de cosas que no están instaladas. Gracias.
Sí, eso definitivamente no está en el lanzamiento: esa bifurcación de QT es probablemente para hacer que los enlaces en el pdf funcionen; y tiene que ser una bifurcación completa, aunque solo se use una fracción en el lanzamiento.
El único problema grave que he encontrado con marcado es que la salida html no tiene un encabezado de conjunto de caracteres, por lo que el html está mal representado, por ejemplo, la palabra Corrección se representa Corrección. Y el archivo pdf resultante también está mal generado. ¿Alguna idea?

Acabo de convertir de HTML en su lugar. Esto funciona para mis necesidades:

https://github.com/dompdf/dompdf

Descubrí que, en general, Markdown no es un buen formato para convertir a PDF, ya que no es compatible con CSS nativo. Aquí está el script que uso:

<?php
require 'dompdf/autoload.inc.php';
use Dompdf\Dompdf;

$dompdf = new Dompdf();
$dompdf->getOptions()->setIsFontSubsettingEnabled(true);
$get = file_get_contents('index.html');
$dompdf->loadHtml($get);

$dompdf->render();
$put = $dompdf->output();
file_put_contents('index.pdf', $put);

Esta solución solo necesita PHP (25 MB) y DomPdf (4 MB), por lo que es bastante liviana en comparación con otras opciones.

Para construir sobre la solución de @nick-wilde, si está usando gruñido, hay complementos tanto para marcado como para wkhtmltopdf:

Después de instalar el wkhtmltopdfbinario principal , puede instalar los complementos usando npm:

npm install grunt-marked --save-dev
npm install grunt-wkhtmltopdf --save-dev

Luego usa algo como esto en tu Gruntfile.js:

marked: {
  std : {
    files: {
      'out.html' : ['src.md']
    }
  }
},

wkhtmltopdf: {
  std : {
    src: 'out.html',
    dest: 'out.pdf'
  }
},

Luego, en su compilación, simplemente llame a los dos en sucesión:

grunt.registerTask('build', ['marked', 'wkhtmltopdf']);

Si quieres que se vea bonito, tendrás que jugar más con la markedconfiguración, pero estoy seguro de que es factible.

Recientemente creé un servicio para convertir documentos de descuento a PDF. Es compatible con la reducción con sabor a GitHub, así como con el resaltado de sintaxis. El servicio se encuentra en: http://markdown2pdf.com

¿Es de código abierto? ¿Cuál es la técnica subyacente?

No es sexy, pero AbiWord convertirá HTML a PDF.

Entonces, asumiendo que tienes instalado abiword:

markdown some.md > some.html  
abiword -t pdf -o some.pdf some.html
Gracias por el consejo. Tal vez alguien pueda decirnos qué tipo de backend usa: genérico o reutilizar una herramienta de terceros.