Skip to content

Asciidoctor: Copy inline images in lists #824

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 2, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 27 additions & 5 deletions resources/asciidoctor/lib/copy_images/extension.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,16 @@ class CopyImages < TreeProcessorScaffold
}.freeze
CALLOUT_RX = /CO\d+-(\d+)/
INLINE_IMAGE_RX = /(\\)?image:([^:\s\[](?:[^\n\[]*[^\s\[])?)\[/m
DOCBOOK_IMAGE_RX = %r{<imagedata fileref="([^"]+)"/>}m

def initialize(name)
super
@copier = Copier.new
end

def process_block(block)
process_inline_image block
process_inline_image_from_source block
process_inline_image_from_converted block
process_block_image block
process_callout block
process_admonition block
Expand All @@ -47,12 +49,13 @@ def process_block_image(block)
process_image block, uri
end

def process_inline_image(block)
##
# Scan the inline image from the asciidoc source. One day Asciidoc will
# parse inline things into the AST and we can get at them nicely. Today, we
# have to scrape them from the source of the node.
def process_inline_image_from_source(block)
return unless block.content_model == :simple

# One day Asciidoc will parse inline things into the AST and we can
# get at them nicely. Today, we have to scrape them from the source
# of the node.
block.source.scan(INLINE_IMAGE_RX) do |(escape, target)|
next if escape

Expand All @@ -68,6 +71,25 @@ def process_inline_image(block)
end
end

##
# Scan the inline image from the generated docbook. It is not nice that
# this is required but there isn't much we can do about it. We *could*
# rewrite all of the image copying to be against the generated docbook
# using this code but I feel like that'd be slower. For now, we'll stick
# with this.
def process_inline_image_from_converted(block)
return unless block.context == :list_item && block.parent.context == :olist

block.text.scan(DOCBOOK_IMAGE_RX) do |(target)|
# We have to resolve attributes inside the target. But there is a
# "funny" ritual for that because attribute substitution is always
# against the document. We have to play the block's attributes against
# the document, then clear them on the way out.
uri = block.image_uri target
process_image block, uri
end
end

def process_image(block, uri)
return unless uri
return if Asciidoctor::Helpers.uriish? uri # Skip external images
Expand Down
10 changes: 10 additions & 0 deletions resources/asciidoctor/spec/copy_images_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,16 @@ def copy_attributes(copied)
expect(logs).to eq(expected_logs.strip)
end
end
context 'when the inline image is inside a list' do
let(:input) do
<<~ASCIIDOC
== Example
. words image:example1.png[] words
ASCIIDOC
end
let(:resolved) { 'example1.png' }
include_examples 'copies example1'
end
end

context 'when the same image is referenced more than once' do
Expand Down