LaTeX rendering of Markdown documents

Introduced classes

class LatexRenderer

markdown2 :: LatexRenderer

Markdown document renderer to LaTeX

Redefined classes

redef class MdBlockQuote

markdown2 :: markdown_latex_rendering $ MdBlockQuote

A block quote
redef class MdCode

markdown2 :: markdown_latex_rendering $ MdCode

An inline code string
redef class MdDocument

markdown2 :: markdown_latex_rendering $ MdDocument

A Markdown document
redef class MdEmphasis

markdown2 :: markdown_latex_rendering $ MdEmphasis

An emphasis
redef class MdFencedCodeBlock

markdown2 :: markdown_latex_rendering $ MdFencedCodeBlock

A code block that starts with a fence
redef class MdHeading

markdown2 :: markdown_latex_rendering $ MdHeading

A heading
redef class MdHtmlBlock

markdown2 :: markdown_latex_rendering $ MdHtmlBlock

An html block
redef class MdHtmlInline

markdown2 :: markdown_latex_rendering $ MdHtmlInline

An inlined html string
redef class MdImage

markdown2 :: markdown_latex_rendering $ MdImage

An image
redef class MdIndentedCodeBlock

markdown2 :: markdown_latex_rendering $ MdIndentedCodeBlock

A block code that starts with an indent
redef abstract class MdLineBreak

markdown2 :: markdown_latex_rendering $ MdLineBreak

A line break (soft or hard)
redef class MdListItem

markdown2 :: markdown_latex_rendering $ MdListItem

An ordered or unordered list item block
redef abstract class MdNode

markdown2 :: markdown_latex_rendering $ MdNode

An abstract node
redef class MdOrderedList

markdown2 :: markdown_latex_rendering $ MdOrderedList

An ordered list block
redef class MdParagraph

markdown2 :: markdown_latex_rendering $ MdParagraph

A paragraph block
redef class MdStrike

markdown2 :: markdown_latex_rendering $ MdStrike

Striked text
redef class MdStrongEmphasis

markdown2 :: markdown_latex_rendering $ MdStrongEmphasis

A strong emphasis token
redef class MdSuper

markdown2 :: markdown_latex_rendering $ MdSuper

Super text
redef class MdText

markdown2 :: markdown_latex_rendering $ MdText

A raw text token
redef class MdUnorderedList

markdown2 :: markdown_latex_rendering $ MdUnorderedList

An unordered list

All class definitions

class LatexRenderer

markdown2 $ LatexRenderer

Markdown document renderer to LaTeX
redef class MdBlockQuote

markdown2 :: markdown_latex_rendering $ MdBlockQuote

A block quote
redef class MdCode

markdown2 :: markdown_latex_rendering $ MdCode

An inline code string
redef class MdDocument

markdown2 :: markdown_latex_rendering $ MdDocument

A Markdown document
redef class MdEmphasis

markdown2 :: markdown_latex_rendering $ MdEmphasis

An emphasis
redef class MdFencedCodeBlock

markdown2 :: markdown_latex_rendering $ MdFencedCodeBlock

A code block that starts with a fence
redef class MdHeading

markdown2 :: markdown_latex_rendering $ MdHeading

A heading
redef class MdHtmlBlock

markdown2 :: markdown_latex_rendering $ MdHtmlBlock

An html block
redef class MdHtmlInline

markdown2 :: markdown_latex_rendering $ MdHtmlInline

An inlined html string
redef class MdImage

markdown2 :: markdown_latex_rendering $ MdImage

An image
redef class MdIndentedCodeBlock

markdown2 :: markdown_latex_rendering $ MdIndentedCodeBlock

A block code that starts with an indent
redef abstract class MdLineBreak

markdown2 :: markdown_latex_rendering $ MdLineBreak

A line break (soft or hard)
redef class MdListItem

markdown2 :: markdown_latex_rendering $ MdListItem

An ordered or unordered list item block
redef abstract class MdNode

markdown2 :: markdown_latex_rendering $ MdNode

An abstract node
redef class MdOrderedList

markdown2 :: markdown_latex_rendering $ MdOrderedList

An ordered list block
redef class MdParagraph

markdown2 :: markdown_latex_rendering $ MdParagraph

A paragraph block
redef class MdStrike

markdown2 :: markdown_latex_rendering $ MdStrike

Striked text
redef class MdStrongEmphasis

markdown2 :: markdown_latex_rendering $ MdStrongEmphasis

A strong emphasis token
redef class MdSuper

markdown2 :: markdown_latex_rendering $ MdSuper

Super text
redef class MdText

markdown2 :: markdown_latex_rendering $ MdText

A raw text token
redef class MdUnorderedList

markdown2 :: markdown_latex_rendering $ MdUnorderedList

An unordered list
package_diagram markdown2::markdown_latex_rendering markdown_latex_rendering markdown2::markdown_rendering markdown_rendering markdown2::markdown_latex_rendering->markdown2::markdown_rendering markdown2::markdown_github markdown_github markdown2::markdown_latex_rendering->markdown2::markdown_github markdown2::markdown_wikilinks markdown_wikilinks markdown2::markdown_latex_rendering->markdown2::markdown_wikilinks markdown2::markdown_ast markdown_ast markdown2::markdown_rendering->markdown2::markdown_ast markdown2::markdown_block_parsing markdown_block_parsing markdown2::markdown_github->markdown2::markdown_block_parsing markdown2::markdown_wikilinks->markdown2::markdown_block_parsing ...markdown2::markdown_ast ... ...markdown2::markdown_ast->markdown2::markdown_ast ...markdown2::markdown_block_parsing ... ...markdown2::markdown_block_parsing->markdown2::markdown_block_parsing markdown2::nitmd nitmd markdown2::nitmd->markdown2::markdown_latex_rendering a_star-m a_star-m a_star-m->markdown2::nitmd a_star-m... ... a_star-m...->a_star-m

Ancestors

module abstract_collection

core :: abstract_collection

Abstract collection classes and services.
module abstract_text

core :: abstract_text

Abstract class for manipulation of sequences of characters
module array

core :: array

This module introduces the standard array structure.
module bitset

core :: bitset

Services to handle BitSet
module bytes

core :: bytes

Services for byte streams and arrays
module circular_array

core :: circular_array

Efficient data structure to access both end of the sequence.
module codec_base

core :: codec_base

Base for codecs to use with streams
module codecs

core :: codecs

Group module for all codec-related manipulations
module collection

core :: collection

This module define several collection classes.
module core

core :: core

Standard classes and methods used by default by Nit programs and libraries.
module environ

core :: environ

Access to the environment variables of the process
module error

core :: error

Standard error-management infrastructure.
module exec

core :: exec

Invocation and management of operating system sub-processes.
module file

core :: file

File manipulations (create, read, write, etc.)
module fixed_ints

core :: fixed_ints

Basic integers of fixed-precision
module fixed_ints_text

core :: fixed_ints_text

Text services to complement fixed_ints
module flat

core :: flat

All the array-based text representations
module gc

core :: gc

Access to the Nit internal garbage collection mechanism
module hash_collection

core :: hash_collection

Introduce HashMap and HashSet.
module iso8859_1

core :: iso8859_1

Codec for ISO8859-1 I/O
module kernel

core :: kernel

Most basic classes and methods.
module list

core :: list

This module handle double linked lists
module markdown_ast

markdown2 :: markdown_ast

Markdown AST representation
module markdown_block_parsing

markdown2 :: markdown_block_parsing

Markdown blocks parsing
module markdown_inline_parsing

markdown2 :: markdown_inline_parsing

Parser for inline markdown
module math

core :: math

Mathematical operations
module native

core :: native

Native structures for text and bytes
module numeric

core :: numeric

Advanced services for Numeric types
module protocol

core :: protocol

module queue

core :: queue

Queuing data structures and wrappers
module range

core :: range

Module for range of discrete objects.
module re

core :: re

Regular expression support for all services based on Pattern
module ropes

core :: ropes

Tree-based representation of a String.
module sorter

core :: sorter

This module contains classes used to compare things and sorts arrays.
module stream

core :: stream

Input and output streams of characters
module text

core :: text

All the classes and methods related to the manipulation of text entities
module time

core :: time

Management of time and dates
module union_find

core :: union_find

union–find algorithm using an efficient disjoint-set data structure
module utf8

core :: utf8

Codec for UTF-8 I/O

Parents

module markdown_github

markdown2 :: markdown_github

Markdown Github mode
module markdown_rendering

markdown2 :: markdown_rendering

Markdown document rendering

Children

module nitmd

markdown2 :: nitmd

A Markdown parser for Nit.

Descendants

module a_star-m

a_star-m

# LaTeX rendering of Markdown documents
module markdown_latex_rendering

import markdown_rendering
import markdown_github
import markdown_wikilinks

# Markdown document renderer to LaTeX
class LatexRenderer
	super MdRenderer

	# Generate the LaTeX document wrapper
	#
	# The header includes:
	#  * document class
	#  * package importation
	#  * begin and end document directives
	var wrap_document = false is optional, writable

	# LaTeX document class
	#
	# Default is `article`.
	var document_class = "article" is optional, writable

	# LaTeX document page format
	#
	# Default is `letter`.
	var page_format = "letter" is optional, writable

	# LaTeX font size
	#
	# Default is `10pt`.
	var font_size = "10pt" is optional, writable

	# Use `listings` package for code blocks?
	var use_listings = false is optional, writable

	# LaTeX output under construction
	private var latex: Buffer is noinit

	# Render `document` as LaTeX
	redef fun render(document) do
		latex = new Buffer
		enter_visit(document)
		return latex.write_to_string
	end

	redef fun visit(node) do node.render_latex(self)

	# Indentation level
	var indent = 0

	# Add a raw `string` to the output
	#
	# Raw means that the string will not be escaped.
	fun add_raw(string: String) do latex.append string

	# Add `text` string to the output
	#
	# The string will be escaped.
	fun add_text(text: String) do latex.append latex_escape(text)

	# Add a blank line to the output
	fun add_line do
		if not latex.is_empty and latex.last != '\n' then
			latex.add '\n'
		end
	end

	# Add an indentation depending on `ident` level
	fun add_indent do latex.append " " * indent

	# Escape `string` to LaTeX
	fun latex_escape(string: String): String do
		var buffer = new Buffer
		for i in [0 .. string.length[ do
			var c = string.chars[i]
			if c == '>' then
				buffer.append "\\textgreater"
				continue
			else if c == '<' then
				buffer.append "\\textless"
				continue
			else if c == '\\' then
				buffer.append "\\textbackslash"
				continue
			else if escaped_chars.has(c) then
				buffer.add '\\'
			end
			buffer.add c
		end
		return buffer.to_s
	end

	# LaTeX characters to escape
	var escaped_chars = ['%', '$', '{', '}', '_', '#', '&']
end

redef class MdNode

	# Render `self` as HTML
	fun render_latex(v: LatexRenderer) do visit_all(v)
end

# Blocks

redef class MdDocument
	redef fun render_latex(v) do
		var wrap_document = v.wrap_document
		if v.wrap_document then
			v.add_line
			v.add_raw "\\documentclass[{v.page_format},{v.font_size}]\{{v.document_class}\}\n\n"
			v.add_raw "\\usepackage[utf8]\{inputenc\}\n"
			if v.use_listings then
				v.add_raw "\\usepackage\{listings\}\n"
			end
			v.add_raw "\\usepackage\{hyperref\}\n"
			v.add_raw "\\usepackage\{graphicx\}\n"
			v.add_raw "\\usepackage\{ulem\}\n\n"
			v.add_raw "\\begin\{document\}\n\n"
		end
		var node = first_child
		while node != null do
			v.enter_visit node
			node = node.next
			if node != null then v.add_raw "\n"
		end
		if wrap_document then
			v.add_raw "\n\\end\{document\}\n"
		end
	end
end

redef class MdHeading
	redef fun render_latex(v) do
		var level = self.level
		v.add_indent
		v.add_line
		if level == 1 then
			v.add_raw "\\section\{"
		else if level == 2 then
			v.add_raw "\\subsection\{"
		else if level == 3 then
			v.add_raw "\\subsubsection\{"
		else if level == 4 then
			v.add_raw "\\paragraph\{"
		else if level == 5 then
			v.add_raw "\\subparagraph\{"
		else
			# use bold for level 6 headings
			v.add_raw "\\textbf\{"
		end
		v.add_indent
		visit_all(v)
		v.add_raw "\}"
		v.add_line
	end
end

redef class MdBlockQuote
	redef fun render_latex(v) do
		v.add_line
		v.add_indent
		v.add_raw "\\begin\{quote\}"
		v.add_line
		v.indent += 2
		visit_all(v)
		v.indent -= 2
		v.add_line
		v.add_indent
		v.add_raw "\\end\{quote\}"
		v.add_line
	end
end

redef class MdIndentedCodeBlock
	redef fun render_latex(v) do
		var directive = if v.use_listings then "lstlisting" else "verbatim"
		v.add_line
		v.add_indent
		v.add_raw "\\begin\{{directive}\}"
		v.add_line
		v.add_raw literal or else ""
		v.add_line
		v.add_indent
		v.add_raw "\\end\{{directive}\}"
		v.add_line
	end
end

redef class MdFencedCodeBlock
	redef fun render_latex(v) do
		var info = self.info
		var lstlistings = v.use_listings
		var directive = if lstlistings then "lstlisting" else "verbatim"
		v.add_line
		v.add_indent
		v.add_raw "\\begin\{{directive}\}"
		if lstlistings and info != null and not info.is_empty then
			v.add_raw "[language={info}]"
		end
		v.add_line
		v.add_raw literal or else ""
		v.add_line
		v.add_indent
		v.add_raw "\\end\{{directive}\}"
		v.add_line
	end
end

redef class MdOrderedList
	redef fun render_latex(v) do
		var start = self.start_number
		v.add_line
		v.add_indent
		v.add_raw "\\begin\{enumerate\}"
		v.indent += 2
		v.add_line
		if start != 1 then
			v.add_indent
			v.add_raw "\\setcounter\{enum{nesting_level}\}\{{start}\}"
			v.add_line
		end
		visit_all(v)
		v.indent -= 2
		v.add_line
		v.add_indent
		v.add_raw "\\end\{enumerate\}"
		v.add_line
	end

	# Depth of ordered list
	#
	# Used to compute the `setcounter` level.
	fun nesting_level: String do
		var nesting = 1

		var parent = self.parent
		while parent != null do
			if parent isa MdOrderedList then nesting += 1
			parent = parent.parent
		end

		if nesting <= 3 then
			return "i" * nesting
		end
		return "iv"
	end
end

redef class MdUnorderedList
	redef fun render_latex(v) do
		v.add_line
		v.add_indent
		v.add_raw "\\begin\{itemize\}"
		v.add_line
		v.indent += 2
		visit_all(v)
		v.indent -= 2
		v.add_line
		v.add_indent
		v.add_raw "\\end\{itemize\}"
		v.add_line
	end
end

redef class MdListItem
	redef fun render_latex(v) do
		v.add_indent
		v.add_raw "\\item"
		v.add_line
		v.indent += 2
		visit_all(v)
		v.indent -= 2
		v.add_line
	end
end

redef class MdThematicBreak
	redef fun render_latex(v) do
		v.add_line
		v.add_indent
		v.add_raw "\\begin\{center\}\\rule\{3in\}\{0.4pt\}\\end\{center\}"
		v.add_line
	end
end

redef class MdParagraph
	redef fun render_latex(v) do
		v.add_indent
		visit_all(v)
		v.add_line
	end
end


redef class MdHtmlBlock
	redef fun render_latex(v) do
		v.add_line
		v.add_indent
		v.add_raw "\\begin\{verbatim\}"
		v.add_line
		v.add_indent
		v.add_raw literal or else ""
		v.add_line
		v.add_indent
		v.add_raw "\\end\{verbatim\}"
		v.add_line
	end
end

# Inlines

redef class MdLineBreak
	redef fun render_latex(v) do
		v.add_line
		v.add_indent
	end
end

redef class MdCode
	redef fun render_latex(v) do
		v.add_raw "\\texttt\{"
		v.add_text literal
		v.add_raw "\}"
	end
end

redef class MdEmphasis
	redef fun render_latex(v) do
		v.add_raw "\\textit\{"
		visit_all(v)
		v.add_raw "\}"
	end
end

redef class MdStrongEmphasis
	redef fun render_latex(v) do
		v.add_raw "\\textbf\{"
		visit_all(v)
		v.add_raw "\}"
	end
end

redef class MdHtmlInline
	redef fun render_latex(v) do
		v.add_raw "\\texttt\{"
		v.add_raw v.latex_escape(literal)
		v.add_raw "\}"
	end
end

redef class MdImage
	redef fun render_latex(v) do
		v.add_raw "\\includegraphics\{"
		v.add_text destination
		v.add_raw "\}"
	end

	private fun alt_text: String do
		var v = new RawTextVisitor
		return v.render(self)
	end
end

redef class MdLink
	redef fun render_latex(v) do
		if is_autolink then
			v.add_raw "\\url\{"
			v.add_text destination
			v.add_raw "\}"
			return
		end
		var title = self.title
		v.add_raw "\\href\{"
		v.add_text destination
		v.add_raw "\}\{"
		visit_all(v)
		if title != null and not title.is_empty then
			v.add_raw " ("
			v.add_text title
			v.add_raw ")"
		end
		v.add_raw "\}"
	end
end

redef class MdText
	redef fun render_latex(v) do
		v.add_text literal
	end
end

# Github mode

redef class MdStrike
	redef fun render_latex(v) do
		v.add_raw "\\sout\{"
		visit_all(v)
		v.add_raw "\}"
	end
end

redef class MdSuper
	redef fun render_latex(v) do
		v.add_raw "\\textsuperscript\{"
		visit_all(v)
		v.add_raw "\}"
	end
end

# Wikilinks

redef class MdWikilink
	redef fun render_latex(v) do
		v.add_raw "\\texttt\{"
		var title = self.title
		if title != null then
			v.add_text "{title} | "
		end
		v.add_text link
		v.add_raw "\}"
	end
end
lib/markdown2/markdown_latex_rendering.nit:15,1--438,3