presently 0.27.0 → 0.29.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: d8b031e64df9f01cd66eb315891ac4bf2b851f78355025afdf3f849a3a7513e5
4
- data.tar.gz: 860837d5f75beaa2d814e388b401a297ce0af0ec4eb8e96eb99459fd79fa5460
3
+ metadata.gz: 98c94c71298a2801441e3a2351c72e09b3c2e3dfdfde63a4d5b7673d42334aac
4
+ data.tar.gz: 15d88cf5bf1f4ddb3574c0f2ece5df062378650a1526bb14de74e20adb27354b
5
5
  SHA512:
6
- metadata.gz: 62a0c52ebb93318dd390592ea580b1fa4883891b36d66339669bdbb98dc8e202af97517f375d463fac720034ec90e2b36f62ef1f5784fba29103e49eb57c4b55
7
- data.tar.gz: f93b4b3b5a00275be37ec3a1a4d4760c41e270193a501a8f9a3030849e0765dcf6dab04cc3c7f92519fdc80b7950a52b259e9864f583e09b397dcbc6cd102a1c
6
+ metadata.gz: e0eb7788c6108fd1b16bfcac25deeeeb91c75e9af3e45f9b994351674931842880ce28567ccc30773e50d7a0f6d0c260f31e0db27d55a579121137e7a9ce912c
7
+ data.tar.gz: 8945b51b03abb5929c28267a544ed88e4f09b8baf342e33a2761f47d457e2476da320d3a7756319f0c2ebc8065ebe709d9b936c053a9d25c76eeffd533b67deb
checksums.yaml.gz.sig CHANGED
Binary file
@@ -112,6 +112,36 @@ Relative images embedded in Markdown resolve from the Markdown file's directory,
112
112
 
113
113
  Presently loads each discovered stylesheet once in deterministic presentation order. Directory styles are loaded from parent to child before the matching slide sidecar, so more specific styles naturally appear later in the cascade. The same stylesheets are used by the display, presenter, recorder, playback, and export interfaces.
114
114
 
115
+ ### Background Images
116
+
117
+ Add a background image behind any slide template using frontmatter:
118
+
119
+ ``` markdown
120
+ ---
121
+ template: title
122
+ background: images/mountains.jpg
123
+ background-size: cover
124
+ ---
125
+
126
+ # Welcome
127
+ ```
128
+
129
+ The background fills the available slide surface, including space outside the 16:9 content area. Content keeps its 16:9 layout. Images are centred and do not repeat.
130
+
131
+ Relative image paths resolve from the slide file's directory, just like Markdown images. Root-relative paths and external URLs are also supported.
132
+
133
+ `background-size` accepts:
134
+
135
+ | Value | Behaviour |
136
+ |---|---|
137
+ | `cover` (default) | Preserves proportions and fills the surface, cropping the image when necessary. |
138
+ | `contain` | Preserves proportions and shows the whole image, potentially leaving uncovered space. |
139
+ | `auto` | Uses the image's natural size. |
140
+
141
+ Missing or unrecognised sizes use `cover`. An explicit background image replaces the template's background image or gradient; uncovered space shows the underlying slide background colour. Slides without a background image retain their template's appearance.
142
+
143
+ Backgrounds appear in the display, presenter previews, recorder, playback, and PDF export. A preview or export with a different aspect ratio can crop the image differently from the audience display.
144
+
115
145
  ### Running the Presentation
116
146
 
117
147
  Start the server from your presentation directory:
@@ -272,24 +272,31 @@ module Presently
272
272
  # @parameter source_path [String] The Markdown source path.
273
273
  # @parameter root [String] The presentation asset root.
274
274
  def rewrite_image_urls!(document, source_path, root)
275
+ document.walk do |node|
276
+ node.url = resolve_image_url(node.url, source_path, root) if node.type == :image
277
+ end
278
+ end
279
+
280
+ # Resolve an image URL relative to its source file within the presentation.
281
+ # @parameter url [String] The image URL.
282
+ # @parameter source_path [String] The source file path.
283
+ # @parameter root [String] The presentation asset root.
284
+ # @returns [String] The resolved URL, preserving absolute URLs.
285
+ def resolve_image_url(url, source_path, root)
286
+ reference = Protocol::URL[url]
287
+ return url unless reference.is_a?(Protocol::URL::Relative)
288
+ return url if reference.path.empty? || reference.path.absolute?
289
+
275
290
  directory = File.dirname(File.expand_path(source_path))
276
291
  root = File.expand_path(root)
277
- return unless directory == root || directory.start_with?(root + File::SEPARATOR)
292
+ return url unless directory == root || directory.start_with?(root + File::SEPARATOR)
278
293
 
279
294
  relative_directory = directory.delete_prefix(root).delete_prefix(File::SEPARATOR)
280
295
  base_path = Stylesheet::PREFIX
281
296
  base_path += Stylesheet.encode_path(relative_directory) + "/" unless relative_directory.empty?
282
297
  base_url = Protocol::URL::Relative.new(base_path)
283
298
 
284
- document.walk do |node|
285
- next unless node.type == :image
286
-
287
- url = Protocol::URL[node.url]
288
- next unless url.is_a?(Protocol::URL::Relative)
289
- next if url.path.empty? || url.path.absolute?
290
-
291
- node.url = (base_url + url).to_s
292
- end
299
+ (base_url + reference).to_s
293
300
  end
294
301
 
295
302
  end
@@ -348,6 +355,22 @@ module Presently
348
355
  @front_matter&.fetch("template", "default") || "default"
349
356
  end
350
357
 
358
+ # The background image URL, resolved relative to this slide's source file.
359
+ # @returns [String | Nil] The URL, or `nil` when no image is specified.
360
+ def background
361
+ value = @front_matter&.fetch("background", nil)
362
+ return unless value.is_a?(String) && !value.strip.empty?
363
+
364
+ Parser.resolve_image_url(value, source_path, @presentation.root)
365
+ end
366
+
367
+ # How the background image is sized within the full slide surface.
368
+ # @returns [String] `"cover"`, `"contain"`, or `"auto"`, defaulting to `"cover"`.
369
+ def background_size
370
+ value = @front_matter&.fetch("background-size", nil)
371
+ ["cover", "contain", "auto"].include?(value) ? value : "cover"
372
+ end
373
+
351
374
  # The expected duration of this slide in seconds.
352
375
  # Negative, invalid, or non-finite values are treated as zero.
353
376
  # @returns [Float] A finite duration of at least `0.0`, defaulting to `0.0` when unspecified or null.
@@ -50,7 +50,14 @@ module Presently
50
50
  classes = classes.compact.join(" ")
51
51
  path = Stylesheet.encode_path(slide.path)
52
52
 
53
- builder.tag(:div, class: "slide-surface", data: {template: slide.template}) do
53
+ background = slide.background
54
+ if background
55
+ # Escape the CSS string independently of the builder's HTML escaping:
56
+ url = background.gsub(/["\\\x00-\x1f\x7f]/){|character| "\\#{character.ord.to_s(16)} "}
57
+ style = %(background-image: url("#{url}"); background-size: #{slide.background_size};)
58
+ end
59
+
60
+ builder.tag(:div, class: "slide-surface", data: {template: slide.template, background: background}, style: style) do
54
61
  builder.tag(:div, class: classes, data: {template: slide.template}, "data-slide-path": path) do
55
62
  builder.raw(html)
56
63
 
@@ -5,5 +5,5 @@
5
5
 
6
6
  # @namespace
7
7
  module Presently
8
- VERSION = "0.27.0"
8
+ VERSION = "0.29.0"
9
9
  end
@@ -4,8 +4,19 @@ import {runScript} from './Scripts.js';
4
4
 
5
5
  const SLIDE_CHANGE_EVENT = 'presently:slide:change';
6
6
 
7
- async function prepareSlides() {
8
- await Syntax.highlight();
7
+ // Wait for background images to decode before capturing a transition or export.
8
+ // A missing or invalid image must not prevent the slides from becoming ready.
9
+ export async function prepareSlideBackgrounds(root = document) {
10
+ const urls = new Set(Array.from(root.querySelectorAll('.slide-surface[data-background]'), surface => surface.dataset.background));
11
+ await Promise.all(Array.from(urls, async url => {
12
+ const image = new Image();
13
+ image.src = url;
14
+ await image.decode().catch(() => {});
15
+ }));
16
+ }
17
+
18
+ async function prepareSlides(view) {
19
+ await Promise.all([Syntax.highlight(), prepareSlideBackgrounds(view)]);
9
20
  await applyCodeFocus();
10
21
  }
11
22
 
@@ -42,7 +53,7 @@ export class SlideRendering {
42
53
  if (slide) this.#slides.push(slide);
43
54
  });
44
55
 
45
- await prepareSlides();
56
+ await prepareSlides(this.#view);
46
57
  return !this.#disposed;
47
58
  }
48
59
 
@@ -1,4 +1,4 @@
1
1
  export {Slide, SlideBuilder, SlideContext, SlideElements} from './Presently/Slide.js';
2
2
  export {applyCodeFocus} from './Presently/CodeFocus.js';
3
- export {SlideRendering} from './Presently/SlideRendering.js';
3
+ export {SlideRendering, prepareSlideBackgrounds} from './Presently/SlideRendering.js';
4
4
  export {runAllSlideScripts, runScript} from './Presently/Scripts.js';
@@ -8,6 +8,7 @@
8
8
  --slide-text: #eee;
9
9
  --accent: #e94560;
10
10
  --accent-light: #ff6b81;
11
+ --text-emphasis: #6bb8ff;
11
12
  --surface: #16213e;
12
13
  --surface-light: #0f3460;
13
14
  --font-sans: "Inter", "Helvetica Neue", Arial, sans-serif;
@@ -189,7 +190,7 @@ a {
189
190
  ======================== */
190
191
 
191
192
  strong, b {
192
- color: var(--accent-light);
193
+ color: var(--text-emphasis);
193
194
  }
194
195
 
195
196
  code {
@@ -17,6 +17,9 @@
17
17
  place-items: center;
18
18
  container-type: size;
19
19
  background: var(--slide-background);
20
+ background-size: cover;
21
+ background-position: center;
22
+ background-repeat: no-repeat;
20
23
  }
21
24
 
22
25
  .slide {
@@ -159,7 +162,7 @@
159
162
 
160
163
  /* Section template */
161
164
  .slide-surface[data-template="section"] {
162
- background: linear-gradient(135deg, var(--accent), var(--surface-light));
165
+ background-image: linear-gradient(135deg, var(--accent), var(--surface-light));
163
166
  }
164
167
 
165
168
  .section-template {
data/public/export.js CHANGED
@@ -1,4 +1,4 @@
1
- import {applyCodeFocus, runAllSlideScripts} from '@socketry/presently';
1
+ import {applyCodeFocus, runAllSlideScripts, prepareSlideBackgrounds} from '@socketry/presently';
2
2
  import Syntax from '@socketry/syntax';
3
3
 
4
4
  // Wait for two animation frames, ensuring the browser has processed all pending
@@ -9,15 +9,16 @@ function waitForRender() {
9
9
  }
10
10
 
11
11
  async function main() {
12
- // 1. Kick off syntax highlighting and font loading concurrently.
12
+ // 1. Kick off syntax highlighting, background decoding, and font loading concurrently.
13
13
  // Slide scripts are synchronous and don't depend on either, so run them now.
14
14
  const syntaxDone = Syntax.highlight();
15
+ const backgroundsDone = prepareSlideBackgrounds();
15
16
 
16
17
  // 2. Run slide scripts (synchronous in export mode — sets visibility instantly).
17
18
  runAllSlideScripts({animated: false});
18
19
 
19
- // 3. Wait for syntax and fonts to finish before applying focus.
20
- await Promise.all([syntaxDone, document.fonts.ready]);
20
+ // 3. Wait for syntax, backgrounds, and fonts to finish before applying focus.
21
+ await Promise.all([syntaxDone, backgroundsDone, document.fonts.ready]);
21
22
 
22
23
  // 4. Apply code focus now that syntax-code elements are ready.
23
24
  await applyCodeFocus();
data/readme.md CHANGED
@@ -155,12 +155,14 @@ bundle exec sus
155
155
 
156
156
  ### Making Releases
157
157
 
158
- To make a new release:
158
+ To prepare a release branch and open a pull request from an up-to-date `main`:
159
159
 
160
160
  ``` shell
161
- bundle exec bake gem:release:patch # or minor or major
161
+ bundle exec bake gem:github:release:patch # or minor or major
162
162
  ```
163
163
 
164
+ See [bake-gem-github](https://github.com/socketry/bake-gem-github) for setup, remote releases, and recovery.
165
+
164
166
  ### Developer Certificate of Origin
165
167
 
166
168
  In order to protect users of this project, we require all contributors to comply with the [Developer Certificate of Origin](https://developercertificate.org/). This ensures that all contributions are properly licensed and attributed.
data/release.cert ADDED
@@ -0,0 +1,24 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIEFDCCAnygAwIBAgIBATANBgkqhkiG9w0BAQsFADAwMREwDwYDVQQKDAhTb2Nr
3
+ ZXRyeTEbMBkGA1UEAwwSU29ja2V0cnkgUnVieSBHZW1zMB4XDTI2MDkyMTA3NTgx
4
+ NFoXDTI3MDkyMTA3NTgxNFowMDERMA8GA1UECgwIU29ja2V0cnkxGzAZBgNVBAMM
5
+ ElNvY2tldHJ5IFJ1YnkgR2VtczCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoC
6
+ ggGBAM/QgjVgDzDo/xJEQoFvAzcVFP7msnswkhPJB2UDsbxXCZmers5jV512TM5s
7
+ NwLHfzJiC4DcI5ax9ZYKM9Q+dS21YYagNqjtg3YPyDqR6phoibEA0VoMuInUQW68
8
+ i5OkCJzYKGD2pYYVZnuFNqyM2ECUvXh/fBmvPoHbncAHhWPaCBH8mQJ8sRNc6+RV
9
+ SoZZu1Yo/aW1zQ+SpZwad7s1ZmigfDNHKhJ22KwZHk+/5Zw1QXVfcajjswV0Mm2P
10
+ irgjKN3fyNVkwlly63EBlR4VydT+g9QtJtqh7ee0ThhI+v4wYovf4dbLNcEBTHu1
11
+ x1pGbXGx/2fBAST5eVwaXIx1V8VU22AJcBk1H2o5/1F0HfbD2HQjmFOA112KUwBW
12
+ 9TtspZD3g6rCQFX53XvL9h6j2y1ukl7s5AdEzOe/x6r1MO8tSDtgcYoF89wgF/88
13
+ Q/Eski0FckQ+znfESZcFcpzs2sPDoYW6SNVX4tZcNty85Y6WBHfHKio14x63PeyC
14
+ CG1gMwIDAQABozkwNzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQU
15
+ SuMc0x24Xshtaa8SQVkBr2Z5WzIwDQYJKoZIhvcNAQELBQADggGBABI62ey5lDWm
16
+ j8jsTQaNBMBb7LbKS3XkBwyL1UNGEwlicp399rJDeuNgVSHqBCZ/nE4yleNjgW9Y
17
+ N6DKdxXCvXmFUoHvUINeAvThHxmlEGhSfXl1x55xHEig0rEP4jgdjnYdQI4fqeOM
18
+ zIDN0F3ruArke4Y62SQgWVN7vspdAA41hBIRl1vsvs0KWG8DIVQ8cmR+TG6zjOmK
19
+ iUiUZGNPnStV1O1xW83c+Ba4Am0krP6/forxDPhRvTehqkVYvMdPfYcICNb5IM58
20
+ 5vaYvuj5AtfZuZWN0F/0KtSphhNC17rh6h8QmuYdMJ1clvlrkiEaO1UjPVwjgtxC
21
+ x/ARh5X6q0/YTXl4r7EfSJEeqW7qhgu9EUj3mGIPHYdX0Dqih/NgK20F3GvQtTfB
22
+ 7sse0duKBHXONYVwKAsceUVvqtCfyF608bCilCkbhw3QaInRj+BkRQKJ5Tuj2PZR
23
+ 76a/hwaV2wWn5RtAFBaUQzQdo/xTqJ7IkwaFjOZe/QyvyoRjCK9Rdg==
24
+ -----END CERTIFICATE-----
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: presently
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.27.0
4
+ version: 0.29.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
@@ -9,32 +9,28 @@ bindir: bin
9
9
  cert_chain:
10
10
  - |
11
11
  -----BEGIN CERTIFICATE-----
12
- MIIE2DCCA0CgAwIBAgIBATANBgkqhkiG9w0BAQsFADBhMRgwFgYDVQQDDA9zYW11
13
- ZWwud2lsbGlhbXMxHTAbBgoJkiaJk/IsZAEZFg1vcmlvbnRyYW5zZmVyMRIwEAYK
14
- CZImiZPyLGQBGRYCY28xEjAQBgoJkiaJk/IsZAEZFgJuejAeFw0yMjA4MDYwNDUz
15
- MjRaFw0zMjA4MDMwNDUzMjRaMGExGDAWBgNVBAMMD3NhbXVlbC53aWxsaWFtczEd
16
- MBsGCgmSJomT8ixkARkWDW9yaW9udHJhbnNmZXIxEjAQBgoJkiaJk/IsZAEZFgJj
17
- bzESMBAGCgmSJomT8ixkARkWAm56MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIB
18
- igKCAYEAomvSopQXQ24+9DBB6I6jxRI2auu3VVb4nOjmmHq7XWM4u3HL+pni63X2
19
- 9qZdoq9xt7H+RPbwL28LDpDNflYQXoOhoVhQ37Pjn9YDjl8/4/9xa9+NUpl9XDIW
20
- sGkaOY0eqsQm1pEWkHJr3zn/fxoKPZPfaJOglovdxf7dgsHz67Xgd/ka+Wo1YqoE
21
- e5AUKRwUuvaUaumAKgPH+4E4oiLXI4T1Ff5Q7xxv6yXvHuYtlMHhYfgNn8iiW8WN
22
- XibYXPNP7NtieSQqwR/xM6IRSoyXKuS+ZNGDPUUGk8RoiV/xvVN4LrVm9upSc0ss
23
- RZ6qwOQmXCo/lLcDUxJAgG95cPw//sI00tZan75VgsGzSWAOdjQpFM0l4dxvKwHn
24
- tUeT3ZsAgt0JnGqNm2Bkz81kG4A2hSyFZTFA8vZGhp+hz+8Q573tAR89y9YJBdYM
25
- zp0FM4zwMNEUwgfRzv1tEVVUEXmoFCyhzonUUw4nE4CFu/sE3ffhjKcXcY//qiSW
26
- xm4erY3XAgMBAAGjgZowgZcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0O
27
- BBYEFO9t7XWuFf2SKLmuijgqR4sGDlRsMC4GA1UdEQQnMCWBI3NhbXVlbC53aWxs
28
- aWFtc0BvcmlvbnRyYW5zZmVyLmNvLm56MC4GA1UdEgQnMCWBI3NhbXVlbC53aWxs
29
- aWFtc0BvcmlvbnRyYW5zZmVyLmNvLm56MA0GCSqGSIb3DQEBCwUAA4IBgQB5sxkE
30
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
38
34
  -----END CERTIFICATE-----
39
35
  date: 1980-01-02 00:00:00.000000000 Z
40
36
  dependencies:
@@ -265,6 +261,7 @@ files:
265
261
  - public/playback.js
266
262
  - public/recording_controls.js
267
263
  - readme.md
264
+ - release.cert
268
265
  - releases.md
269
266
  - templates/code.xrb
270
267
  - templates/default.xrb
@@ -295,7 +292,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
295
292
  - !ruby/object:Gem::Version
296
293
  version: '0'
297
294
  requirements: []
298
- rubygems_version: 4.0.16
295
+ rubygems_version: 4.0.21
299
296
  specification_version: 4
300
297
  summary: A web-based presentation tool built with Lively.
301
298
  test_files: []
metadata.gz.sig CHANGED
Binary file