Skip to content

Commit

Permalink
Create document class to store footnotes.
Browse files Browse the repository at this point in the history
  • Loading branch information
ricardoricho committed Jul 23, 2024
1 parent 67f6ba3 commit 3981cc1
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 55 deletions.
1 change: 1 addition & 0 deletions lib/org-ruby.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# internal requires
require 'org-ruby/version'
require 'orgmode/elements/document'
require 'org-ruby/parser'
require 'org-ruby/regexp_helper'
require 'org-ruby/line'
Expand Down
21 changes: 7 additions & 14 deletions lib/org-ruby/html_output_buffer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,10 @@ class HtmlOutputBuffer < OutputBuffer

attr_reader :options

def initialize(output, opts = {})
super(output)
def initialize(output, document = nil, opts = {})
super(output, document)
@options = opts
@new_paragraph = :start
@footnotes = []
@unclosed_tags = []

# move from output_buffer
Expand Down Expand Up @@ -237,11 +236,11 @@ def html_buffer_code_block_indent(line)
# added to a separate Footnotes section at the end of the document. All footnotes that are
# defined separately from their references will be rendered where they appear in the original
# Org document.
def output_footnotes!(footnotes = [])
return if !options[:export_footnotes] || footnotes.empty?
def output_footnotes!
return if !options[:export_footnotes] || document.footnotes.empty?

@output.concat footnotes_header
footnotes.each do |footnote|
document.footnotes.each do |footnote|
@buffer = footnote[:content].empty? && footnote[:label] || footnote[:content]
a_href = footnote[:index]
@output << "<div class=\"footdef\"><sup><a id=\"fn.#{a_href}\" class=\"footnum\" href=\"#fnr.#{a_href}\" role=\"doc-backlink\">#{a_href}</a></sup>" \
Expand Down Expand Up @@ -397,14 +396,8 @@ def inline_formatting(str)

# Reference footnote
@re_help.rewrite_footnote str do |label, content|
footnote = @footnotes.find { |footnote| footnote[:label] == label }

if footnote.nil?
footnote_index = @footnotes.length + 1
footnote = { index: footnote_index, label: label, content: content }
@footnotes.push(footnote)
else
footnote[:content] = content
footnote = document.footnotes.find do |footnote|
footnote[:label] == label || footnote[:content] == content
end

a_id = (footnote[:label].nil? || footnote[:label].empty?) ? footnote[:index] : footnote[:label]
Expand Down
1 change: 0 additions & 1 deletion lib/org-ruby/line.rb
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ def footnote?
RegexpHelper.footnote_definition.match(@line) ||
RegexpHelper.footnote_reference.match(@line)
end
end

def property_drawer_begin_block?
match = RegexpHelper.drawer.match(@line)
Expand Down
7 changes: 4 additions & 3 deletions lib/org-ruby/output_buffer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ module Orgmode
# add a newline character prior emitting the output.
class OutputBuffer
# This is the overall output buffer
attr_reader :output, :mode_stack, :list_indent_stack
attr_reader :output, :mode_stack, :list_indent_stack, :document

# This is the current type of output being accumulated.
attr_accessor :output_type, :headline_number_stack, :custom_blocktags

# Creates a new OutputBuffer object that is bound to an output object.
# The output will get flushed to =output=.
def initialize(output)
def initialize(output, document = nil)
# This is the accumulation buffer. It's a holding pen so
# consecutive lines of the right type can get stuck together
# without intervening newlines.
Expand All @@ -29,6 +29,7 @@ def initialize(output)
@list_indent_stack = []
@mode_stack = []
@custom_blocktags = []
@document = document

# regexp module
@re_help = RegexpHelper.new
Expand Down Expand Up @@ -169,7 +170,7 @@ def no_custom_markup_file_exist
nil
end

def output_footnotes!(footnotes = [])
def output_footnotes!
# Implement in output buffers
end

Expand Down
32 changes: 10 additions & 22 deletions lib/org-ruby/parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ class Parser
# Array of custom keywords.
attr_reader :custom_keywords

attr_reader :footnotes

# Regexp that recognizes words in custom_keywords.
def custom_keyword_regexp
return nil if @custom_keywords.empty?
Expand Down Expand Up @@ -102,7 +100,7 @@ def initialize(lines, parser_options = {})
@lines = initialize_lines(lines)
@custom_keywords = []
@current_headline = nil
@footnotes = []
@document = Orgmode::Elements::Document.new
@in_buffer_settings = {}
@headlines = []
@header_lines = []
Expand Down Expand Up @@ -174,19 +172,7 @@ def parse_lines(lines)
end

# Store footnotes
if line.footnote?
line.store_footnote do |label, content|
footnote = @footnotes.find { |footnote| footnote[:label] == label }

if footnote.nil?
footnote_index = @footnotes.length + 1
footnote = { index: footnote_index, label: label, content: content }
@footnotes.push(footnote)
else
footnote[:content] = content
end
end
end
document.store_footnote(line)

if (line.end_block? && [line.paragraph_type, :comment].include?(mode)) ||
(line.property_drawer_end_block? && (mode == :property_drawer))
Expand Down Expand Up @@ -333,7 +319,7 @@ def to_textile
@headlines.each do |headline|
translate(headline.body_lines, output_buffer)
end
output_buffer.output_footnotes!(@footnotes)
output_buffer.output_footnotes!
output
end

Expand All @@ -358,8 +344,8 @@ def to_html
decorate_title: in_buffer_settings['TITLE'],
export_heading_number: export_heading_number?,
export_todo: export_todo?,
use_sub_superscripts: use_sub_superscripts?,
export_footnotes: export_footnotes?,
use_sub_superscripts: use_sub_superscripts?,
link_abbrevs: @link_abbrevs,
skip_syntax_highlight: @parser_options[:skip_syntax_highlight],
markup_file: @parser_options[:markup_file],
Expand All @@ -369,8 +355,7 @@ def to_html
}
export_options[:skip_tables] = true unless export_tables?
output = ''
output_buffer = HtmlOutputBuffer.new(output, export_options)

output_buffer = HtmlOutputBuffer.new(output, document, export_options)
if title?
# If we're given a new title, then just create a new line
# for that title.
Expand Down Expand Up @@ -398,7 +383,10 @@ def title
in_buffer_settings['TITLE']
end

######################################################################
protected

attr_reader :document

private

def translate_headlines(headlines, output_buffer)
Expand All @@ -410,7 +398,7 @@ def translate_headlines(headlines, output_buffer)
translate(headline.body_lines, output_buffer)
end
end
output_buffer.output_footnotes!(footnotes)
output_buffer.output_footnotes!
end

# Converts an array of lines to the appropriate format.
Expand Down
19 changes: 7 additions & 12 deletions lib/org-ruby/textile_output_buffer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@
module Orgmode
class TextileOutputBuffer < OutputBuffer

def initialize(output)
super(output)
def initialize(output, document = nil)
super(output, document)
@add_paragraph = true
@support_definition_list = true # TODO this should be an option
@footnotes = []
end

def push_mode(mode, indent, properties={})
Expand Down Expand Up @@ -88,12 +87,8 @@ def inline_formatting(input)
@re_help.rewrite_footnote(input) do |label, content|
# textile only support numerical names, so we need to do some conversion
# Try to find the footnote and use its index
footnote = @footnotes.find { |footnote| footnote[:label] == label }
if footnote.nil?
footnote = { index: @footnotes.length + 1, label: label, content: content }
@footnotes.push(footnote)
else
footnote[:content] = content&.strip
footnote = document.footnotes.find do |footnote|
footnote[:label] == label || footnote[:content] == content
end

"[#{footnote[:index]}]"
Expand All @@ -104,10 +99,10 @@ def inline_formatting(input)
input
end

def output_footnotes!(footnotes = [])
return if @footnotes.empty?
def output_footnotes!
return if document.footnotes.empty?

footnotes.each do |footnote|
document.footnotes.each do |footnote|
@output << "\nfn#{footnote[:index]}. #{footnote[:content].lstrip || 'DEFINITION NOT FOUND' }\n"
end
end
Expand Down
3 changes: 2 additions & 1 deletion lib/orgmode/elements/document.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ def initialize
end

def store_footnote(line)
return unless line.footnote?

if RegexpHelper.footnote_definition.match(line.to_s)
match = Regexp.last_match
label = match[:label]
Expand All @@ -26,7 +28,6 @@ def store_footnote(line)
else
footnote[:content] = content
end
@footnotes.push(footnote)
end
end
end
Expand Down
22 changes: 20 additions & 2 deletions spec/org-ruby/html_output_buffer_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,27 @@ module Orgmode
expect(buffer.buffer_tag).to eq 'HTML'
end

context 'when call with a document' do
let(:document) { "This is a document" }
let(:buffer) { Orgmode::HtmlOutputBuffer.new(output, document)}

it 'has a document' do
expect(buffer.document).to eq document
end

it 'has empty options' do
expect(buffer.options).to be_empty
end
end

context 'when call with options' do
let(:options) { { option: 'value'} }
let(:buffer) { Orgmode::HtmlOutputBuffer.new(output, options)}
let(:buffer) { Orgmode::HtmlOutputBuffer.new(output, nil, options)}

it 'has nil document' do
expect(buffer.document).to be_nil
end

it 'has options' do
expect(buffer.options).to eq options
end
Expand Down Expand Up @@ -64,7 +82,7 @@ module Orgmode
let(:mode) { :src }

context 'when Buffer options include skip_syntax_highlight = true' do
let(:buffer) { Orgmode::HtmlOutputBuffer.new(output, { skip_syntax_highlight: true })}
let(:buffer) { Orgmode::HtmlOutputBuffer.new(output, nil, { skip_syntax_highlight: true })}
before(:each) do
allow(buffer).to receive(:block_lang).and_return('')
end
Expand Down

0 comments on commit 3981cc1

Please sign in to comment.