From 44c9f81921201d186f1b69e445fe7b95c7a46d87 Mon Sep 17 00:00:00 2001 From: Parker Moore Date: Sun, 12 Oct 2014 02:29:53 -0700 Subject: [PATCH 01/10] Cache the extname regexp in Converters::Markdown and Textile --- lib/jekyll/converters/markdown.rb | 9 +++++++-- lib/jekyll/converters/textile.rb | 9 +++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/lib/jekyll/converters/markdown.rb b/lib/jekyll/converters/markdown.rb index 687b0eca..da37d249 100644 --- a/lib/jekyll/converters/markdown.rb +++ b/lib/jekyll/converters/markdown.rb @@ -8,6 +8,7 @@ module Jekyll def setup return if @setup + @regexp = build_extname_regexp @parser = case @config['markdown'].downcase when 'redcarpet' then RedcarpetParser.new(@config) @@ -27,6 +28,11 @@ module Jekyll @setup = true end + def build_extname_regexp + rgx = '^\.(' + @config['markdown_ext'].gsub(',','|') +')$' + Regexp.new(rgx, Regexp::IGNORECASE) + end + def valid_processors %w[ maruku @@ -47,8 +53,7 @@ module Jekyll end def matches(ext) - rgx = '^\.(' + @config['markdown_ext'].gsub(',','|') +')$' - ext =~ Regexp.new(rgx, Regexp::IGNORECASE) + ext =~ @regexp end def output_ext(ext) diff --git a/lib/jekyll/converters/textile.rb b/lib/jekyll/converters/textile.rb index 366aa0ce..8c366908 100644 --- a/lib/jekyll/converters/textile.rb +++ b/lib/jekyll/converters/textile.rb @@ -9,6 +9,7 @@ module Jekyll def setup return if @setup require 'redcloth' + @regexp = build_extname_regexp @setup = true rescue LoadError STDERR.puts 'You are missing a library required for Textile. Please run:' @@ -16,9 +17,13 @@ module Jekyll raise Errors::FatalException.new("Missing dependency: RedCloth") end + def build_extname_regexp + rgx = '(' + @config['textile_ext'].gsub(',','|') +')$' + Regexp.new(rgx, Regexp::IGNORECASE) + end + def matches(ext) - rgx = '(' + @config['textile_ext'].gsub(',','|') +')' - ext =~ Regexp.new(rgx, Regexp::IGNORECASE) + ext =~ @regexp end def output_ext(ext) From fbe98df4883b7856d2e53241cb18e784f9940e56 Mon Sep 17 00:00:00 2001 From: Parker Moore Date: Sun, 12 Oct 2014 02:30:10 -0700 Subject: [PATCH 02/10] Cache variables that won't change through the life of an object --- lib/jekyll/collection.rb | 4 ++-- lib/jekyll/document.rb | 32 ++++++++++++++++---------------- lib/jekyll/tags/include.rb | 4 ++-- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/lib/jekyll/collection.rb b/lib/jekyll/collection.rb index 5fc3994f..33654f45 100644 --- a/lib/jekyll/collection.rb +++ b/lib/jekyll/collection.rb @@ -75,7 +75,7 @@ module Jekyll # Returns a String containing the directory name where the collection # is stored on the filesystem. def relative_directory - "_#{label}" + @relative_directory ||= "_#{label}" end # The full path to the directory containing the @@ -83,7 +83,7 @@ module Jekyll # Returns a String containing th directory name where the collection # is stored on the filesystem. def directory - Jekyll.sanitized_path(site.source, relative_directory) + @directory ||= Jekyll.sanitized_path(site.source, relative_directory) end # Checks whether the directory "exists" for this collection. diff --git a/lib/jekyll/document.rb b/lib/jekyll/document.rb index f4761ef8..95a2bdcd 100644 --- a/lib/jekyll/document.rb +++ b/lib/jekyll/document.rb @@ -4,7 +4,7 @@ module Jekyll class Document include Comparable - attr_reader :path, :site + attr_reader :path, :site, :extname attr_accessor :content, :collection, :output # Create a new Document. @@ -16,6 +16,7 @@ module Jekyll def initialize(path, relations) @site = relations[:site] @path = path + @extname = File.extname(path) @collection = relations[:collection] @has_yaml_header = nil end @@ -33,23 +34,21 @@ module Jekyll # Returns a String path which represents the relative path # from the site source to this document def relative_path - Pathname.new(path).relative_path_from(Pathname.new(site.source)).to_s + @relative_path ||= Pathname.new(path).relative_path_from(Pathname.new(site.source)).to_s + end + + # The base filename of the document, without the file extname. + # + # Returns the basename without the file extname. + def basename_without_ext + @basename_without_ext ||= File.basename(path, '.*') end # The base filename of the document. # - # suffix - (optional) the suffix to be removed from the end of the filename - # # Returns the base filename of the document. - def basename(suffix = "") - File.basename(path, suffix) - end - - # The extension name of the document. - # - # Returns the extension name of the document. - def extname - File.extname(path) + def basename + @basename ||= File.basename(path) end # Produces a "cleaned" relative path. @@ -64,7 +63,8 @@ module Jekyll # # Returns the cleaned relative path of the document. def cleaned_relative_path - relative_path[0 .. -extname.length - 1].sub(collection.relative_directory, "") + @cleaned_relative_path ||= + relative_path[0 .. -extname.length - 1].sub(collection.relative_directory, "") end # Determine whether the document is a YAML file. @@ -129,8 +129,8 @@ module Jekyll collection: collection.label, path: cleaned_relative_path, output_ext: Jekyll::Renderer.new(site, self).output_ext, - name: Utils.slugify(basename(".*")), - title: Utils.slugify(data['title']) || Utils.slugify(basename(".*")) + name: Utils.slugify(basename_without_ext), + title: Utils.slugify(data['title']) || Utils.slugify(basename_without_ext) } end diff --git a/lib/jekyll/tags/include.rb b/lib/jekyll/tags/include.rb index 87583e95..d5aa3b6d 100644 --- a/lib/jekyll/tags/include.rb +++ b/lib/jekyll/tags/include.rb @@ -98,7 +98,7 @@ eos end def includes_dir - '_includes' + @includes_dir ||= '_includes' end def render(context) @@ -150,7 +150,7 @@ eos class IncludeRelativeTag < IncludeTag def includes_dir - '.' + @includes_dir ||= '.' end def resolved_includes_dir(context) From 4942b2947bcc8a11bc589efe904fd913812ffa5d Mon Sep 17 00:00:00 2001 From: Parker Moore Date: Sun, 12 Oct 2014 14:31:49 -0700 Subject: [PATCH 03/10] Only compile the Converter#matches regexp when asked for --- lib/jekyll/converters/markdown.rb | 15 ++++++++------- lib/jekyll/converters/textile.rb | 11 ++++++----- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/lib/jekyll/converters/markdown.rb b/lib/jekyll/converters/markdown.rb index da37d249..0dcc90a8 100644 --- a/lib/jekyll/converters/markdown.rb +++ b/lib/jekyll/converters/markdown.rb @@ -8,7 +8,6 @@ module Jekyll def setup return if @setup - @regexp = build_extname_regexp @parser = case @config['markdown'].downcase when 'redcarpet' then RedcarpetParser.new(@config) @@ -28,11 +27,6 @@ module Jekyll @setup = true end - def build_extname_regexp - rgx = '^\.(' + @config['markdown_ext'].gsub(',','|') +')$' - Regexp.new(rgx, Regexp::IGNORECASE) - end - def valid_processors %w[ maruku @@ -52,8 +46,15 @@ module Jekyll ].map(&:to_sym) end + def extname_matches_regexp + @extname_matches_regexp ||= Regexp.new( + '(' + @config['markdown_ext'].gsub(',','|') +')$', + Regexp::IGNORECASE + ) + end + def matches(ext) - ext =~ @regexp + ext =~ extname_matches_regexp end def output_ext(ext) diff --git a/lib/jekyll/converters/textile.rb b/lib/jekyll/converters/textile.rb index 8c366908..c8137a3a 100644 --- a/lib/jekyll/converters/textile.rb +++ b/lib/jekyll/converters/textile.rb @@ -9,7 +9,6 @@ module Jekyll def setup return if @setup require 'redcloth' - @regexp = build_extname_regexp @setup = true rescue LoadError STDERR.puts 'You are missing a library required for Textile. Please run:' @@ -17,13 +16,15 @@ module Jekyll raise Errors::FatalException.new("Missing dependency: RedCloth") end - def build_extname_regexp - rgx = '(' + @config['textile_ext'].gsub(',','|') +')$' - Regexp.new(rgx, Regexp::IGNORECASE) + def extname_matches_regexp + @extname_matches_regexp ||= Regexp.new( + '(' + @config['textile_ext'].gsub(',','|') +')$', + Regexp::IGNORECASE + ) end def matches(ext) - ext =~ @regexp + ext =~ extname_matches_regexp end def output_ext(ext) From 73ca205a5c34d91690fc6735d977ba5323af165d Mon Sep 17 00:00:00 2001 From: Parker Moore Date: Sun, 12 Oct 2014 14:33:13 -0700 Subject: [PATCH 04/10] Add test for Document#basename_without_ext --- test/test_document.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/test_document.rb b/test/test_document.rb index 5e26173f..3464cd2b 100644 --- a/test/test_document.rb +++ b/test/test_document.rb @@ -25,8 +25,8 @@ class TestDocument < Test::Unit::TestCase assert_equal "configuration.md", @document.basename end - should "allow the suffix to be specified for the basename" do - assert_equal "configuration", @document.basename(".*") + should "know its basename without extname" do + assert_equal "configuration", @document.basename_without_ext end should "know whether its a yaml file" do From a7c0fffcec4278bc12f713066728435d56e8f4ee Mon Sep 17 00:00:00 2001 From: Parker Moore Date: Sun, 12 Oct 2014 14:39:04 -0700 Subject: [PATCH 05/10] Only run script/bootstrap in stackprof if stackprof executable isn't there --- script/stackprof | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/stackprof b/script/stackprof index 32c89ac3..847d66bd 100755 --- a/script/stackprof +++ b/script/stackprof @@ -3,7 +3,7 @@ set -e export BENCHMARK=true -script/bootstrap +command -v stackprof || script/bootstrap TEST_SCRIPT="Jekyll::Commands::Build.process({'source' => 'site'})" PROF_OUTPUT_FILE=tmp/stackprof-$(date +%Y%m%d).dump From 626706c8c5fa152787c0ae7a2ceab7648d850e87 Mon Sep 17 00:00:00 2001 From: Parker Moore Date: Sun, 12 Oct 2014 15:11:28 -0700 Subject: [PATCH 06/10] Cache the `@includes_dir` in each instance so the method isn't called all the time --- lib/jekyll/tags/include.rb | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/lib/jekyll/tags/include.rb b/lib/jekyll/tags/include.rb index d5aa3b6d..fbe03ed3 100644 --- a/lib/jekyll/tags/include.rb +++ b/lib/jekyll/tags/include.rb @@ -13,11 +13,14 @@ module Jekyll class IncludeTag < Liquid::Tag + attr_reader :includes_dir + VALID_SYNTAX = /([\w-]+)\s*=\s*(?:"([^"\\]*(?:\\.[^"\\]*)*)"|'([^'\\]*(?:\\.[^'\\]*)*)'|([\w\.-]+))/ VARIABLE_SYNTAX = /(?[^{]*\{\{\s*(?[\w\-\.]+)\s*(\|.*)?\}\}[^\s}]*)(?.*)/ def initialize(tag_name, markup, tokens) super + @includes_dir = tag_includes_dir matched = markup.strip.match(VARIABLE_SYNTAX) if matched @file = matched['variable'].strip @@ -97,8 +100,8 @@ eos end end - def includes_dir - @includes_dir ||= '_includes' + def tag_includes_dir + '_includes' end def render(context) @@ -118,12 +121,12 @@ eos partial.render!(context) end rescue => e - raise IncludeTagError.new e.message, File.join(includes_dir, @file) + raise IncludeTagError.new e.message, File.join(@includes_dir, @file) end end def resolved_includes_dir(context) - File.join(File.realpath(context.registers[:site].source), includes_dir) + File.join(File.realpath(context.registers[:site].source), @includes_dir) end def validate_path(path, dir, safe) @@ -135,7 +138,7 @@ eos end def path_relative_to_source(dir, path) - File.join(includes_dir, path.sub(Regexp.new("^#{dir}"), "")) + File.join(@includes_dir, path.sub(Regexp.new("^#{dir}"), "")) end def realpath_prefixed_with?(path, dir) @@ -149,12 +152,15 @@ eos end class IncludeRelativeTag < IncludeTag - def includes_dir - @includes_dir ||= '.' + def tag_includes_dir + '.' + end + + def page_path + context.registers[:page].nil? ? includes_dir : File.dirname(context.registers[:page]["path"]) end def resolved_includes_dir(context) - page_path = context.registers[:page].nil? ? includes_dir : File.dirname(context.registers[:page]["path"]) Jekyll.sanitized_path(context.registers[:site].source, page_path) end end From b07cbcecbde4003f70b1dc8dca0f188608b70a19 Mon Sep 17 00:00:00 2001 From: Parker Moore Date: Sun, 12 Oct 2014 15:11:44 -0700 Subject: [PATCH 07/10] Don't print the location of the stackprof executable --- script/stackprof | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/stackprof b/script/stackprof index 847d66bd..fd075cac 100755 --- a/script/stackprof +++ b/script/stackprof @@ -3,7 +3,7 @@ set -e export BENCHMARK=true -command -v stackprof || script/bootstrap +command -v stackprof > /dev/null || script/bootstrap TEST_SCRIPT="Jekyll::Commands::Build.process({'source' => 'site'})" PROF_OUTPUT_FILE=tmp/stackprof-$(date +%Y%m%d).dump From 0400ffe377b6bf1ec8612319d7c722a2fbd15ed2 Mon Sep 17 00:00:00 2001 From: Parker Moore Date: Sun, 12 Oct 2014 15:11:53 -0700 Subject: [PATCH 08/10] Only re-run the stackprof if I delete the prof output file. --- script/stackprof | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/script/stackprof b/script/stackprof index fd075cac..e0e2d4db 100755 --- a/script/stackprof +++ b/script/stackprof @@ -8,6 +8,9 @@ command -v stackprof > /dev/null || script/bootstrap TEST_SCRIPT="Jekyll::Commands::Build.process({'source' => 'site'})" PROF_OUTPUT_FILE=tmp/stackprof-$(date +%Y%m%d).dump -bundle exec ruby -r./lib/jekyll -rstackprof -e "StackProf.run(mode: :cpu, out: '${PROF_OUTPUT_FILE}') { ${TEST_SCRIPT} }" +test -f "$PROF_OUTPUT_FILE" || { + bundle exec ruby -r./lib/jekyll -rstackprof \ + -e "StackProf.run(mode: :cpu, out: '${PROF_OUTPUT_FILE}') { ${TEST_SCRIPT} }" +} bundle exec stackprof $PROF_OUTPUT_FILE $@ From 22cc393cd48647b417fc886b82147db5b1ffa3ca Mon Sep 17 00:00:00 2001 From: Parker Moore Date: Sun, 12 Oct 2014 15:12:30 -0700 Subject: [PATCH 09/10] Ignore the stackprof tmp files. --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 42bba817..aa6c14f8 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ site/_site/ coverage .ruby-version .sass-cache +tmp/stackprof-* From b564214535dd6972be687481a4b1ab05dd1f0652 Mon Sep 17 00:00:00 2001 From: Parker Moore Date: Sun, 12 Oct 2014 15:16:38 -0700 Subject: [PATCH 10/10] Pass the context on to IncludeRelativeTag#page_path --- lib/jekyll/tags/include.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/jekyll/tags/include.rb b/lib/jekyll/tags/include.rb index fbe03ed3..c6b1ed9c 100644 --- a/lib/jekyll/tags/include.rb +++ b/lib/jekyll/tags/include.rb @@ -156,12 +156,12 @@ eos '.' end - def page_path + def page_path(context) context.registers[:page].nil? ? includes_dir : File.dirname(context.registers[:page]["path"]) end def resolved_includes_dir(context) - Jekyll.sanitized_path(context.registers[:site].source, page_path) + Jekyll.sanitized_path(context.registers[:site].source, page_path(context)) end end end