Class: Mint::Document

Inherits:
Resource show all
Defined in:
lib/mint/plugins/epub.rb,
lib/mint/document.rb

Overview

Add chapters to document – this is probably not a sustainable pattern for all plugins, but it’s useful here.

Constant Summary collapse

METADATA_DELIM =
"\n\n"

Instance Attribute Summary collapse

Attributes inherited from Resource

#context, #destination, #name, #root, #source, #type

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Resource

#destination_directory, #destination_directory_path, #destination_file, #destination_file_path, #equal?, #renderer=, #root_directory, #root_directory_path, #source_directory, #source_directory_path, #source_file, #source_file_path

Constructor Details

#initialize(source, root: nil, destination: nil, context: nil, name: nil, style_mode: :inline, style_destination: nil, layout: nil, style: nil, template: nil, layout_or_style_or_template: [:template, 'default'], all_files: nil) {|_self| ... } ⇒ Document

Creates a new Mint Document object. Can be block initialized.

Yields:

  • (_self)

Yield Parameters:



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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
# File 'lib/mint/document.rb', line 10

def initialize(source, 
               root: nil, 
               destination: nil, 
               context: nil, 
               name: nil, 
               style_mode: :inline, 
               style_destination: nil, 
               layout: nil, 
               style: nil, 
               template: nil,
               layout_or_style_or_template: [:template, 'default'],
               all_files: nil,
               &block)
               
  destination = preserve_folder_structure!(source, root, destination)
  
  @all_files = all_files if all_files && all_files.any?

  style_mode = :external if style_destination && style_mode == :inline

  # Loads source and destination, which will be used for
  # all source_* and destination_* virtual attributes.
  super(source, root: root, destination: destination, context: context, name: name)
  self.type = :document

  # Each of these should invoke explicitly defined method
  self.content = source
  self.style_mode = style_mode
  self.style_destination = style_destination

  if layout_or_style_or_template
    type, name = layout_or_style_or_template
    case type
    when :template
      self.template = name
    when :layout
      self.layout = name
    when :style
      self.style = name
    end
  end

  # Individual layout/style options can override the above
  self.layout = layout if layout
  self.style = style if style

  # The template option will override layout and style choices
  self.template = template if template

  # Yield self to block after all other parameters are loaded,
  # so we only have to tweak. (We don't have to give up our
  # defaults or re-test blocks beyond them being tweaked.)
  yield self if block
end

Instance Attribute Details

#layoutObject

Implicit readers are paired with explicit accessors. This allows for processing variables before storing them.



89
90
91
# File 'lib/mint/document.rb', line 89

def layout
  @layout
end

#metadataObject (readonly)

Implicit readers are paired with explicit accessors. This allows for processing variables before storing them.



89
90
91
# File 'lib/mint/document.rb', line 89

def 
  @metadata
end

#styleObject

Implicit readers are paired with explicit accessors. This allows for processing variables before storing them.



89
90
91
# File 'lib/mint/document.rb', line 89

def style
  @style
end

#style_destinationObject

Explanation of style_destination:

I’m going to maintain a document’s official style_destination outside of its style object. If a document has no style_destination defined when it needs one, the document will use the original style’s source directory.

This decision eliminates edge cases, including the case where we want to generate, but not move, a document’s style. It also lets us keep style information separate from document-specific information. (Without this separation, funky things happen when you assign a new style template to an existing document – if you had specified a custom style_destination before changing the template, that custom destination would be overridden.)

The style_destination attribute is lazy. It’s exposed via virtual attributes like #style_destination_file.



176
177
178
# File 'lib/mint/document.rb', line 176

def style_destination
  @style_destination
end

#style_modeObject

Explanation of style_destination:

I’m going to maintain a document’s official style_destination outside of its style object. If a document has no style_destination defined when it needs one, the document will use the original style’s source directory.

This decision eliminates edge cases, including the case where we want to generate, but not move, a document’s style. It also lets us keep style information separate from document-specific information. (Without this separation, funky things happen when you assign a new style template to an existing document – if you had specified a custom style_destination before changing the template, that custom destination would be overridden.)

The style_destination attribute is lazy. It’s exposed via virtual attributes like #style_destination_file.



176
177
178
# File 'lib/mint/document.rb', line 176

def style_mode
  @style_mode
end

Class Method Details

.metadata_chunk(text) ⇒ Object



349
350
351
# File 'lib/mint/document.rb', line 349

def (text)
  text.split(METADATA_DELIM).first
end

.metadata_from(text) ⇒ Object



353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
# File 'lib/mint/document.rb', line 353

def (text)
   = YAML.load (text)

  case 
  when String
    {}
  when false
    {}
  when nil
    {}
  else
    
  end
rescue Psych::SyntaxError
  {}
rescue Exception
  {}
end

.parse_metadata_from(text) ⇒ Object



372
373
374
375
376
377
378
379
380
381
382
# File 'lib/mint/document.rb', line 372

def (text)
   =  text
  new_text =
    if !.empty?
      text.sub (text) + METADATA_DELIM, ""
    else
      text
    end

  [, new_text]
end

Instance Method Details

#chaptersObject



18
19
20
21
# File 'lib/mint/plugins/epub.rb', line 18

def chapters
  html_document = Nokogiri::HTML::Document.parse render
  EPub.split_on(html_document, "h2").map &:to_s
end

#contentObject

Returns HTML content marked as safe for template rendering



92
93
94
# File 'lib/mint/document.rb', line 92

def content
  @content.html_safe
end

#content=(content) ⇒ void

This method returns an undefined value.

Passes content through a renderer before assigning it to be the Document’s content

Parameters:

  • content (File, #read, #basename)

    the content to be rendered from a templating language into HTML



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/mint/document.rb', line 102

def content=(content)
  tempfile = Helpers.generate_temp_file! content
  original_content = File.read content

  @metadata, text = Document. original_content
  text_with_links = Helpers.transform_markdown_links text
  intermediate_content = Mint.before_render text_with_links, {}

  File.open(tempfile, "w") do |file|
    file << intermediate_content
  end

  @renderer = Mint.renderer tempfile
  @content = @renderer.render
end

#filesObject

Returns information about all files for navigation in some templates (e.g., garden) Available when processing multiple files



263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
# File 'lib/mint/document.rb', line 263

def files
  return [] unless @all_files
  
  # Get the base directories
  source_base_dir = Pathname.new(root_directory_path).expand_path
  
  # Calculate where the current file will actually be placed
  current_source_path = Pathname.new(source_file_path).expand_path
  current_relative_to_source = current_source_path.relative_path_from(source_base_dir)
  current_html_filename = current_relative_to_source.to_s.gsub(/\.(#{Mint::MARKDOWN_EXTENSIONS.join('|')})$/i, '.html')
  
  dest_base = Pathname.new(root_directory_path).expand_path
  if destination && !destination.empty?
    dest_base = dest_base + destination
  end
  
  current_full_path = dest_base + current_html_filename
  current_destination_dir = current_full_path.dirname
  
  @all_files.map do |file|
    title = extract_title_from_file(file)
    
    # Calculate where this target file will be placed
    file_path = Pathname.new(file).expand_path
    relative_to_source = file_path.relative_path_from(source_base_dir)
    html_filename = relative_to_source.to_s.gsub(/\.(#{Mint::MARKDOWN_EXTENSIONS.join('|')})$/i, '.html')
    
    target_full_path = dest_base + html_filename
    
    # Calculate the relative path from the current file's destination directory to the target file
    relative_link = target_full_path.relative_path_from(current_destination_dir)
    
    {
      source_path: relative_to_source.to_s,
      html_path: relative_link.to_s,
      title: title,
      depth: relative_to_source.to_s.count('/')
    }
  end.sort_by {|f| f[:source_path] }
end

#inline_stylesObject

Parses styles defined in YAML metadata in content, including it in output CSS style

TODO: Implement injection of these styles



257
258
259
# File 'lib/mint/document.rb', line 257

def inline_styles
  CSS.parse()
end

#inline_stylesheetObject

Returns the rendered CSS content for inline inclusion



238
239
240
# File 'lib/mint/document.rb', line 238

def inline_stylesheet
  self.style.render
end

#publish!(opts = {}) ⇒ Object

Writes all rendered content where a) possible, b) required, and c) specified. Outputs to specified file.



73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/mint/document.rb', line 73

def publish!(opts={})
  options = { :render_style => true }.merge(opts)
  super

  if @style_mode == :external && options[:render_style]
    FileUtils.mkdir_p style_destination_directory
    File.open(self.style_destination_file, "w+") do |f|
      f << self.style.render
    end
  end

  Mint.after_publish(self, opts)
end

#render(args = {}) ⇒ Object

Renders content in the context of layout and returns as a String.



66
67
68
69
# File 'lib/mint/document.rb', line 66

def render(args={})
  intermediate_content = layout.render self, args
  Mint.after_render(intermediate_content, {})
end

#style_destination_directoryString

Exposes style_destination directory as a String.

Returns:

  • (String)


222
223
224
# File 'lib/mint/document.rb', line 222

def style_destination_directory
  style_destination_directory_path.to_s
end

#style_destination_directory_pathPathname

Exposes style_destination directory as a Pathname object.

Returns:

  • (Pathname)


215
216
217
# File 'lib/mint/document.rb', line 215

def style_destination_directory_path
  style_destination_file_path.dirname
end

#style_destination_fileString

Exposes style_destination as a String.

Returns:

  • (String)


208
209
210
# File 'lib/mint/document.rb', line 208

def style_destination_file
  style_destination_file_path.to_s
end

#style_destination_file_pathPathname

Exposes style_destination as a Pathname object.

Returns:

  • (Pathname)


194
195
196
197
198
199
200
201
202
203
# File 'lib/mint/document.rb', line 194

def style_destination_file_path
  if style_destination
    path = Pathname.new style_destination
    dir = path.absolute? ?
      path : destination_directory_path + path
    dir + style.name
  else
    style.destination_file_path
  end
end

#stylesheetObject

Returns a relative path from the document to its stylesheet. Can be called directly from inside a layout template.



230
231
232
233
234
235
# File 'lib/mint/document.rb', line 230

def stylesheet
  tmp_style_dir = Mint.path_for_scope(:user) + "tmp"
  tmp_style_file = tmp_style_dir + File.basename(style.name)
  Helpers.normalize_path(tmp_style_file.to_s,
                         self.destination_directory).to_s
end

#stylesheet_tagObject

Returns either inline CSS or stylesheet link based on style mode Use this helper in layouts instead of stylesheet or inline_stylesheet directly



244
245
246
247
248
249
250
251
# File 'lib/mint/document.rb', line 244

def stylesheet_tag
  case @style_mode
  when :external
    "<link rel=\"stylesheet\" href=\"#{stylesheet}\">".html_safe
  else # :inline (default)
    "<style>#{self.style.render}</style>".html_safe
  end
end

#template=(template) ⇒ Object

Overrides layout and style settings with named template.

Parameters:

  • template (String)

    the name of the template to set as layout and string



152
153
154
155
156
157
# File 'lib/mint/document.rb', line 152

def template=(template)
  if template
    self.layout = template
    self.style = template
  end
end