#!/usr/bin/env ruby # encoding: UTF-8 # coding: UTF-8 # Instalación: # sudo wget https://gitlab.com/snippets/2189719/raw /usr/local/bin && sudo mv /usr/local/bin/raw /usr/local/bin/export-pdf-li && sudo chmod +755 /usr/local/bin/export-pdf-li require 'fileutils' # Variables $file = '' $title = '' $author = '' $press = '' $date = '' $year = Time.now.year.to_s $ragged = false $default = true $just_tex = false $leave_h1 = false $numbered = false $en_date = false $no_day = false $bib = false $script = __FILE__.gsub(/.*?\//, '') $tmp_dir = "tmp_#{$script}" $tem_name = "template_#{$script}.tex" # Plantillas # Plantilla por defecto $template = <<-HEREDOC % Universal settings \\documentclass[11pt,extrafontsizes,openany]{book} \\usepackage[utf8]{inputenc} \\usepackage[T1]{fontenc} \\usepackage[spanish,es-noindentfirst]{babel} \\usepackage[osf]{Alegreya} % PACKAGE DEFINITION % Typographical packages \\usepackage{microtype} % for micro-typographical adjustments \\usepackage{setspace} % for line spacing \\usepackage{lettrine} % for drop caps and awesome chapter beginnings \\usepackage[md]{titlesec} % for manipulation of chapter titles \\usepackage{enumitem} % for lists \\usepackage{geometry} % page size \\usepackage{fancyhdr} % headers and footers \\usepackage{tocloft} % toc \\usepackage[font=small,labelformat=empty]{caption} % captions \\usepackage{chngcntr} % change numnering behavior \\usepackage{csquotes} % change quoting behavior \\usepackage{emptypage} \\usepackage{calc} \\usepackage{hologo} \\usepackage[pdfencoding=auto,hidelinks]{hyperref} \\usepackage{ragged2e} \\usepackage{graphicx} % Bibliography \\usepackage[style=apa,backend=biber]{biblatex} % for bibliography @bibliography % Meta \\newcommand{\\mytitle}{\\emph{@title}} \\newcommand{\\myauthor}{@author} \\newcommand{\\press}{@press} \\newcommand{\\printyear}{@year} \\newcommand{\\printdate}{@date} \\if\\myauthor\\empty \\newcommand{\\myauthor}{@title} \\fi % Page size \\geometry{ paperwidth=5.5in, paperheight=8.5in, inner=1in, outer=1in } % TOC \\addto\\captionsspanish{ \\renewcommand{\\contentsname}{\\textsc{Índice general}} } \\renewcommand{\\cfttoctitlefont}{\\normalfont\\Large} \\renewcommand{\\cftpartfont}{\\normalfont} \\renewcommand{\\cftpartpagefont}{\\normalfont} \\renewcommand{\\cftchapfont}{\\vspace{-1em}\\footnotesize\\normalfont} \\renewcommand{\\cftchappagefont}{\\normalfont} % Defining the title and the author \\title{\\mytitle} \\author{\\myauthor} \\date{@year} % Custom second title page \\makeatletter \\newcommand*\\halftitlepage{\\begingroup % Misericords, T&H p 153 \\setlength\\drop{0.1\\textheight} \\begin{center} \\vspace*{\\drop} \\rule{\\textwidth}{0in}\\par {\\large\\textsc\\thetitle\\par} \\rule{\\textwidth}{0in}\\par {\\textsc\\theauthor\\par} \\vfill \\end{center} \\endgroup} \\makeatother % Part title display \\makeatletter \\renewcommand\\part{% \\if@openright \\cleardoublepage \\else \\clearpage \\fi \\thispagestyle{empty} \\if@twocolumn \\onecolumn \\@tempswatrue \\else \\@tempswafalse \\fi \\null\\vfil \\secdef\\@part\\@spart} \\makeatother \\titleformat {\\part} [display] {\\normalfont\\scshape\\Large} {\\Huge\\thepart\\centering} {0pt} {\\centering}[] % Reset chapter number in each part \\counterwithin*{chapter}{part} % Chapter title display \\titleformat {\\chapter} [display] {\\normalfont\\scshape\\Large} {\\Huge\\thechapter\\centering} {0pt} {\\centering}[] % Quotation \\renewenvironment{quote} {\\small\\list{}{ \\listparindent=1.5em \\leftmargin=.5cm \\rightmargin=0cm \\parsep=0cm}% \\item\\relax} {\\endlist} % Typographical settings for the body text \\setlength{\\parskip}{0em} \\linespread{1.09} % Modify spaces between headers \\titlespacing*{\\chapter} {0pt}{2em}{1em} \\titlespacing*{\\section} {0pt}{1em}{1em} % HEADER AND FOOTER MANIPULATION \\renewcommand{\\headrulewidth}{0.0pt} \\renewcommand{\\footrulewidth}{0.0pt} \\setlength{\\RaggedRightParindent}{\\parindent} % THE DOCUMENT \\begin{document} % Preliminares @ragged \\frontmatter \\pagestyle{empty} \\maketitle % Legal \\begin{center} \\footnotesize \\vspace*{\\fill} \\mytitle \\\\ \\myauthor \\if\\press\\empty \\else \\vskip 1em Edición: \\press \\fi \\vskip 1em Última edición: \\printdate \\vskip 1em Permitida su reproducción y difusión por cualquier \\\\ medio mecánico o electrónico sin la autorización \\\\ escrita del titular de los derechos. \\vskip 1em Hecho en México / \\emph{Made in Mexico} \\normalsize \\end{center} % Principal \\mainmatter \\newgeometry{ inner=.75in, outer=1.25in } \\include{@file} % Finales \\backmatter @printbibliography % Índice % Descomentar las siguientes líneas si se quiere índice %\\pagestyle{fancy} %\\fancyhead{} %\\fancyhead[CO]{\\footnotesize\\textsc{Índice general}\\normalsize} %\\fancyhead[CE]{\\footnotesize\\textsc{\\myauthor}\\normalsize} %\\begin{center} % \\tableofcontents %\\end{center} %\\tocloftpagestyle{empty} % Descomentar para enviar colofón a una página par %\\cleardoublepage\\pagestyle{empty}\\mbox{} % +2 páginas blancas %\\clearpage\\pagestyle{empty}\\mbox{} % +1 página blanca % Colofón \\newgeometry{ inner=1.5in, outer=1.5in } \\pagestyle{empty} \\vspace*{\\fill} \\begin{center} \\mytitle \\hspace{.1em} se terminó de componer el \\printdate. Documento hecho con \\fontfamily{cmr}\\LaTeX. \\end{center} \\end{document} % END THE DOCUMENT HEREDOC # Cabeza del documento $header = <<-HEREDOC \\chapter*{@title} \\addcontentsline{toc}{chapter}{@tex_chapter} \\pagestyle{fancy} \\fancyhead{} \\fancyhead[CO]{\\footnotesize\\textsc{@title}\\normalsize} \\fancyhead[CE]{\\footnotesize\\textsc{\\myauthor}\\normalsize} \\vskip 3em HEREDOC # Definiciones # Obtiene el mes def get_month m if m == 1 return 'enero' elsif m == 2 return 'febrero' elsif m == 3 return 'marzo' elsif m == 4 return 'abril' elsif m == 5 return 'mayo' elsif m == 6 return 'junio' elsif m == 7 return 'julio' elsif m == 8 return 'agosto' elsif m == 9 return 'septiembre' elsif m == 10 return 'octubre' elsif m == 11 return 'noviembre' elsif m == 12 return 'diciembre' end end # Incorpora modificaciones a los párrafos def get_classes txt clean = txt.gsub(/((.|\n)*?)\\{\s*(\.(.|\n)*?)\\}((.|\n)*$)/, '\1').strip rest = txt.gsub(/((.|\n)*?)\\{\s*(\.(.|\n)*?)\\}((.|\n)*$)/, '\5').strip classes = txt.gsub(/((.|\n)*?)\\{\s*(\.(.|\n)*?)\\}((.|\n)*$)/, '\3').split(/\s+/) avoid = false # Evita falsos positivos classes.each do |c| if c !~ /^\./ || c =~ /\s/ avoid = true end end if !avoid # Eliminación de sangrados classes.each do |c| if c =~ /\.sin-sangria/ clean = "\\noindent " + clean end end # Alineaciones classes.each do |c| if c == '.derecha' || c == '.izquierda' || c == '.centrado' if c == '.derecha' align = "flushright" elsif c == '.izquierda' align = "flushleft" elsif c == '.centrado' align = "center" end clean = "\\begin{" + align + "}\n" + clean + "\n\\end{" + align + "}" elsif c == ".frances" clean = "\\hangindent=\\parindent\n\\hangafter=1\n\\noindent " + clean end # Reacomoda los bloques de cita if clean =~ /\\begin{quote}/ clean = "\\begin{quote}\n" + clean.gsub(/\\begin{quote}\s*/, '') end if clean =~ /\\end{quote}/ clean = clean.gsub(/\s*\\end{quote}/, '') + "\n\\end{quote}" end end # Espacios verticales classes.each do |c| if c =~ /\.espacio-arriba\d+/ num = c.gsub(/.*?(\d+)/, '\1').to_i vskip = "\\vskip " + num.to_s + "em\n" clean = vskip + clean end end clean = clean + rest end return clean end # Modifica tildes y esas cosas para la tabla de contenidos def tex_transliterate s chars = s.split('') change = [] bib = [ ['á', "\\\\'{a}"],['é', "\\\\'{e}"],['í', "\\\\'{i}"], ['ó', "\\\\'{o}"],['ú', "\\\\'{u}"],['ü', "\\\\\"{u}"], ['ñ', "\\\\~{n}"],['Á', "\\\\'{A}"],['É', "\\\\'{E}"], ['Í', "\\\\'{I}"],['Ó', "\\\\'{O}"],['Ú', "\\\\'{U}"], ['Ü', "\\\\\"{U}"],['Ñ', "\\\\~{N}"] ] chars.each do |c| bib.each do |x| if c == x.first c = x.last end end change.push(c) end return change.join('') end # Genera la estructura para los gráficos def generate_graphics s p = $just_tex ? '' : '../' return "\\bigskip\\noindent\\includegraphics[width=\\textwidth,keepaspectratio]{" + p + s + "}\\bigskip" end # Genera la plantilla por defecto def print_template file = File.open('template.tex', 'w:utf-8') file.puts $template file.close puts "Archivo de la plantilla guardado en <#{Dir.pwd}/template.tex>." abort end begin ARGV.each do |arg| if arg =~ /^-h$/ || arg =~ /^--help$/ puts "#{$script} genera un documento PDF con modificaciones hechas a Pandoc." puts "\nUso:" puts " #{$script} [argumentos] [archivo]" puts "\nArgumentos:" puts " --title=\"text\" Título del texto" puts " --author=\"text\" Autor del texto" puts " --press=\"text\" Editorial del texto" puts " --template=\"path\" Plantilla para el documento" puts " --bib=\"path\" Bibliografía para el documento" puts " --ragged-right Justificación en bandera" puts " --just-tex Solo genera los archivos TeX" puts " --leave-h1 Respeta los h1 del documento" puts " --numbered Numeración en partes y capítulos" puts " --get-template Genera la plantilla por defecto" puts " --en-date Genera fechas en formato inglosajón" puts " --no-day No incluye el día en la fecha" puts " -h | --help Muestra esta ayuda" puts "\nEjemplos:" puts " #{$script} archivo.md" puts " #{$script} --template=../platila.tex archivo.html" puts " #{$script} --template=../platila.tex --ragged-right archivo.xhml" puts "\nFormatos de archivos aceptados: MD, HTML o XHTML. Por defecto solo deja un h1 con el título del documento" abort end # Cambia la cantidad de caracteres por línea de texto y detecta si se aplicará a todos los bloques if arg =~ /--template/ $template = File.absolute_path(arg.gsub(/--\w+="*([^"]*?)"*/,'\1')) $default = false elsif arg =~ /--title/ $title = arg.gsub(/--\w+="*([^"]*?)"*/,'\1') elsif arg =~ /--author/ $author = arg.gsub(/--\w+="*([^"]*?)"*/,'\1') elsif arg =~ /--press/ $press = arg.gsub(/--\w+="*([^"]*?)"*/,'\1') elsif arg =~ /--bib/ $bib = arg.gsub(/--\w+="*([^"]*?)"*/,'\1') elsif arg =~ /--ragged-right/ $ragged = true elsif arg =~ /--just-tex/ $just_tex = true elsif arg =~ /--leave-h1/ $leave_h1 = true elsif arg =~ /--numbered/ $numbered = true elsif arg =~ /--en-date/ $en_date = true elsif arg =~ /--no-day/ $no_day = true elsif arg =~ /--get-template/ print_template end end $file = ARGV.last # Comprueba el archivo if !File.file?($file) || !(File.extname($file) == '.md' || File.extname($file) == '.html' || File.extname($file) == '.xhtml') raise else $file = File.absolute_path($file) end # Obtiene la fecha if $en_date if $no_day $date = Time.now.strftime("%B, %Y") else $date = Time.now.strftime("%B %d, %Y") .gsub(/0(\d,)/, '\1') end else if !$no_day $date = Time.now.day.to_s + ' de ' end $date += get_month(Time.now.month) + ' del ' + Time.now.year.to_s end # Produce una carpeta temporal Dir.mkdir($tmp_dir) Dir.chdir($tmp_dir) # Modifica la etiqueta para los saltos de línea md = File.read($file) .gsub(/\s*\\\n\s*/, ' @line-break ') tmp = File.open(File.basename($file), 'w:utf-8') tmp.puts md tmp.close # Convierte el archivo a .tex system("pandoc #{File.basename($file)} -o #{File.basename($file, '.*')}.tex") # Obtiene el texto procesado por pc-pandog raw = File.read(File.basename($file, '.*') + '.tex') # Obtiene el título limpio regex = /^(.|\n)*?\\section{((.|\n)*?)}\\label(.|\n)*$/ if $title == '' $title = raw.gsub(regex, '\2') .gsub(/\n/, ' ') .gsub(/\\texorpdfstring{(.*?)}{.*}/, '\1') end title = $header.gsub('@title', $title) .gsub('@tex_chapter', tex_transliterate($title)) # Limpia cosillas clean = raw.gsub('@line-break', '\\\\\\') .gsub(/\+\+\+((.|\n)*?)\+\+\+/,){|e| e.downcase } .gsub(/\+\+\+((.|\n)*?)\+\+\+/, '\\textsc{' + '\1' + '}') .gsub(/\\hypertarget{.*?%/, '') .gsub(/\\label{.*?}}/, '') .gsub('subsection', 'subsection*') .gsub("\\tightlist\n", '') .gsub("\\def\\labelenumi{\\arabic{enumi}.}\n", '') .gsub('begin{itemize}', 'begin{itemize}[noitemsep]') .gsub('begin{enumerate}', 'begin{enumerate}[noitemsep]') .gsub(/\\includegraphics{(.*?)}/, generate_graphics('\1')) .gsub('LaTeX', '\\LaTeX') .gsub('TeX', '\\teX') .gsub("\n\n\n", "\n\n") .gsub('{[}', '[') .gsub('{]}', ']') .gsub(/\\end{quote}\s*\\begin{quote}/, '') .gsub(/@textcite\s+\[([^\[]+?)\]/, '\\textcite{' + '\1' + '}') .gsub(/@parencite\s+\[([^\[]+?)\]/, '\\parencite{' + '\1' + '}') .gsub(/\\texorpdfstring{((.|\n)*?)}{.*}/,) do |e| e.gsub(/\\texorpdfstring{((.|\n)*?)}{.*}/, '\1}') .gsub(/\n/, ' ') end # Limpieza específica del español if !$en_date clean = clean.gsub('---', '"+--') end # Da formato a los títulos if !$leave_h1 clean = clean.gsub(/\\section{((.|\n)*?)}\s*\n/, '') .gsub(/\n{3,}/, "\n\n") clean = title + "\n" + clean.strip else clean = clean.gsub(/\\section{((.|\n)*?)}\s*\n/,) do |e| if e =~ /@part/ n = $numbered ? '' : '*' e.gsub(/\s*@part/, '').gsub(/section{/, 'part' + n + '{') else $header .gsub('@title', e.gsub(/\\section{((.|\n)*?)}\s*\n/, '\1') .gsub(/\n/, ' ')) .gsub('@tex_chapter', tex_transliterate( e.gsub(/\\section{((.|\n)*?)}\s*\n/, '\1') .gsub(/\n/, ' '))) end end end if $numbered clean = clean.gsub('chapter*{', 'chapter{') .gsub(/\\addcontentsline{toc}{chapter}{.*?}\n/, '') end # Modifica alineaciones o espacios verticales final = [] clean = clean.split(/\n{2,}/) clean.each do |b| b = b.strip if b =~ /{\s*\.(.|\n)*?}/ final.push(get_classes(b)) else final.push(b) end end # Guardado del archivo file = File.open(File.basename($file, '.*') + '.tex', 'w:utf-8') file.puts final.join("\n\n").strip file.close if $default template = $template else template = File.read($template) end # Modifica la plantilla template = template.gsub('@title', $title) .gsub('@press', $press) .gsub('@year', $year) .gsub('@date', $date) .gsub('@ragged', $ragged ? '\\RaggedRight' : '') .gsub('@file', File.basename($file, '.*')) if $author == '' template = template.gsub('@author', $title) else template = template.gsub('@author', $author) end # Añade bibliografía if $bib template = template.gsub('@bibliography', "\\bibliography{../#{$bib}}") template = template.gsub('@printbibliography', "\\printbibliography") else template = template.gsub('@bibliography', '') template = template.gsub('@printbibliography', '') end # Guardado de la plantilla file = File.open($tem_name, 'w:utf-8') file.puts template file.close if !$just_tex # Compone el PDF system("lualatex -synctex=1 -interaction=batchmode #{File.basename($tem_name, '.*')}.tex") if $bib system("biber #{File.basename($tem_name, '.*')}") system("lualatex -synctex=1 -interaction=batchmode #{File.basename($tem_name, '.*')}.tex") end system("lualatex -synctex=1 -interaction=batchmode #{File.basename($tem_name, '.*')}.tex") # Compone la imposición system("pdfbook2 -n -p letterpaper #{File.basename($tem_name, '.*')}.pdf") # Mueve los archivos FileUtils.mv(File.basename($tem_name, '.*') + '.pdf', '../' + File.basename($file, '.*') + '.pdf') FileUtils.mv(File.basename($tem_name, '.*') + '-book.pdf', '../' + File.basename($file, '.*') + '_imposition.pdf') else FileUtils.mv(File.basename($file, '.*') + '.tex', '..') FileUtils.mv(File.basename($tem_name), '..') end # Regresa a la raíz Dir.chdir('..') rescue puts "ERROR: el archivo no pudo ser analizado, revisa su formato o ejecuta: #{$script} --help." end # Elimina la carpeta temporal FileUtils.rm_rf($tmp_dir)