Skip to content
Merged
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
58 changes: 44 additions & 14 deletions _plugins/copy_markdown.rb
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,28 @@ def link_bases(site)
[full, root]
end

# Rewrite an internal docs URL (…/foo.html in either its root-absolute or
# full-URL form) to the .md form. Anything else is returned unchanged; a
# "#fragment" is preserved.
def to_full_md(dest, full_base, root_base)
# Root-relative URL of every published page that Jekyll serves from a
# directory ("/", "/parameters/", …) mapped to the .md URL of its copy. A page
# whose basename is "index" gets a directory URL instead of "…/index.html"
# (see Jekyll::Page#template), so it never matches the ".html" rule below and
# needs its own mapping. Only pages we actually publish are listed, so links
# never point at a .md copy that will not be written.
def index_url_map(site)
items = site.pages.dup
site.collections.each_value { |collection| items.concat(collection.docs) }

items.each_with_object({}) do |item, map|
next unless process?(site, item)

url = item.url.to_s
map[url] = "#{url}index.md" if url.end_with?('/')
end
end

# Rewrite an internal docs URL (…/foo.html, or the directory form …/foo/ of an
# index page, in either its root-absolute or full-URL shape) to the .md form.
# Anything else is returned unchanged; a "#fragment" is preserved.
def to_full_md(dest, full_base, root_base, index_url_map)
rel =
if !root_base.empty? && dest.start_with?("#{root_base}/")
dest.sub(%r{\A#{Regexp.escape(root_base)}}, '')
Expand All @@ -115,13 +133,14 @@ def to_full_md(dest, full_base, root_base)
return dest unless rel

path, fragment = rel.split('#', 2)
return dest unless path =~ /\.html\z/i

output = if full_base.empty?
"#{root_base}#{path.sub(/\.html\z/i, '')}.md"
else
"#{full_base}#{path.sub(/\.html\z/i, '')}.md"
end
md = if path =~ /\.html\z/i
path.sub(/\.html\z/i, '') + '.md'
else
index_url_map[path]
end
return dest unless md

output = "#{full_base.empty? ? root_base : full_base}#{md}"
fragment ? "#{output}##{fragment}" : output
end

Expand All @@ -131,6 +150,7 @@ def snapshot(site, item, payload)
return nil unless File.exist?(source_path)

full_base, root_base = link_bases(site)
index_urls = index_url_map(site)

# Keep the original YAML front matter byte-for-byte.
raw = File.binread(source_path).force_encoding('UTF-8')
Expand All @@ -149,17 +169,27 @@ def snapshot(site, item, payload)
content = content.gsub(%r{(\]\()([^)\s]+)}) do
head = Regexp.last_match(1)
dest = Regexp.last_match(2)
"#{head}#{to_full_md(dest, full_base, root_base)}"
"#{head}#{to_full_md(dest, full_base, root_base, index_urls)}"
end

front_matter + content
end

# Filesystem path of the .md copy inside site.dest (mirrors the .html page URL).
def dest_path(site, item)
return nil unless item.url.to_s =~ /\.html\z/i
url = item.url.to_s
relative =
if url =~ /\.html\z/i
url.sub(/\.html\z/i, '') + '.md'
elsif url.end_with?('/')
# A page whose basename is "index" is served from its directory
# ("/parameters/" rather than "/parameters/index.html"), so its copy is
# that directory's index.md — matching the rewrite in to_full_md.
"#{url}index.md"
end
return nil unless relative

File.join(site.dest, item.url.sub(/\.html\z/i, '').sub(%r{\A/+}, '') + '.md')
File.join(site.dest, relative.sub(%r{\A/+}, ''))
end

def buffer_key(item)
Expand Down