jekyll 3.8.7 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +71 -62
  3. data/LICENSE +1 -1
  4. data/README.markdown +46 -17
  5. data/lib/blank_template/_config.yml +3 -0
  6. data/lib/blank_template/_layouts/default.html +12 -0
  7. data/lib/blank_template/_sass/main.scss +9 -0
  8. data/lib/blank_template/assets/css/main.scss +4 -0
  9. data/lib/blank_template/index.md +8 -0
  10. data/lib/jekyll.rb +10 -1
  11. data/lib/jekyll/cache.rb +190 -0
  12. data/lib/jekyll/cleaner.rb +5 -4
  13. data/lib/jekyll/collection.rb +82 -10
  14. data/lib/jekyll/command.rb +33 -6
  15. data/lib/jekyll/commands/build.rb +11 -20
  16. data/lib/jekyll/commands/clean.rb +2 -0
  17. data/lib/jekyll/commands/doctor.rb +15 -8
  18. data/lib/jekyll/commands/help.rb +1 -1
  19. data/lib/jekyll/commands/new.rb +37 -35
  20. data/lib/jekyll/commands/new_theme.rb +30 -28
  21. data/lib/jekyll/commands/serve.rb +55 -81
  22. data/lib/jekyll/commands/serve/live_reload_reactor.rb +6 -10
  23. data/lib/jekyll/commands/serve/servlet.rb +22 -25
  24. data/lib/jekyll/commands/serve/websockets.rb +1 -1
  25. data/lib/jekyll/configuration.rb +61 -149
  26. data/lib/jekyll/converters/identity.rb +18 -0
  27. data/lib/jekyll/converters/markdown.rb +49 -40
  28. data/lib/jekyll/converters/markdown/kramdown_parser.rb +84 -11
  29. data/lib/jekyll/converters/smartypants.rb +34 -14
  30. data/lib/jekyll/convertible.rb +30 -31
  31. data/lib/jekyll/deprecator.rb +1 -3
  32. data/lib/jekyll/document.rb +89 -61
  33. data/lib/jekyll/drops/collection_drop.rb +2 -3
  34. data/lib/jekyll/drops/document_drop.rb +14 -1
  35. data/lib/jekyll/drops/drop.rb +17 -14
  36. data/lib/jekyll/drops/excerpt_drop.rb +4 -0
  37. data/lib/jekyll/drops/page_drop.rb +18 -0
  38. data/lib/jekyll/drops/site_drop.rb +6 -5
  39. data/lib/jekyll/drops/unified_payload_drop.rb +1 -0
  40. data/lib/jekyll/drops/url_drop.rb +53 -1
  41. data/lib/jekyll/entry_filter.rb +42 -45
  42. data/lib/jekyll/excerpt.rb +45 -34
  43. data/lib/jekyll/external.rb +10 -5
  44. data/lib/jekyll/filters.rb +200 -40
  45. data/lib/jekyll/filters/date_filters.rb +6 -3
  46. data/lib/jekyll/filters/grouping_filters.rb +1 -2
  47. data/lib/jekyll/filters/url_filters.rb +46 -14
  48. data/lib/jekyll/frontmatter_defaults.rb +46 -35
  49. data/lib/jekyll/hooks.rb +4 -8
  50. data/lib/jekyll/inclusion.rb +32 -0
  51. data/lib/jekyll/liquid_extensions.rb +0 -2
  52. data/lib/jekyll/liquid_renderer.rb +31 -16
  53. data/lib/jekyll/liquid_renderer/file.rb +24 -3
  54. data/lib/jekyll/liquid_renderer/table.rb +36 -77
  55. data/lib/jekyll/log_adapter.rb +5 -1
  56. data/lib/jekyll/mime.types +53 -11
  57. data/lib/jekyll/page.rb +54 -12
  58. data/lib/jekyll/page_excerpt.rb +26 -0
  59. data/lib/jekyll/page_without_a_file.rb +0 -4
  60. data/lib/jekyll/path_manager.rb +31 -0
  61. data/lib/jekyll/plugin.rb +5 -11
  62. data/lib/jekyll/plugin_manager.rb +2 -0
  63. data/lib/jekyll/profiler.rb +58 -0
  64. data/lib/jekyll/reader.rb +42 -9
  65. data/lib/jekyll/readers/collection_reader.rb +1 -0
  66. data/lib/jekyll/readers/data_reader.rb +8 -9
  67. data/lib/jekyll/readers/layout_reader.rb +3 -12
  68. data/lib/jekyll/readers/page_reader.rb +5 -5
  69. data/lib/jekyll/readers/post_reader.rb +31 -18
  70. data/lib/jekyll/readers/static_file_reader.rb +4 -4
  71. data/lib/jekyll/readers/theme_assets_reader.rb +8 -5
  72. data/lib/jekyll/regenerator.rb +4 -12
  73. data/lib/jekyll/renderer.rb +23 -40
  74. data/lib/jekyll/site.rb +91 -38
  75. data/lib/jekyll/static_file.rb +62 -21
  76. data/lib/jekyll/stevenson.rb +2 -3
  77. data/lib/jekyll/tags/highlight.rb +19 -51
  78. data/lib/jekyll/tags/include.rb +82 -42
  79. data/lib/jekyll/tags/link.rb +11 -7
  80. data/lib/jekyll/tags/post_url.rb +25 -21
  81. data/lib/jekyll/theme.rb +16 -18
  82. data/lib/jekyll/theme_builder.rb +91 -89
  83. data/lib/jekyll/url.rb +10 -5
  84. data/lib/jekyll/utils.rb +18 -21
  85. data/lib/jekyll/utils/ansi.rb +1 -1
  86. data/lib/jekyll/utils/exec.rb +0 -1
  87. data/lib/jekyll/utils/internet.rb +2 -4
  88. data/lib/jekyll/utils/platforms.rb +8 -8
  89. data/lib/jekyll/utils/thread_event.rb +1 -5
  90. data/lib/jekyll/utils/win_tz.rb +2 -2
  91. data/lib/jekyll/version.rb +1 -1
  92. data/lib/site_template/.gitignore +2 -0
  93. data/lib/site_template/404.html +1 -0
  94. data/lib/site_template/_config.yml +17 -5
  95. data/lib/site_template/_posts/0000-00-00-welcome-to-jekyll.markdown.erb +5 -1
  96. data/lib/site_template/{about.md → about.markdown} +0 -0
  97. data/lib/site_template/{index.md → index.markdown} +0 -0
  98. data/lib/theme_template/gitignore.erb +1 -0
  99. data/lib/theme_template/theme.gemspec.erb +1 -4
  100. data/rubocop/jekyll/assert_equal_literal_actual.rb +149 -0
  101. metadata +69 -31
  102. data/lib/jekyll/converters/markdown/rdiscount_parser.rb +0 -37
  103. data/lib/jekyll/converters/markdown/redcarpet_parser.rb +0 -112
  104. data/lib/jekyll/utils/rouge.rb +0 -22
@@ -1,96 +1,55 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Jekyll
4
- class LiquidRenderer::Table
5
- def initialize(stats)
6
- @stats = stats
7
- end
8
-
9
- def to_s(num_of_rows = 50)
10
- data = data_for_table(num_of_rows)
11
- widths = table_widths(data)
12
- generate_table(data, widths)
13
- end
14
-
15
- private
16
-
17
- def generate_table(data, widths)
18
- str = String.new("\n")
19
-
20
- table_head = data.shift
21
- str << generate_row(table_head, widths)
22
- str << generate_table_head_border(table_head, widths)
4
+ class LiquidRenderer
5
+ class Table
6
+ GAUGES = [:count, :bytes, :time].freeze
23
7
 
24
- data.each do |row_data|
25
- str << generate_row(row_data, widths)
8
+ def initialize(stats)
9
+ @stats = stats
26
10
  end
27
11
 
28
- str << "\n"
29
- str
30
- end
31
-
32
- def generate_table_head_border(row_data, widths)
33
- str = String.new("")
34
-
35
- row_data.each_index do |cell_index|
36
- str << "-" * widths[cell_index]
37
- str << "-+-" unless cell_index == row_data.length - 1
12
+ def to_s(num_of_rows = 50)
13
+ Jekyll::Profiler.tabulate(data_for_table(num_of_rows))
38
14
  end
39
15
 
40
- str << "\n"
41
- str
42
- end
43
-
44
- def generate_row(row_data, widths)
45
- str = String.new("")
16
+ private
46
17
 
47
- row_data.each_with_index do |cell_data, cell_index|
48
- str << if cell_index.zero?
49
- cell_data.ljust(widths[cell_index], " ")
50
- else
51
- cell_data.rjust(widths[cell_index], " ")
52
- end
18
+ # rubocop:disable Metrics/AbcSize
19
+ def data_for_table(num_of_rows)
20
+ sorted = @stats.sort_by { |_, file_stats| -file_stats[:time] }
21
+ sorted = sorted.slice(0, num_of_rows)
53
22
 
54
- str << " | " unless cell_index == row_data.length - 1
55
- end
23
+ table = [header_labels]
24
+ totals = Hash.new { |hash, key| hash[key] = 0 }
56
25
 
57
- str << "\n"
58
- str
59
- end
60
-
61
- def table_widths(data)
62
- widths = []
63
-
64
- data.each do |row|
65
- row.each_with_index do |cell, index|
66
- widths[index] = [cell.length, widths[index]].compact.max
26
+ sorted.each do |filename, file_stats|
27
+ GAUGES.each { |gauge| totals[gauge] += file_stats[gauge] }
28
+ row = []
29
+ row << filename
30
+ row << file_stats[:count].to_s
31
+ row << format_bytes(file_stats[:bytes])
32
+ row << format("%.3f", file_stats[:time])
33
+ table << row
67
34
  end
68
- end
69
-
70
- widths
71
- end
72
35
 
73
- def data_for_table(num_of_rows)
74
- sorted = @stats.sort_by { |_, file_stats| -file_stats[:time] }
75
- sorted = sorted.slice(0, num_of_rows)
76
-
77
- table = [%w(Filename Count Bytes Time)]
78
-
79
- sorted.each do |filename, file_stats|
80
- row = []
81
- row << filename
82
- row << file_stats[:count].to_s
83
- row << format_bytes(file_stats[:bytes])
84
- row << format("%.3f", file_stats[:time])
85
- table << row
36
+ footer = []
37
+ footer << "TOTAL (for #{sorted.size} files)"
38
+ footer << totals[:count].to_s
39
+ footer << format_bytes(totals[:bytes])
40
+ footer << format("%.3f", totals[:time])
41
+ table << footer
86
42
  end
43
+ # rubocop:enable Metrics/AbcSize
87
44
 
88
- table
89
- end
45
+ def header_labels
46
+ GAUGES.map { |gauge| gauge.to_s.capitalize }.unshift("Filename")
47
+ end
90
48
 
91
- def format_bytes(bytes)
92
- bytes /= 1024.0
93
- format("%.2fK", bytes)
49
+ def format_bytes(bytes)
50
+ bytes /= 1024.0
51
+ format("%.2fK", bytes)
52
+ end
94
53
  end
95
54
  end
96
55
  end
@@ -29,7 +29,9 @@ module Jekyll
29
29
  #
30
30
  # Returns nothing
31
31
  def log_level=(level)
32
- writer.level = LOG_LEVELS.fetch(level)
32
+ writer.level = level if level.is_a?(Integer) && level.between?(0, 3)
33
+ writer.level = LOG_LEVELS[level] ||
34
+ raise(ArgumentError, "unknown log level")
33
35
  @level = level
34
36
  end
35
37
 
@@ -41,6 +43,7 @@ module Jekyll
41
43
  self.log_level = :debug
42
44
  end
43
45
  debug "Logging at level:", LOG_LEVELS.key(writer.level).to_s
46
+ debug "Jekyll Version:", Jekyll::VERSION
44
47
  end
45
48
 
46
49
  # Public: Print a debug message
@@ -141,6 +144,7 @@ module Jekyll
141
144
  # the appropriate writer method, e.g. writer.info.
142
145
  def write(level_of_message, topic, message = nil, &block)
143
146
  return false unless write_message?(level_of_message)
147
+
144
148
  writer.public_send(level_of_message, message(topic, message, &block))
145
149
  end
146
150
  end
@@ -19,18 +19,17 @@ application/davmount+xml davmou
19
19
  application/docbook+xml dbk
20
20
  application/dssc+der dssc
21
21
  application/dssc+xml xdssc
22
- application/ecmascript ecma
22
+ application/ecmascript ecma es
23
23
  application/emma+xml emma
24
24
  application/epub+zip epub
25
25
  application/exi exi
26
26
  application/font-tdpfr pfr
27
- application/font-woff woff
28
- application/font-woff2 woff2
29
27
  application/geo+json geojson
30
28
  application/gml+xml gml
31
29
  application/gpx+xml gpx
32
30
  application/gxf gxf
33
31
  application/gzip gz
32
+ application/hjson hjson
34
33
  application/hyperstudio stk
35
34
  application/inkml+xml ink inkml
36
35
  application/ipfix ipfix
@@ -61,6 +60,8 @@ application/mp21 m21 mp
61
60
  application/mp4 mp4s m4p
62
61
  application/msword doc dot
63
62
  application/mxf mxf
63
+ application/n-quads nq
64
+ application/n-triples nt
64
65
  application/octet-stream bin dms lrf mar so dist distz pkg bpk dump elc deploy exe dll deb dmg iso img msi msp msm buffer
65
66
  application/oda oda
66
67
  application/oebps-package+xml opf
@@ -86,7 +87,8 @@ application/pls+xml pls
86
87
  application/postscript ai eps ps
87
88
  application/prs.cww cww
88
89
  application/pskc+xml pskcxml
89
- application/rdf+xml rdf
90
+ application/raml+yaml raml
91
+ application/rdf+xml rdf owl
90
92
  application/reginfo+xml rif
91
93
  application/relax-ng-compact-syntax rnc
92
94
  application/resource-lists+xml rl
@@ -107,6 +109,7 @@ application/sdp sdp
107
109
  application/set-payment-initiation setpay
108
110
  application/set-registration-initiation setreg
109
111
  application/shf+xml shf
112
+ application/sieve siv sieve
110
113
  application/smil+xml smi smil
111
114
  application/sparql-query rq
112
115
  application/sparql-results+xml srx
@@ -143,7 +146,10 @@ application/vnd.anser-web-certificate-issue-initiation cii
143
146
  application/vnd.anser-web-funds-transfer-initiation fti
144
147
  application/vnd.antix.game-component atx
145
148
  application/vnd.apple.installer+xml mpkg
149
+ application/vnd.apple.keynote keynote
146
150
  application/vnd.apple.mpegurl m3u8
151
+ application/vnd.apple.numbers numbers
152
+ application/vnd.apple.pages pages
147
153
  application/vnd.apple.pkpass pkpass
148
154
  application/vnd.aristanetworks.swi swi
149
155
  application/vnd.astraea-software.iota iota
@@ -154,6 +160,7 @@ application/vnd.businessobjects rep
154
160
  application/vnd.chemdraw+xml cdxml
155
161
  application/vnd.chipnuts.karaoke-mmd mmd
156
162
  application/vnd.cinderella cdy
163
+ application/vnd.citationstyles.style+xml csl
157
164
  application/vnd.claymore cla
158
165
  application/vnd.cloanto.rp9 rp9
159
166
  application/vnd.clonk.c4group c4g c4d c4f c4p c4u
@@ -482,6 +489,7 @@ application/vnd.yellowriver-custom-menu cmp
482
489
  application/vnd.zul zir zirz
483
490
  application/vnd.zzazz.deck+xml zaz
484
491
  application/voicexml+xml vxml
492
+ application/wasm wasm
485
493
  application/widget wgt
486
494
  application/winhlp hlp
487
495
  application/wsdl+xml wsdl
@@ -521,10 +529,8 @@ application/x-eva eva
521
529
  application/x-font-bdf bdf
522
530
  application/x-font-ghostscript gsf
523
531
  application/x-font-linux-psf psf
524
- application/x-font-otf otf
525
532
  application/x-font-pcf pcf
526
533
  application/x-font-snf snf
527
- application/x-font-ttf ttf ttc
528
534
  application/x-font-type1 pfa pfb pfm afm
529
535
  application/x-freearc arc
530
536
  application/x-futuresplash spl
@@ -661,20 +667,41 @@ chemical/x-cmdf cmdf
661
667
  chemical/x-cml cml
662
668
  chemical/x-csml csml
663
669
  chemical/x-xyz xyz
670
+ font/collection ttc
671
+ font/otf otf
672
+ font/ttf ttf
673
+ font/woff woff
674
+ font/woff2 woff2
675
+ image/aces exr
664
676
  image/apng apng
665
677
  image/bmp bmp
666
678
  image/cgm cgm
679
+ image/dicom-rle drle
680
+ image/fits fits
667
681
  image/g3fax g3
668
682
  image/gif gif
683
+ image/heic heic
684
+ image/heic-sequence heics
685
+ image/heif heif
686
+ image/heif-sequence heifs
669
687
  image/ief ief
688
+ image/jls jls
689
+ image/jp2 jp2 jpg2
670
690
  image/jpeg jpeg jpg jpe
691
+ image/jpm jpm
692
+ image/jpx jpx jpf
693
+ image/jxr jxr
671
694
  image/ktx ktx
672
695
  image/png png
673
696
  image/prs.btif btif
697
+ image/prs.pti pti
674
698
  image/sgi sgi
675
699
  image/svg+xml svg svgz
676
- image/tiff tiff tif
700
+ image/t38 t38
701
+ image/tiff tif tiff
702
+ image/tiff-fx tfx
677
703
  image/vnd.adobe.photoshop psd
704
+ image/vnd.airzip.accelerator.azv azv
678
705
  image/vnd.dece.graphic uvi uvvi uvg uvvg
679
706
  image/vnd.djvu djvu djv
680
707
  image/vnd.dvb.subtitle sub
@@ -685,20 +712,22 @@ image/vnd.fpx fpx
685
712
  image/vnd.fst fst
686
713
  image/vnd.fujixerox.edmics-mmr mmr
687
714
  image/vnd.fujixerox.edmics-rlc rlc
715
+ image/vnd.microsoft.icon ico
688
716
  image/vnd.ms-modi mdi
689
717
  image/vnd.ms-photo wdp
690
718
  image/vnd.net-fpx npx
719
+ image/vnd.tencent.tap tap
720
+ image/vnd.valve.source.texture vtf
691
721
  image/vnd.wap.wbmp wbmp
692
722
  image/vnd.xiff xif
723
+ image/vnd.zbrush.pcx pcx
693
724
  image/webp webp
694
725
  image/x-3ds 3ds
695
726
  image/x-cmu-raster ras
696
727
  image/x-cmx cmx
697
728
  image/x-freehand fh fhc fh4 fh5 fh7
698
- image/x-icon ico
699
729
  image/x-jng jng
700
730
  image/x-mrsid-image sid
701
- image/x-pcx pcx
702
731
  image/x-pict pic pct
703
732
  image/x-portable-anymap pnm
704
733
  image/x-portable-bitmap pbm
@@ -709,7 +738,14 @@ image/x-tga tga
709
738
  image/x-xbitmap xbm
710
739
  image/x-xpixmap xpm
711
740
  image/x-xwindowdump xwd
741
+ message/disposition-notification disposition-notification
742
+ message/global u8msg
743
+ message/global-delivery-status u8dsn
744
+ message/global-disposition-notification u8mdn
745
+ message/global-headers u8hdr
712
746
  message/rfc822 eml mime
747
+ message/vnd.wfa.wsc wsc
748
+ model/3mf 3mf
713
749
  model/gltf+json gltf
714
750
  model/gltf-binary glb
715
751
  model/iges igs iges
@@ -719,6 +755,11 @@ model/vnd.dwf dwf
719
755
  model/vnd.gdl gdl
720
756
  model/vnd.gtw gtw
721
757
  model/vnd.mts mts
758
+ model/vnd.opengex ogex
759
+ model/vnd.parasolid.transmit.binary x_b
760
+ model/vnd.parasolid.transmit.text x_t
761
+ model/vnd.usdz+zip usdz
762
+ model/vnd.valve.source.compiled-map bsp
722
763
  model/vnd.vtu vtu
723
764
  model/vrml wrl vrml
724
765
  model/x3d+binary x3db x3dbz
@@ -729,18 +770,19 @@ text/calendar ics if
729
770
  text/coffeescript coffee litcoffee
730
771
  text/css css
731
772
  text/csv csv
732
- text/hjson hjson
733
773
  text/html html htm shtml
734
774
  text/jade jade
735
775
  text/jsx jsx
736
776
  text/less less
737
777
  text/markdown markdown md
738
778
  text/mathml mml
779
+ text/mdx mdx
739
780
  text/n3 n3
740
781
  text/plain txt text conf def list log in ini
741
782
  text/prs.lines.tag dsc
742
783
  text/richtext rtx
743
784
  text/sgml sgml sgm
785
+ text/shex shex
744
786
  text/slim slim slm
745
787
  text/stylus stylus styl
746
788
  text/tab-separated-values tsv
@@ -788,7 +830,7 @@ video/h261 h261
788
830
  video/h263 h263
789
831
  video/h264 h264
790
832
  video/jpeg jpgv
791
- video/jpm jpm jpgm
833
+ video/jpm jpgm
792
834
  video/mj2 mj2 mjp2
793
835
  video/mp2t ts
794
836
  video/mp4 mp4 mp4v mpg4
@@ -11,12 +11,11 @@ module Jekyll
11
11
 
12
12
  alias_method :extname, :ext
13
13
 
14
- FORWARD_SLASH = "/".freeze
15
-
16
14
  # Attributes for Liquid templates
17
15
  ATTRIBUTES_FOR_LIQUID = %w(
18
16
  content
19
17
  dir
18
+ excerpt
20
19
  name
21
20
  path
22
21
  url
@@ -49,10 +48,10 @@ module Jekyll
49
48
  end
50
49
 
51
50
  process(name)
52
- read_yaml(File.join(base, dir), name)
51
+ read_yaml(PathManager.join(base, dir), name)
53
52
 
54
53
  data.default_proc = proc do |_, key|
55
- site.frontmatter_defaults.find(File.join(dir, name), type, key)
54
+ site.frontmatter_defaults.find(relative_path, type, key)
56
55
  end
57
56
 
58
57
  Jekyll::Hooks.trigger :pages, :post_init, self
@@ -64,13 +63,45 @@ module Jekyll
64
63
  #
65
64
  # Returns the String destination directory.
66
65
  def dir
67
- if url.end_with?(FORWARD_SLASH)
66
+ if url.end_with?("/")
68
67
  url
69
68
  else
70
69
  url_dir = File.dirname(url)
71
- url_dir.end_with?(FORWARD_SLASH) ? url_dir : "#{url_dir}/"
70
+ url_dir.end_with?("/") ? url_dir : "#{url_dir}/"
71
+ end
72
+ end
73
+
74
+ # For backwards-compatibility in subclasses that do not redefine
75
+ # the `:to_liquid` method, stash existing definition under a new name
76
+ #
77
+ # TODO: Remove in Jekyll 5.0
78
+ alias_method :legacy_to_liquid, :to_liquid
79
+ private :legacy_to_liquid
80
+
81
+ # Private
82
+ # Subclasses can choose to optimize their `:to_liquid` method by wrapping
83
+ # it around this definition.
84
+ #
85
+ # TODO: Remove in Jekyll 5.0
86
+ def liquid_drop
87
+ @liquid_drop ||= begin
88
+ defaults = site.frontmatter_defaults.all(relative_path, type)
89
+ unless defaults.empty?
90
+ Utils.deep_merge_hashes!(data, Utils.deep_merge_hashes!(defaults, data))
91
+ end
92
+ Drops::PageDrop.new(self)
72
93
  end
73
94
  end
95
+ private :liquid_drop
96
+
97
+ # Public
98
+ #
99
+ # Liquid representation of current page
100
+ #
101
+ # TODO: Remove optional parameter in Jekyll 5.0
102
+ def to_liquid(attrs = nil)
103
+ self.class == Jekyll::Page ? liquid_drop : legacy_to_liquid(attrs)
104
+ end
74
105
 
75
106
  # The full path and filename of the post. Defined in the YAML of the post
76
107
  # body.
@@ -97,11 +128,11 @@ module Jekyll
97
128
  #
98
129
  # Returns the String url.
99
130
  def url
100
- @url ||= URL.new({
131
+ @url ||= URL.new(
101
132
  :template => template,
102
133
  :placeholders => url_placeholders,
103
- :permalink => permalink,
104
- }).to_s
134
+ :permalink => permalink
135
+ ).to_s
105
136
  end
106
137
 
107
138
  # Returns a hash of URL placeholder names (as symbols) mapping to the
@@ -118,10 +149,11 @@ module Jekyll
118
149
  #
119
150
  # name - The String filename of the page file.
120
151
  #
152
+ # NOTE: `String#gsub` removes all trailing periods (in comparison to `String#chomp`)
121
153
  # Returns nothing.
122
154
  def process(name)
123
155
  self.ext = File.extname(name)
124
- self.basename = name[0..-ext.length - 1]
156
+ self.basename = name[0..-ext.length - 1].gsub(%r!\.*\z!, "")
125
157
  end
126
158
 
127
159
  # Add any necessary layouts to this post
@@ -146,7 +178,7 @@ module Jekyll
146
178
 
147
179
  # The path to the page source file, relative to the site source
148
180
  def relative_path
149
- File.join(*[@dir, @name].map(&:to_s).reject(&:empty?)).sub(%r!\A\/!, "")
181
+ @relative_path ||= File.join(*[@dir, @name].map(&:to_s).reject(&:empty?)).sub(%r!\A\/!, "")
150
182
  end
151
183
 
152
184
  # Obtain destination path.
@@ -163,7 +195,7 @@ module Jekyll
163
195
 
164
196
  # Returns the object as a debug String.
165
197
  def inspect
166
- "#<Jekyll::Page @name=#{name.inspect}>"
198
+ "#<#{self.class} @relative_path=#{relative_path.inspect}>"
167
199
  end
168
200
 
169
201
  # Returns the Boolean of whether this Page is HTML or not.
@@ -183,5 +215,15 @@ module Jekyll
183
215
  def write?
184
216
  true
185
217
  end
218
+
219
+ def excerpt_separator
220
+ @excerpt_separator ||= (data["excerpt_separator"] || site.config["excerpt_separator"]).to_s
221
+ end
222
+
223
+ def excerpt
224
+ return data["excerpt"] unless self.class == Jekyll::Page
225
+
226
+ data["excerpt"] ||= Jekyll::PageExcerpt.new(self).to_liquid unless excerpt_separator.empty?
227
+ end
186
228
  end
187
229
  end