Class: MaRuKu::MDDocument

Inherits:
MDElement show all
Includes:
In::Markdown, In::Markdown::BlockLevelParser, In::Markdown::SpanLevelParser
Defined in:
lib/maruku/structures.rb,
lib/maruku.rb,
lib/maruku/toc.rb,
lib/maruku/toc.rb,
lib/maruku/output/s5/to_s5.rb,
lib/maruku/output/to_latex.rb,
lib/maruku/ext/math/parsing.rb,
lib/maruku/output/to_markdown.rb,
lib/maruku/input_textile2/t2_parser.rb

Overview

This represents the whole document and holds global data.

Direct Known Subclasses

Maruku

Defined Under Namespace

Classes: Handling

Constant Summary collapse

Latex_preamble_enc_cjk =
"\\usepackage[C40]{fontenc}
\\usepackage[cjkjis]{ucs}
\\usepackage[utf8x]{inputenc}"
Latex_preamble_enc_utf8 =
"\\usepackage{ucs}
\\usepackage[utf8x]{inputenc}"
T2_Handling =
{
	nil => Handling.new(:t2_block_paragraph, true),
	'p' => Handling.new(:t2_block_paragraph, true)
}

Constants included from In::Markdown::SpanLevelParser

In::Markdown::SpanLevelParser::CharSource, In::Markdown::SpanLevelParser::Close_class, In::Markdown::SpanLevelParser::EscapedCharInInlineCode, In::Markdown::SpanLevelParser::EscapedCharInQuotes, In::Markdown::SpanLevelParser::EscapedCharInText, In::Markdown::SpanLevelParser::Punct_class, In::Markdown::SpanLevelParser::R_REF_ID, In::Markdown::SpanLevelParser::Rules, In::Markdown::SpanLevelParser::SPACE

Constants included from Strings

Strings::Abbreviation, Strings::AttributeDefinitionList, Strings::Definition, Strings::EMailAddress, Strings::FootnoteText, Strings::HeaderWithAttributes, Strings::HeaderWithId, Strings::IncompleteLink, Strings::InlineAttributeList, Strings::LinkRegex, Strings::MightBeTableHeader, Strings::Sep, Strings::TabSize, Strings::TableSeparator

Constants included from In::Markdown

In::Markdown::BlockExtensions, In::Markdown::SpanExtensions, In::Markdown::SpanExtensionsTrigger

Constants included from Out::Latex

Out::Latex::ENTITY_TABLE, Out::Latex::SAFE_CHARS, Out::Latex::TexHeaders, Out::Latex::XML_TABLE

Constants included from Out::HTML

Out::HTML::HTML4Attributes, Out::HTML::METAS, Out::HTML::Xhtml10strict, Out::HTML::Xhtml11_mathml2_svg11, Out::HTML::Xhtml11strict_mathml2

Constants included from Out::Markdown

Out::Markdown::DefaultLineLength

Constants included from MaRuKu

Globals, MagicChar, MarukuURL, S5_Fancy, S5_external, Version

Instance Attribute Summary collapse

Attributes inherited from MDElement

#doc, #meta_priv

Instance Method Summary collapse

Methods included from In::Markdown::BlockLevelParser

#eventually_comes_a_def_list, #execute_code_blocks, #expand_attribute_list, #parse_blocks, #parse_doc, #parse_text_as_markdown, #read_abbreviation, #read_ald, #read_code, #read_definition, #read_footnote_text, #read_header12, #read_header3, #read_indented_content, #read_list_item, #read_metadata, #read_paragraph, #read_quote, #read_raw_html, #read_ref_definition, #read_table, #read_text_material, #read_xml_instruction, #safe_execute_code, #search_abbreviations, #split_cells, #substitute_markdown_inside_raw_html

Methods included from In::Markdown::SpanLevelParser

#apply_one_rule, #describe_pos, #educate, #extension_meta, #interpret_extension, #is_ial, #md_al, #merge_ial, #parse_lines_as_span, #parse_span_better, #read_attribute_list, #read_em, #read_email_el, #read_emstrong, #read_footnote_ref, #read_image, #read_inline_code, #read_inline_html, #read_link, #read_quoted, #read_quoted_or_unquoted, #read_ref_id, #read_simple, #read_span, #read_strong, #read_url, #read_url_el, #read_xml_instr_span, #unit_tests_for_attribute_lists

Methods included from Helpers

#md_abbr, #md_abbr_def, #md_ald, #md_br, #md_code, #md_codeblock, #md_el, #md_em, #md_email, #md_emstrong, #md_entity, #md_foot_ref, #md_footnote, #md_header, #md_hrule, #md_html, #md_ial, #md_im_image, #md_im_link, #md_image, #md_li, #md_link, #md_par, #md_quote, #md_ref_def, #md_strong, #md_url, #md_xml_instr

Methods included from Strings

#add_tabs, #dbg_describe_ary, #force_linebreak?, #line_md_type, #normalize_key_and_value, #num_leading_hashes, #number_of_leading_spaces, #parse_email_headers, #sanitize_ref_id, #spaces_before_first_char, #split_lines, #strip_hashes, #strip_indent, #unquote

Methods included from In::Markdown

#any_matching_block_extension?, #check_block_extensions, #check_span_extensions, register_block_extension, register_span_extension

Methods inherited from MDElement

#==, #children_inspect, #children_to_s, #each_element, #generate_id, #get_setting, #inspect, #inspect2, #md_div, #md_equation, #md_inline_math, #replace_each_string, #to_s

Methods included from Errors

#create_frame, #describe_error, #maruku_error, #maruku_recover, #raise_error, #tell_user

Methods included from Out::Latex

#array_to_latex, #children_to_latex, init_entity_table, #latex_color, #latex_escape, need_entity_table, #to_latex_abbr, #to_latex_cell, #to_latex_code, #to_latex_definition, #to_latex_definition_list, #to_latex_div, #to_latex_divref, #to_latex_email_address, #to_latex_emphasis, #to_latex_entity, #to_latex_eqref, #to_latex_equation, #to_latex_footnote_reference, #to_latex_head_cell, #to_latex_header, #to_latex_hrule, #to_latex_im_link, #to_latex_image, #to_latex_immediate_link, #to_latex_inline_code, #to_latex_inline_math, #to_latex_li, #to_latex_li_span, #to_latex_linebreak, #to_latex_link, #to_latex_ol, #to_latex_paragraph, #to_latex_quote, #to_latex_raw_html, #to_latex_strong, #to_latex_table, #to_latex_ul, #wrap_as_environment, #wrap_as_span

Methods included from Out::HTML

#add_class_to, #add_class_to_link, #add_css_to, #add_ws, #adjust_png, #array_to_html, #children_to_html, #convert_to_mathml_blahtex, #convert_to_mathml_itex2mml, #convert_to_mathml_none, #convert_to_mathml_ritex, #convert_to_png_blahtex, #convert_to_png_none, #create_html_element, #day_suffix, #maruku_html_signature, #nice_date, #obfuscate, #pixels_per_ex, #render_footnotes, #render_mathml, #render_png, #render_section_number, #section_number, #source2html, #to_html, #to_html_abbr, #to_html_cell, #to_html_code, #to_html_code_using_pre, #to_html_definition, #to_html_definition_data, #to_html_definition_list, #to_html_definition_term, #to_html_div, #to_html_divref, #to_html_document, #to_html_document_tree, #to_html_email_address, #to_html_emphasis, #to_html_entity, #to_html_eqref, #to_html_equation, #to_html_footnote_reference, #to_html_head_cell, #to_html_header, #to_html_hrule, #to_html_im_image, #to_html_im_link, #to_html_image, #to_html_immediate_link, #to_html_inline_code, #to_html_inline_math, #to_html_li, #to_html_li_span, #to_html_linebreak, #to_html_link, #to_html_ol, #to_html_paragraph, #to_html_quote, #to_html_raw_html, #to_html_ref_definition, #to_html_strong, #to_html_table, #to_html_tree, #to_html_ul, #to_html_xml_instr, #to_latex_ref_definition, #wrap_as_element, #xml_newline

Methods included from Out::Markdown

#add_indent, #array_to_md, #children_to_md, #to_md_abbr_def, #to_md_li_span, #to_md_ol, #to_md_paragraph, #to_md_ul, #wrap

Methods included from MaRuKu

#markdown_extra?, #new_meta_data?, textile2

Constructor Details

#initialize(s = nil) ⇒ MDDocument

Returns a new instance of MDDocument.



150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'lib/maruku/structures.rb', line 150

def initialize(s=nil)
	super(:document)
	@doc       = self

	self.refs = {}
	self.footnotes = {}
	self.footnotes_order = []
	self.abbreviations = {}
	self.ald = {}
	self.latex_required_packages = []
	
	parse_doc(s) if s 
end

Instance Attribute Details

#tocObject

an instance of Section (see below)



26
27
28
# File 'lib/maruku/toc.rb', line 26

def toc
  @toc
end

Instance Method Details

#create_tocObject



135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
# File 'lib/maruku/toc.rb', line 135

def create_toc
	each_element(:header) do |h|
		h.attributes[:id] ||= h.generate_id
	end

	stack = []

	# the ancestor section
	s = Section.new
	s.section_level = 0

	stack.push s
	
	i = 0;
	while i < @children.size
		while i < @children.size 
			if @children[i].node_type == :header
				level = @children[i].level
				break if level <= stack.last.section_level+1
			end
		
			stack.last.immediate_children.push @children[i]
			i += 1
		end

		break if i>=@children.size
	
		header = @children[i]
		level = header.level
	
		if level > stack.last.section_level
			# this level is inside
		
			s2 = Section.new
			s2.section_level = level
			s2.header_element = header
			header.instance_variable_set :@section, s2
		
			stack.last.section_children.push s2
			stack.push s2
		
			i+=1
		elsif level == stack.last.section_level
			# this level is a sibling
			stack.pop
		else 
			# this level is a parent
			stack.pop
		end
	
	end

	# If there is only one big header, then assume
	# it is the master
	if s.section_children.size == 1
		s = s.section_children.first
	end

	# Assign section numbers
	s.numerate
	
	s
end

#html_escape(string) ⇒ Object



18
19
20
21
22
23
24
# File 'lib/maruku/output/s5/to_s5.rb', line 18

def  html_escape(string)
  string.gsub( /&/, "&amp;" ).
         gsub( /</, "&lt;" ).
         gsub( />/, "&gt;" ).
         gsub( /'/, "&#39;" ).
         gsub( /"/, "&quot;" )
end

#is_math_enabled?Boolean

Returns:

  • (Boolean)


7
8
9
# File 'lib/maruku/ext/math/parsing.rb', line 7

def is_math_enabled? 
	get_setting :math_enabled
end

#latex_require_package(p) ⇒ Object



34
35
36
37
38
# File 'lib/maruku/output/to_latex.rb', line 34

def latex_require_package(p)
	if not self.latex_required_packages.include? p
		self.latex_required_packages.push p
	end
end

#old_mdObject



158
# File 'lib/maruku/output/to_markdown.rb', line 158

alias old_md to_md

#render_latex_signatureObject



141
142
143
144
145
146
147
148
# File 'lib/maruku/output/to_latex.rb', line 141

def render_latex_signature
"\\vfill
\\hrule
\\vspace{1.2mm}
\\begin{tiny}
Created by \\href{http://maruku.rubyforge.org}{Maruku} #{self.nice_date}.
\\end{tiny}"
end

#s5_themeObject



14
15
16
# File 'lib/maruku/output/s5/to_s5.rb', line 14

def s5_theme
  html_escape(self.attributes[:slide_theme] || "default")
end

#t2_block_paragraph(src, output, signature, lines) ⇒ Object



151
152
153
154
155
# File 'lib/maruku/input_textile2/t2_parser.rb', line 151

def t2_block_paragraph(src, output, signature, lines)
	paragraph = lines.join("\n")
	src2 = CharSource.new(paragraph, src)
#			output = 
end

#t2_parse(source, params) ⇒ Object



95
96
97
98
99
100
# File 'lib/maruku/input_textile2/t2_parser.rb', line 95

def t2_parse(source, params)
	src = LineSource.new(source)
	output = BlockContext.new
	t2_parse_blocks(src, output)
	self.children = output.elements
end

#t2_parse_blocks(src, output) ⇒ Object

Input is a LineSource



109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/maruku/input_textile2/t2_parser.rb', line 109

def t2_parse_blocks(src, output)
	while src.cur_line
		l = src.shift_line
		
		# ignore empty line
		if l.t2_empty? then 
			src.shift_line
			next 
		end
		
		# TODO: lists
		# TODO: xml
		# TODO: `==`

		signature, l =
			if l.t2_contains_signature?
				l.t2_get_signature
			else
				[Textile2Signature.new, l]
			end

		if handling = T2_Handling.has_key?(signature.block_name)
			if self.responds_to? handling.method
				# read as many non-empty lines that you can
				lines = [l]
				if handling.parse_lines
					while not src.cur_line.t2_empty?
						lines.push src.shift_line
					end
				end
			
				self.send(handling.method, src, output, signature, lines)
			else
				maruku_error("We don't know about method #{handling.method.inspect}")
				next
			end
		end
		
		
	end
end

#t2_parse_span(src, output) ⇒ Object



157
158
159
# File 'lib/maruku/input_textile2/t2_parser.rb', line 157

def t2_parse_span(src, output)
	
end

#to_latexObject

Render as a LaTeX fragment



41
42
43
# File 'lib/maruku/output/to_latex.rb', line 41

def to_latex
	children_to_latex
end

#to_latex_documentObject

Render as a complete LaTeX document



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/maruku/output/to_latex.rb', line 57

def to_latex_document
	body = to_latex
	
	if get_setting(:maruku_signature)
		body += render_latex_signature 
	end
	
	required = 
	self.latex_required_packages.map {|p|
		"\\usepackage{#{p}}\n"
	}.join
	
=begin maruku_doc
Attribute: latex_cjk
Scope:     document
Output:    latex
Summary:   Support for CJK characters.

If the `latex_cjk` attribute is specified, then appropriate headers
are added to the LaTeX preamble to support Japanese fonts.
You have to have these fonts installed -- and this can be a pain.

If `latex_cjk` is specified, this is added to the preamble:

<?mrk puts "ciao" ?> 

<?mrk md_codeblock(Maruku::MDDocument::Latex_preamble_enc_cjk) ?>


while the default is to add this:

<?mrk md_codeblock(Maruku::MDDocument::Latex_preamble_enc_utf8) ?>

=end
	encoding = get_setting(:latex_cjk) ? 
		Latex_preamble_enc_cjk : Latex_preamble_enc_utf8

=begin maruku_doc
Attribute: latex_preamble
Scope:     document
Output:    latex
Summary:   User-defined preamble.

If the `latex_preamble` attribute is specified, then its value
will be used as a custom preamble. 

For example:

Title: My document
Latex preamble: preamble.tex

will produce:

...
\input{preamble.tex}
...

=end
user_preamble = (file = @doc.attributes[:latex_preamble]) ?
	"\\input{#{file}}\n" : ""
	
"\\documentclass{article}

% Packages required to support encoding
#{encoding}

% Packages required by code
#{required}

% Packages always used
\\usepackage{hyperref}
\\usepackage{xspace}
\\usepackage[usenames,dvipsnames]{color}
\\hypersetup{colorlinks=true,urlcolor=blue}

#{user_preamble}

\\begin{document} 
#{body}
\\end{document}
"	
end

#to_md(context = {}) ⇒ Object



159
160
161
162
163
# File 'lib/maruku/output/to_markdown.rb', line 159

def to_md(context={})
	s = old_md(context)
#		puts s
	s
end

#to_s5(context = {}) ⇒ Object

Render as an HTML fragment (no head, just the content of BODY). (returns a string)



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/maruku/output/s5/to_s5.rb', line 27

def to_s5(context={})
	indent       = context[:indent]       || -1
	ie_hack      = !context[:ie_hack].kind_of?(FalseClass)
	content_only = !context[:content_only].kind_of?(FalseClass)

	doc = Document.new(nil,{:respect_whitespace =>:all})

	if content_only
		body = Element.new('div', doc)
	else
		html = Element.new('html', doc)
		html.add_namespace('http://www.w3.org/1999/xhtml')
		html.add_namespace('svg', "http://www.w3.org/2000/svg" )

		head = Element.new('head', html)
		me = Element.new 'meta', head
		me.attributes['http-equiv'] = 'Content-type'
		me.attributes['content'] = 'text/html;charset=utf-8'	

		# Create title element
		doc_title = self.attributes[:title] || self.attributes[:subject] || ""
		title = Element.new 'title', head
			title << Text.new(doc_title)		
		body = Element.new('body', html)
		
	end
	
	slide_header = self.attributes[:slide_header]
	slide_footer = self.attributes[:slide_footer]
	slide_subfooter = self.attributes[:slide_subfooter]
	slide_topleft  = self.attributes[:slide_topleft]
	slide_topright  = self.attributes[:slide_topright]
	slide_bottomleft  = self.attributes[:slide_bottomleft]
	slide_bottomright  = self.attributes[:slide_bottomright]

	dummy_layout_slide = 
	"
	<div class='layout'>
	<div id='controls'> </div>
	<div id='currentSlide'> </div>
	<div id='header'> #{slide_header}</div>
	<div id='footer'>
	<h1>#{slide_footer}</h1>
	<h2>#{slide_subfooter}</h2>
	</div>
	<div class='topleft'> #{slide_topleft}</div>
	<div class='topright'> #{slide_topright}</div>
	<div class='bottomleft'> #{slide_bottomleft}</div>
	<div class='bottomright'> #{slide_bottomright}</div>
	</div>
               "
	body.add_element Document.new(dummy_layout_slide, {:respect_whitespace =>:all}).root

	presentation = Element.new 'div', body
	presentation.attributes['class'] = 'presentation'
	
	first_slide="
  <div class='slide'>
  <h1> #{self.attributes[:title] ||context[:title]}</h1>
  <h2> #{self.attributes[:subtitle] ||context[:subtitle]}</h2>
  <h3> #{self.attributes[:author] ||context[:author]}</h3>
  <h4> #{self.attributes[:company] ||context[:company]}</h4>
  </div>
	"
	presentation.add_element Document.new(first_slide).root

	slide_num = 0
	self.toc.section_children.each do |slide|
		slide_num += 1
		@doc.attributes[:doc_prefix] = "s#{slide_num}"
		
		puts "Slide #{slide_num}: " + slide.header_element.to_s
		div = Element.new('div', presentation)
		div.attributes['class'] = 'slide'
		
		h1 = Element.new 'h1', div
		slide.header_element.children_to_html.each do |e| h1 << e; end
		
		array_to_html(slide.immediate_children).each do |e|  div << e  end
			
		# render footnotes
		if @doc.footnotes_order.size > 0
			div << render_footnotes
			@doc.footnotes_order = []
		end
	end

	xml  = "" 
	if (content_only)
	   if $rexml_new_version
	     formatter = REXML::Formatters::Default.new(ie_hack)
                    formatter.write(body, xml)
	   else
	     body.write(xml,indent,transitive=true,ie_hack);
	  end
	else
	  doc2 = Document.new("<div>"+S5_external+"</div>",{:respect_whitespace =>:all})
	  doc2.root.children.each{ |child| head << child }

	  add_css_to(head)

	  # REXML Bug? if indent!=-1 whitespace is not respected for 'pre' elements
	  # containing code.
	  html.write(xml,indent,transitive=true,ie_hack);
	  Xhtml11_mathml2_svg11 + xml
	end
end