diff --git a/lib/org-ruby.rb b/lib/org-ruby.rb index 39e5167..0aebfae 100644 --- a/lib/org-ruby.rb +++ b/lib/org-ruby.rb @@ -1,6 +1,7 @@ # internal requires require 'org-ruby/version' require 'orgmode/elements/document' +require 'orgmode/elements/link' require 'org-ruby/parser' require 'org-ruby/regexp_helper' require 'org-ruby/line' diff --git a/lib/org-ruby/html_output_buffer.rb b/lib/org-ruby/html_output_buffer.rb index bc39c33..ba983cf 100644 --- a/lib/org-ruby/html_output_buffer.rb +++ b/lib/org-ruby/html_output_buffer.rb @@ -431,24 +431,8 @@ def rewrite_links(str) 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 "\"#{defi}\"" - end - - if defi - link = options[:link_abbrevs][link] if options[:link_abbrevs].has_key?(link) - target = document.targets.find do |target| - target[:content] == defi - end - link = "#tg.#{target[:index]}" if target - quote_tags("") + defi + quote_tags("") - else - quote_tags "\"#{link}\"" - end + org_link = Orgmode::Elements::Link.new(document, link, defi) + quote_tags org_link.html_tag end end diff --git a/lib/org-ruby/image_regexp.rb b/lib/org-ruby/image_regexp.rb new file mode 100644 index 0000000..6fc9db4 --- /dev/null +++ b/lib/org-ruby/image_regexp.rb @@ -0,0 +1,7 @@ +module Orgmode + module ImageRegexp + def image_file + /\.(gif|jpe?g|p(?:bm|gm|n[gm]|pm)|svgz?|tiff?|x[bp]m)/i + end + end +end diff --git a/lib/org-ruby/regexp_helper.rb b/lib/org-ruby/regexp_helper.rb index 5a0166d..5d18f8d 100644 --- a/lib/org-ruby/regexp_helper.rb +++ b/lib/org-ruby/regexp_helper.rb @@ -1,5 +1,6 @@ require 'org-ruby/line_regexp' require 'org-ruby/headline_regexp' +require 'org-ruby/image_regexp' module Orgmode @@ -21,6 +22,7 @@ module Orgmode class RegexpHelper extend LineRegexp extend HeadlineRegexp + extend ImageRegexp ###################################################################### # EMPHASIS diff --git a/lib/orgmode/elements/link.rb b/lib/orgmode/elements/link.rb new file mode 100644 index 0000000..62125ca --- /dev/null +++ b/lib/orgmode/elements/link.rb @@ -0,0 +1,68 @@ +module Orgmode + module Elements + class Link + attr_reader :url, :description, :document + + def initialize(document, url, description = nil) + @document = document + @url = expand(url, document.link_abbreviations) + @description = description + end + + def html_tag + return image_tag if target_image? + return target_tag unless document.targets.empty? + + "#{description || url}" + end + + private + + def expand(url, abbreviations) + return url if abbreviations.nil? + return url unless abbreviations.has_key?(url) + + abbreviations[url] + end + + def description_img_tag + "\"#{description}\"" + end + + def find_target(targets = []) + targets.find do |target| + target[:content] == description || target[:content] == url + end + end + + def image_file?(file) + RegexpHelper.image_file.match(file) + end + + def image_tag + if !image_file?(url) + "#{description_img_tag}" + elsif image_file? description + description_img_tag + elsif description.nil? + "\"#{url}\"" + else + "\"#{description}\"" + end + end + + def target_image? + return @target_image unless @target_image.nil? + + @target_image = image_file?(url) || image_file?(description) || false + end + + def target_tag + target = find_target(document.targets) + link = target ? "#tg.#{target[:index]}" : url + + "#{description || url}" + end + end + end +end diff --git a/spec/html_examples/include-file.html b/spec/html_examples/include-file.html index ab56cb6..cb8ab74 100644 --- a/spec/html_examples/include-file.html +++ b/spec/html_examples/include-file.html @@ -107,6 +107,10 @@

Within a center block

images/animate-dom-01-f.svg

Sample relative link to .svgz:

images/conform-viewers-01-t.svgz

+

Image with alt description

+

This image should use the description as the alt attribute:

+

A screenshot of our new UI

+

This is an inline emacs-logo from a link.

Within a blockquote

This is similar to the center block:

@@ -134,6 +138,10 @@

Within a blockquote

images/animate-dom-01-f.svg

Sample relative link to .svgz:

images/conform-viewers-01-t.svgz

+

Image with alt description

+

This image should use the description as the alt attribute:

+

A screenshot of our new UI

+

This is an inline emacs-logo from a link.

After

Within an example block, it should not be possible to include a file.

diff --git a/spec/html_examples/inline-images.html b/spec/html_examples/inline-images.html index d36beeb..81cc074 100644 --- a/spec/html_examples/inline-images.html +++ b/spec/html_examples/inline-images.html @@ -20,3 +20,7 @@

images/animate-dom-01-f.svg

Sample relative link to .svgz:

images/conform-viewers-01-t.svgz

+

Image with alt description

+

This image should use the description as the alt attribute:

+

A screenshot of our new UI

+

This is an inline emacs-logo from a link.

diff --git a/spec/html_examples/inline-images.org b/spec/html_examples/inline-images.org index 3d1ee3a..5e93af3 100644 --- a/spec/html_examples/inline-images.org +++ b/spec/html_examples/inline-images.org @@ -30,3 +30,11 @@ Sample relative link to .svg: Sample relative link to .svgz: [[file:images/conform-viewers-01-t.svgz]] + +Image with alt description + +This image should use the description as the alt attribute: + +[[file:/images/emacs-logo.png][A screenshot of our new UI]] + +This is an inline [[file:images/emacs-logo.svg][emacs-logo]] from a link. diff --git a/spec/org-ruby/image_regexp_spec.rb b/spec/org-ruby/image_regexp_spec.rb new file mode 100644 index 0000000..64af06a --- /dev/null +++ b/spec/org-ruby/image_regexp_spec.rb @@ -0,0 +1,27 @@ +require 'spec_helper' + +module Orgmode + RSpec.describe ImageRegexp do + class DummyRegexp + include ImageRegexp + end + let(:regexp) { DummyRegexp.new } + + describe 'image_file' do + it { expect(regexp.image_file).to match 'file.jpg' } + it { expect(regexp.image_file).to match 'file.jpeg' } + it { expect(regexp.image_file).to match 'file.png' } + it { expect(regexp.image_file).to match 'file.svg' } + it { expect(regexp.image_file).to match 'some/path/file.gif' } + it { expect(regexp.image_file).to match 'other.svgz' } + it { expect(regexp.image_file).to match 'tiffany.tiff' } + it { expect(regexp.image_file).to match 'xx.xpm' } + it { expect(regexp.image_file).to match 'yy.xbm' } + + it { expect(regexp.image_file).not_to match 'file' } + it { expect(regexp.image_file).not_to match 'path/file/' } + it { expect(regexp.image_file).not_to match 'file.pdf' } + it { expect(regexp.image_file).not_to match 'some/file.xml' } + end + end +end diff --git a/spec/orgmode/elements/document_spec.rb b/spec/orgmode/elements/document_spec.rb index 26b7ab3..b9df9af 100644 --- a/spec/orgmode/elements/document_spec.rb +++ b/spec/orgmode/elements/document_spec.rb @@ -1,4 +1,5 @@ require 'spec_helper' + module Orgmode module Elements RSpec.describe Document do diff --git a/spec/orgmode/elements/link_spec.rb b/spec/orgmode/elements/link_spec.rb new file mode 100644 index 0000000..62c3c78 --- /dev/null +++ b/spec/orgmode/elements/link_spec.rb @@ -0,0 +1,109 @@ +require 'spec_helper' + +module Orgmode + module Elements + RSpec.describe Link do + describe 'initialize' do + let(:document) { Document.new } + let(:url) { "This is a url" } + let(:link) { Link.new document, url } + + it 'has a document' do + expect(link.document).not_to be_nil + end + + it 'has an url' do + expect(link.url).not_to be_nil + end + + it 'has a description' do + expect(link.description).to be_nil + end + + context 'when description is present' do + let(:description) { "this is the description" } + let(:link) { Link.new document, url, description } + + it 'set a description value' do + expect(link.description).to eq description + end + end + + context 'when document has link abbrevitions' do + let(:url) { "abbrev"} + + before do + line = Line.new "#+LINK: abbrev long_url" + document.store_link_abbreviation(line) + end + + it 'expand url abbreviation' do + abbreviate_url = "long_url" + expect(link.url).to eq abbreviate_url + end + end + end + + describe '#html_tag' do + let(:document) { Document.new } + let(:url) { "Any url" } + let(:description) { nil } + let(:link) { Link.new document, url, description } + + context 'when description is nil' do + it 'return a html link with the url as description' do + html_link = "#{url}" + expect(link.html_tag).to eq html_link + end + end + + context 'when description is not nil' do + let(:description) { "this is the description"} + + it 'return an html link to url with description as text' do + html_link = "#{description}" + expect(link.html_tag).to eq html_link + end + end + + context 'when url is an image' do + let(:url) { "an/image/path.png" } + + context 'when description is text' do + let(:description) { "Text description"} + + it 'return an img tag' do + img_tag = "\"#{description}\"" + expect(link.html_tag).to eq img_tag + end + end + end + + context 'when url is not an image but description is' do + let(:url) { "link/path" } + let(:description) { "an_image.jpeg" } + + it 'return an img tag wrapper in a link' do + img_tag = "\"#{description}\"" + link_tag = "#{img_tag}" + expect(link.html_tag).to eq link_tag + end + end + + context 'when document has targets' do + let(:url) { "target" } + + before do + line = Line.new "<>" + document.store_target(line) + end + + it 'set url to numerated target' do + target_tag = "target" + expect(link.html_tag).to eq target_tag + end + end + end + end + end +end