jekyll-octopod 0.23.0 → 0.24.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2e8a41ff862f72c1aec7028926e077d7bd3d6f202a3139b2e733d1ea2033b2df
4
- data.tar.gz: 3a9f0249e0039acc36666d3e3c74d450864677b73967b63ff8f79e75a7cf90d3
3
+ metadata.gz: d953001b39397be865714d7b3ed448dc513ae4673d1c362bacead88d51897be9
4
+ data.tar.gz: 5c0f42e40cec30b2977f495df8169f5f92d5b2c02a38b9a8320c9613cc456e06
5
5
  SHA512:
6
- metadata.gz: ff581e079d12768deded21853f2568ce4a1fbe03c42187e81f1cf8016979f2fe9f3deaed583cf93ec436f8f9f7cfb20e00b90ee1d20f98700836d35eb3120140
7
- data.tar.gz: 62c687c7c7b91ff57ea896b6145bb7e8b16c786d358ae95ac1c3095dc96db89e8a5fbe9d012498e74162215c97d429c3abf908e02e1aef2e36d3903425761508
6
+ metadata.gz: 8c5b98504862f358426070babb61db21df771c307070b2408631896dcb133a187aa6b5eb807dc981cff65cd0968d3b39626082e91fbdeffbc9cc00ef76e6d360
7
+ data.tar.gz: e8884a4dac88e26b5ebad5230451524b6cdd9cdc12a86eda7b9bd9af1e885d66c64f8d81c98ea5816335ed1c9e04ac6590ece78aa54d2d75dd2b320df6218023
@@ -26,6 +26,20 @@ rsync_delete: true
26
26
  ### Fediverse config, optional
27
27
  fediverse_url: https://podcasts.social/@my_account # Fediverse links will not be shown unless this is set
28
28
 
29
+ ### Feed permalinks, optional: by default the episode feeds live at /episodes.<format>.rss. When
30
+ ### migrating a podcast from another platform, keep its old feed URL so subscribers don't have to
31
+ ### resubscribe (a path ending in "/" is written as index.html, which every web server serves).
32
+ # episode_feed_permalinks:
33
+ # mp3: /feed/mp3/
34
+
35
+ ### Transcript speakers, optional: map WebVTT voice tags (<v Thomas>) to names and avatars shown
36
+ ### in the player's transcript. Without this, the voice tag itself is shown as the speaker's name.
37
+ # speakers:
38
+ # - id: thomas
39
+ # name: Thomas Kahle
40
+ # voice: Thomas # defaults to name
41
+ # avatar: /assets/img/speakers/thomas.jpg
42
+
29
43
  language: en
30
44
  explicit: "no" # "yes" | "no" | clean
31
45
 
@@ -283,7 +283,7 @@ module Jekyll
283
283
 
284
284
  if site['episode_feed_formats']
285
285
  site['episode_feed_formats'].map { |f|
286
- feeds << ["#{f} Episode RSS-Feed", "#{site['url']}/episodes.#{f}.rss"] unless f == except
286
+ feeds << ["#{f} Episode RSS-Feed", OctopodFilters.feed_url(site, f)] unless f == except
287
287
  }
288
288
  end
289
289
  if site['additional_feeds']
@@ -295,6 +295,33 @@ module Jekyll
295
295
  feeds
296
296
  end
297
297
 
298
+ # Path of an episode feed page, relative to the site root. By default that's
299
+ # '/episodes.<format>.rss' (page 1) and '/episodes<n>.<format>.rss' (page n). The
300
+ # 'episode_feed_permalinks' setting in '_config.yml' moves page 1 of a format elsewhere, e.g. to
301
+ # keep the feed URL of a podcast migrated from another platform:
302
+ #
303
+ # episode_feed_permalinks:
304
+ # mp3: /feed/mp3/
305
+ def self.feed_path(site, format, page_number = 1)
306
+ permalink = (site['episode_feed_permalinks'] || {})[format.to_s]
307
+ if page_number == 1 && permalink && !permalink.to_s.strip.empty?
308
+ permalink.start_with?('/') ? permalink : "/#{permalink}"
309
+ else
310
+ "/episodes#{page_number == 1 ? '' : page_number}.#{format}.rss"
311
+ end
312
+ end
313
+
314
+ def self.feed_url(site, format, page_number = 1)
315
+ "#{site['url']}#{feed_path(site, format, page_number)}"
316
+ end
317
+
318
+ # Returns the full URL of an episode feed, honouring 'episode_feed_permalinks'.
319
+ #
320
+ # {{ site | episode_feed_url:'mp3' }} => https://example.com/episodes.mp3.rss
321
+ def episode_feed_url(site, format)
322
+ OctopodFilters.feed_url(site, format)
323
+ end
324
+
298
325
  # Returns HTML links to all episode feeds named by the convetion
299
326
  # 'episodes.<episode_file_format>.rss' within the root directory. Also it
300
327
  # returns all additional feeds specified by 'additional_feeds' in the
@@ -18,6 +18,33 @@ module Jekyll
18
18
  self.data['myself'] = page_number == 1 ? nil : page_number.to_s
19
19
  self.data['format'] = format
20
20
  self.data['page_number'] = page_number
21
+
22
+ # Full URLs for the feed's self/first/last/next/prev links, so the theme doesn't have to
23
+ # rebuild them from the naming convention (which an 'episode_feed_permalinks' entry changes).
24
+ config = site.config
25
+ self.data['self_url'] = OctopodFilters.feed_url(config, format, page_number)
26
+ self.data['first_url'] = OctopodFilters.feed_url(config, format, 1)
27
+ self.data['last_url'] = OctopodFilters.feed_url(config, format, [pages_total, 1].max)
28
+ self.data['next_url'] = OctopodFilters.feed_url(config, format, page_number + 1) if pages_total > page_number
29
+ self.data['prev_url'] = OctopodFilters.feed_url(config, format, page_number - 1) if page_number > 1
30
+
31
+ # Only the canonical first page moves; the generator's duplicate "episodes1.<format>.rss"
32
+ # stays where it is.
33
+ if name == "episodes.#{format}.rss"
34
+ path = OctopodFilters.feed_path(config, format, 1)
35
+ @feed_path = path unless path == "/#{name}"
36
+ self.data['permalink'] = @feed_path if @feed_path
37
+ end
38
+ end
39
+
40
+ # A custom feed path ending in "/" (like Podlove's "/feed/mp3/") is written as index.html, the
41
+ # one directory index every web server serves without extra configuration. Jekyll's default
42
+ # would be index.rss, which no server picks up for a directory URL.
43
+ def destination(dest)
44
+ return super unless @feed_path
45
+
46
+ path = @feed_path.end_with?('/') ? "#{@feed_path}index.html" : @feed_path
47
+ site.in_dest_dir(dest, URL.unescape_path(path))
21
48
  end
22
49
  end
23
- end
50
+ end
@@ -45,9 +45,44 @@ module Jekyll
45
45
  duration: page["duration"],
46
46
  audio: audio,
47
47
  chapters: page["chapters"] ? page["chapters"].map { |chapter| split_chapter(chapter) }.compact : nil,
48
- transcripts: transcripts_for(page),
49
48
  share: { channels: SHARE_CHANNELS }
50
- }.to_json
49
+ }.merge(transcripts_and_contributors(page, config).compact).to_json
50
+ end
51
+
52
+ # The player shows a transcript cue's speaker by looking cue[:speaker] up by id in the
53
+ # top-level "contributors" list (and ignores cue[:voice] entirely), so the VTT voice tags only
54
+ # become visible names/avatars - and paragraph breaks at each speaker change - once both are
55
+ # filled in. Speakers can be declared per post or site-wide:
56
+ #
57
+ # speakers:
58
+ # - id: thomas
59
+ # name: Thomas Kahle
60
+ # voice: Thomas # matches <v Thomas>, defaults to name
61
+ # avatar: /assets/img/speakers/thomas.jpg
62
+ #
63
+ # Voices without a declared speaker still get a contributor named after the voice itself, so
64
+ # speaker names work out of the box without any configuration.
65
+ def transcripts_and_contributors(page, config)
66
+ speakers = page["speakers"] || config["speakers"] || []
67
+ contributors = speakers.map do |speaker|
68
+ avatar = speaker["avatar"]
69
+ avatar = config["url"] + avatar if avatar&.start_with?("/")
70
+ { id: speaker["id"].to_s, name: speaker["name"], avatar: avatar, group: speaker["group"] }.compact
71
+ end
72
+ id_by_voice = speakers.to_h { |speaker| [speaker["voice"] || speaker["name"], speaker["id"].to_s] }
73
+
74
+ transcripts = transcripts_for(page)
75
+ transcripts&.each do |cue|
76
+ next unless cue[:voice]
77
+
78
+ unless id_by_voice.key?(cue[:voice])
79
+ id_by_voice[cue[:voice]] = cue[:voice]
80
+ contributors << { id: cue[:voice], name: cue[:voice] }
81
+ end
82
+ cue[:speaker] = id_by_voice[cue[:voice]]
83
+ end
84
+
85
+ { transcripts: transcripts, contributors: contributors.empty? ? nil : contributors }
51
86
  end
52
87
 
53
88
  # Finds a WebVTT transcript for this episode and parses it into the cue list Podlove Web
@@ -2,7 +2,7 @@ module Jekyll
2
2
  class Octopod
3
3
  module VERSION #:nodoc:
4
4
  MAJOR = 0
5
- MINOR = 23
5
+ MINOR = 24
6
6
  TINY = 0
7
7
 
8
8
  STRING = [MAJOR, MINOR, TINY].join('.')
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jekyll-octopod
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.23.0
4
+ version: 0.24.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Arne Eilermann