diff --git a/lib/org-ruby/html_output_buffer.rb b/lib/org-ruby/html_output_buffer.rb
index 5e5d595..dfb9131 100644
--- a/lib/org-ruby/html_output_buffer.rb
+++ b/lib/org-ruby/html_output_buffer.rb
@@ -342,6 +342,7 @@ def inline_formatting(str)
quote_tags("#{Tags[marker][:close]}>")
end
end
+ rewrite_targets(str)
if @options[:use_sub_superscripts]
@re_help.rewrite_subp str do |type, text|
@@ -353,28 +354,7 @@ def inline_formatting(str)
end
end
- @re_help.rewrite_links str do |link, defi|
- [link, defi].compact.each do |text|
- # We don't support search links right now. Get rid of it.
- text.sub!(/\A(file:[^\s]+)::[^\s]*?\Z/, "\\1")
- text.sub!(/\Afile(|\+emacs|\+sys):(?=[^\s]+\Z)/, "")
- end
-
- # We don't add a description for images in links, because its
- # empty value forces the image to be inlined.
- defi ||= link unless link =~ @re_help.org_image_file_regexp
-
- if defi =~ @re_help.org_image_file_regexp
- defi = quote_tags ""
- end
-
- if defi
- link = @options[:link_abbrevs][link] if @options[:link_abbrevs].has_key? link
- quote_tags("") + defi + quote_tags("")
- else
- quote_tags ""
- end
- end
+ rewrite_links(str)
if @output_type == :table_row
str.gsub!(/^\|\s*/, quote_tags("
"))
@@ -395,18 +375,7 @@ def inline_formatting(str)
end
# Reference footnote
- @re_help.rewrite_footnote str do |label, 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]
- a_text = footnote[:index]
- a_href = (footnote[:label].nil? || footnote[:label].empty?) ? footnote[:index] : footnote[:label]
-
- footnote_tag = "#{a_text}"
- quote_tags(footnote_tag)
- end
+ rewrite_footnote(str)
end
# Two backslashes \\ at the end of the line make a line break without breaking paragraph.
@@ -419,6 +388,62 @@ def inline_formatting(str)
str = @re_help.restore_code_snippets str
end
+ def rewrite_footnote(str)
+ @re_help.rewrite_footnote(str) do |label, 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]
+ a_text = footnote[:index]
+ a_href = (footnote[:label].nil? || footnote[:label].empty?) ? footnote[:index] : footnote[:label]
+
+ footnote_tag = "#{a_text}"
+ quote_tags(footnote_tag)
+ end
+ end
+
+ def rewrite_links(str)
+ @re_help.rewrite_links(str) do |link, defi|
+ [link, defi].compact.each do |text|
+ text.sub!(/\A(file:[^\s]+)::[^\s]*?\Z/, "\\1")
+ # We don't support search links right now. Get rid of it.
+ text.sub!(/\Afile(|\+emacs|\+sys):(?=[^\s]+\Z)/, "")
+ end
+
+ # We don't add a description for images in links, because its
+ # empty value forces the image to be inlined.
+ defi ||= link unless link =~ @re_help.org_image_file_regexp
+
+ if defi =~ @re_help.org_image_file_regexp
+ defi = quote_tags ""
+ end
+
+ if defi
+ link = @options[:link_abbrevs][link] if @options[:link_abbrevs].has_key?(link)
+ target = document.targets.find do |target|
+ puts "Find #{defi} target #{target}"
+ target[:content] == defi
+ end
+ link = "#tg.#{target[:index]}" if target
+ quote_tags("") + defi + quote_tags("")
+ else
+ quote_tags ""
+ end
+ end
+ end
+
+ def rewrite_targets(line)
+ line.gsub!(RegexpHelper.target) do |_match|
+ match = Regexp.last_match
+ target = document.targets.find do |target|
+ target[:content] == match[:content]
+ end
+ target_tag = "#{target[:content]}"
+ quote_tags(target_tag)
+ end
+ end
+
def normalize_lang(lang)
case lang
when 'emacs-lisp', 'common-lisp', 'lisp'
diff --git a/lib/org-ruby/line.rb b/lib/org-ruby/line.rb
index ef15712..107cd63 100644
--- a/lib/org-ruby/line.rb
+++ b/lib/org-ruby/line.rb
@@ -70,6 +70,10 @@ def footnote?
RegexpHelper.footnote_reference.match(@line)
end
+ def target?
+ RegexpHelper.target.match(@line)
+ end
+
def property_drawer_begin_block?
match = RegexpHelper.drawer.match(@line)
match && match[:name].downcase == 'properties'
diff --git a/lib/org-ruby/line_regexp.rb b/lib/org-ruby/line_regexp.rb
index a69b7d2..0dc52ca 100644
--- a/lib/org-ruby/line_regexp.rb
+++ b/lib/org-ruby/line_regexp.rb
@@ -74,6 +74,10 @@ def metadata
/^\s*(CLOCK|DEADLINE|START|CLOSED|SCHEDULED):/
end
+ def org_link
+ /\[\[(?[^\[\]]+)\](\[(?[^\[\]]+)\])?\]/x
+ end
+
def property_item
/^\s*:(?[\w\-]+):\s*(?.*)$/
end
@@ -102,5 +106,9 @@ def table_separator
def tags
/\s*:(?[\w:@]+):\s*$/
end
+
+ def target
+ /<{2}(?[\w\s]+)>{2}/
+ end
end
end
diff --git a/lib/org-ruby/parser.rb b/lib/org-ruby/parser.rb
index d1e4c5e..6b94578 100644
--- a/lib/org-ruby/parser.rb
+++ b/lib/org-ruby/parser.rb
@@ -173,6 +173,8 @@ def parse_lines(lines)
# Store footnotes
document.store_footnote(line)
+ # Store targets
+ document.store_target(line)
if (line.end_block? && [line.paragraph_type, :comment].include?(mode)) ||
(line.property_drawer_end_block? && (mode == :property_drawer))
diff --git a/lib/org-ruby/regexp_helper.rb b/lib/org-ruby/regexp_helper.rb
index ddad892..3646f22 100644
--- a/lib/org-ruby/regexp_helper.rb
+++ b/lib/org-ruby/regexp_helper.rb
@@ -147,7 +147,7 @@ def capture_footnote_definition(str)
# HTML-style link, and that is how things will get recorded in
# +result+.
def rewrite_links(str)
- str.gsub!(org_link_regexp) do |_match|
+ str.gsub!(RegexpHelper.org_link) do |_match|
yield Regexp.last_match['url'], Regexp.last_match['friendly_text']
end
str.gsub!(org_angle_link_text_regexp) do |_match|
@@ -172,10 +172,6 @@ def org_emphasis_regexp
"(?=#{post_emphasis})")
end
- def org_link_regexp
- /\[\[(?[^\[\]]+)\](\[(?[^\[\]]+)\])?\]/x
- end
-
def org_image_file_regexp
/\.(gif|jpe?g|p(?:bm|gm|n[gm]|pm)|svgz?|tiff?|x[bp]m)/i
end
diff --git a/lib/orgmode/elements/document.rb b/lib/orgmode/elements/document.rb
index 86c1efe..804400c 100644
--- a/lib/orgmode/elements/document.rb
+++ b/lib/orgmode/elements/document.rb
@@ -1,10 +1,11 @@
module Orgmode
module Elements
class Document
- attr_reader :footnotes
+ attr_reader :footnotes, :targets
def initialize
@footnotes = []
+ @targets = []
end
def store_footnote(line)
@@ -29,6 +30,17 @@ def store_footnote(line)
footnote[:content] = content
end
end
+
+ def store_target(line)
+ return unless line.target?
+
+ line.to_s.scan(RegexpHelper.target) do |match|
+ content = match.first
+ target_index = @targets.length + 1
+ target = { index: target_index, content: content }
+ @targets.push(target)
+ end
+ end
end
end
end
diff --git a/spec/html_examples/link-features.html b/spec/html_examples/link-features.html
index 30b0854..4994cf3 100644
--- a/spec/html_examples/link-features.html
+++ b/spec/html_examples/link-features.html
@@ -27,3 +27,6 @@
In these links, .org used to be converted to .html. Not anymore since 0.9.2
Links abbreviations
URLs can be abbreviated by a LINK definition in the org file
Links with plain text point to target and each link has it’s own id.
+
This is a target and the link has tg.index id.
diff --git a/spec/html_examples/link-features.org b/spec/html_examples/link-features.org
index 1b3ffc4..166be15 100644
--- a/spec/html_examples/link-features.org
+++ b/spec/html_examples/link-features.org
@@ -46,3 +46,9 @@ sections within documents, etc.
#+LINK: example http://example.com/something
[[example][This is an abbreviated link example]]
+
+* Internal links
+
+ Links with plain text point to [[target]] and each [[link]] has it's own id.
+
+ This is a <> and the <> has ~tg.index~ id.
diff --git a/spec/org-ruby/line_regexp_spec.rb b/spec/org-ruby/line_regexp_spec.rb
index c67e598..8b5b655 100644
--- a/spec/org-ruby/line_regexp_spec.rb
+++ b/spec/org-ruby/line_regexp_spec.rb
@@ -181,6 +181,12 @@ class DummyRegexp
it { expect(regexp.metadata).to match ' SCHEDULED:' }
end
+ describe '.org-link-regexp' do
+ it { expect(regexp.org_link).to match '[[url][description]]' }
+ it { expect(regexp.org_link).to match '[[url]]' }
+ it { expect(regexp.org_link).to match '[[a][~a~]]' }
+ end
+
describe '.property_item' do
it { expect(regexp.property_item).to match ':key:value' }
it { expect(regexp.property_item).to match ':key: value' }
@@ -234,5 +240,15 @@ class DummyRegexp
it { expect(regexp.tags).not_to match ":@tag :" }
it { expect(regexp.tags).not_to match "@tag:" }
end
+
+ describe '.target' do
+ it { expect(regexp.target).to match "<>" }
+ it { expect(regexp.target).to match "Line <>" }
+ it { expect(regexp.target).to match "<> end" }
+ it 'captures match content' do
+ match = regexp.target.match("Pre <> post")
+ expect(match[:content]).to eq "This is a target"
+ end
+ end
end
end
diff --git a/spec/orgmode/elements/document_spec.rb b/spec/orgmode/elements/document_spec.rb
new file mode 100644
index 0000000..26b7ab3
--- /dev/null
+++ b/spec/orgmode/elements/document_spec.rb
@@ -0,0 +1,40 @@
+require 'spec_helper'
+module Orgmode
+ module Elements
+ RSpec.describe Document do
+ let(:document) { Document.new }
+
+ describe 'initialize' do
+ it 'has empty footnotes' do
+ expect(document.footnotes).to be_empty
+ end
+ it 'has empty targets' do
+ expect(document.targets).to be_empty
+ end
+ end
+
+ describe '#store_target' do
+ let(:target_content) { 'Target content' }
+ let(:target) { "<<#{target_content}>>" }
+ let(:line) { Line.new target }
+
+ it 'save target in targets' do
+ document.store_target line
+ saved_target = document.targets.last
+ expect(saved_target[:content]).to eq target_content
+ expect(saved_target[:index]).to be 1
+ end
+
+ context 'when line has several targets' do
+ let(:line) { Line.new "Line with <> than <> target." }
+
+ it "save all targets" do
+ document.store_target line
+ contents = document.targets.map { |target| target[:content] }
+ expect(contents).to include('more', 'one')
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/regexp_helper_spec.rb b/spec/regexp_helper_spec.rb
index 3e43dac..2cafd14 100644
--- a/spec/regexp_helper_spec.rb
+++ b/spec/regexp_helper_spec.rb
@@ -10,15 +10,6 @@
example { expect(helper.org_emphasis_regexp).to match '[[a][~a~]]' }
end
- describe '#org-link-regexp' do
- it 'match org-links' do
- expect(helper.org_link_regexp).to match '[[url][description]]'
- end
-
- example { expect(helper.org_link_regexp).to match '[[url]]' }
- example { expect(helper.org_link_regexp).to match '[[a][~a~]]' }
- end
-
it "should recognize simple markup" do
e = Orgmode::RegexpHelper.new
total = 0