mp 0.1.1 → 0.1.2

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: 34fc0a2942d59611b53629311f2696063e7c780f5d5a23f295961806f13898da
4
- data.tar.gz: bbf907d4146120f4438f9e260a402dc7fca7fd7a8e3e366ef987cd6655fea2d0
3
+ metadata.gz: 5129f3b2c3b3d69f8dfd2ccbf055ff7beeb95befb40fc92bbaede6f0e6aa90ed
4
+ data.tar.gz: bf6f1b7fc5b27dbf4c3358d71c5e7f78b9fd8dfb5356c42afe50746034b80227
5
5
  SHA512:
6
- metadata.gz: 999b1907304af0e73c5520565a1e4cc20d68beb94f54ca4509589b9978c1e6ad75839ed5b21100bbee4ffbb8504fdd7137550bfce94ba3779472518004bae851
7
- data.tar.gz: 9b86c3d9a52300db5b225fde23b43e94e4d5e108b02c07c6ca3ecf3bc0e83fc885e1527331fb936fb135a2425b0511e68ef9c0667429cbe9355a8a215fe408f3
6
+ metadata.gz: 68d1748098ff537a0a9a0c868831f625c525b5a19b7bd1cef064716c25a12912fe3538c866281ac72fe0e006945e95a0bcdbaac11c67c3c04fc03c26492a0459
7
+ data.tar.gz: a54861155242c7e478cca020fabe42047cdef83087067b48b2af71e2599f38212894dd5ad42ab3aa27c341ce72bddffab399e25ca3feb0295664467b59ca70bd
data/README.md CHANGED
@@ -68,7 +68,22 @@ https://example.com
68
68
 
69
69
  クリックするとページを操作でき、マウスが外に出るとスライドのキー操作に戻ります。
70
70
 
71
- ターミナルとページを横に並べるには `<!-- _class: columns -->` を使います。
71
+ 画面を左右に分けるには `<!-- _class: columns -->` を使います。本文の最後の要素が右の列に、それ以外が左の列に入ります。
72
+
73
+ ````markdown
74
+ ## タイトル
75
+
76
+ <!-- _class: columns -->
77
+
78
+ 説明の文章
79
+
80
+ - 箇条書き
81
+
82
+ ```terminal
83
+ ```
84
+ ````
85
+
86
+ ターミナルと Web を 1 つずつ書けば左右に並びます。上下に分けるには `height=50%` を指定します。
72
87
 
73
88
  ## Marp 互換の記法
74
89
 
@@ -90,12 +105,13 @@ style: |
90
105
  <!-- _backgroundColor: black --> このスライドだけに適用(先頭に _)
91
106
  ```
92
107
 
93
- 使えるディレクティブは `paginate` `header` `footer` `class` `color` `backgroundColor` `backgroundImage` `backgroundPosition` `backgroundRepeat` `backgroundSize` です。クラスには `lead`(中央寄せ)、`left`(左寄せ)、`invert`(配色反転)、`columns`(2 列)があります。
108
+ 使えるディレクティブは `paginate` `header` `footer` `class` `color` `backgroundColor` `backgroundImage` `backgroundPosition` `backgroundRepeat` `backgroundSize` です。クラスには `lead`(中央寄せ)、`left`(左寄せ)、`right`(本文だけ右寄せ)、`invert`(配色反転)、`columns`(2 列)があります。
94
109
 
95
110
  **画像**
96
111
 
97
112
  ```markdown
98
113
  ![w:300 h:200](a.png) サイズ指定
114
+ ![fit](a.png) 本文の残りの領域に画像全体を収める
99
115
  ![blur:5px grayscale](a.png) フィルタ
100
116
  ![bg](a.png) 背景(複数並べると分割)
101
117
  ![bg contain](a.png) cover / contain / fit / auto / 50%
data/lib/mp/deck.rb CHANGED
@@ -188,8 +188,11 @@ module Mp
188
188
  id = "e#{@embeds.length + 1}"
189
189
  style = %w[width height].filter_map { |key|
190
190
  value = attrs[key]
191
- "#{key}:#{value}#{"px" if value.match?(/\A[\d.]+\z/)};flex:none" if value&.match?(CSS_LENGTH)
192
- }.join(";")
191
+ "#{key}:#{value}#{"px" if value.match?(/\A[\d.]+\z/)}" if value&.match?(CSS_LENGTH)
192
+ }
193
+ # 高さを固定するときだけ伸縮を止める。幅だけなら高さは残りの領域を使う
194
+ style << "flex:none" if style.any? { _1.start_with?("height") }
195
+ style = style.join(";")
193
196
  @embeds[id] = type == "web" ? web_embed(attrs, inner) : terminal_embed(attrs, inner)
194
197
  token(%(<div class="embed embed-#{type}" data-embed="#{id}" style="#{CGI.escapeHTML(style)}"></div>))
195
198
  end
@@ -44,6 +44,7 @@ module Mp
44
44
  @source_lines = source.split("\n", -1)
45
45
  transform(document.root)
46
46
  @title_only = title_only?(document.root)
47
+ arrange_columns(document.root) if directive_classes.include?("columns")
47
48
  html = scope_styles(restore_tokens(document.to_html))
48
49
  html = html.sub(/<h([12])>/, '<h\1 class="fit">') if @chunk.fit
49
50
 
@@ -57,17 +58,33 @@ module Mp
57
58
  element.children.each { transform(_1) }
58
59
  element.children.reject! { |child| background_only?(child) }
59
60
  mark_fragments(element) if element.type == :ul
60
- element.children.each { convert_image(_1) if _1.type == :img }
61
+ element.children.each { convert_image(_1, element) if _1.type == :img }
61
62
  end
62
63
 
63
64
  # 背景画像はここまでに取り除かれ、ノートは kramdown に渡していない
64
65
  def title_only?(root)
65
66
  return false if @chunk.kind == :continuation
66
67
 
67
- content = root.children.reject { _1.type == :blank || (_1.type == :html_element && _1.value == "style") }
68
+ content = root.children.reject { _1.type == :blank || style_element?(_1) }
68
69
  content.length == 1 && content.first.type == :header
69
70
  end
70
71
 
72
+ def style_element?(element)
73
+ element.type == :html_element && element.value == "style"
74
+ end
75
+
76
+ # 最後の要素を右の列、それ以外を左の列に積む
77
+ def arrange_columns(root)
78
+ children = root.children.reject { _1.type == :blank }
79
+ heading = children.first&.type == :header && children.first.options[:level] <= 2 ? [children.shift] : []
80
+ styles, blocks = children.partition { style_element?(_1) }
81
+ columns = blocks.length > 1 ? [blocks[0...-1], blocks.last(1)] : [blocks]
82
+ wrapped = columns.flat_map { |column| [column_tag(%(<div class="column">)), *column, column_tag("</div>")] }
83
+ root.children.replace(heading + styles + wrapped)
84
+ end
85
+
86
+ def column_tag(html) = Kramdown::Element.new(:raw, html, nil, category: :block)
87
+
71
88
  def background_only?(element)
72
89
  return false unless element.type == :p
73
90
 
@@ -106,7 +123,7 @@ module Mp
106
123
  end
107
124
  end
108
125
 
109
- def convert_image(image)
126
+ def convert_image(image, parent)
110
127
  return if keywords(image).include?("bg") # 親の段落を処理するときに背景へ移す
111
128
 
112
129
  styles = []
@@ -115,6 +132,7 @@ module Mp
115
132
  case name
116
133
  when "w", "width" then styles << "width:#{css_length(value)}"
117
134
  when "h", "height" then styles << "height:#{css_length(value)}"
135
+ when "fit" then parent.attr["class"] = "image-fit" # 段落ごと本文の残りの領域を使う
118
136
  when *FILTERS then (@image_filters ||= []) << "#{name}(#{value || FILTER_DEFAULTS[name]})"
119
137
  else next false
120
138
  end
@@ -145,7 +163,11 @@ module Mp
145
163
  def classes
146
164
  kind = { cover: "cover", continuation: "continuation" }[@chunk.kind]
147
165
  title_only = "title-only" if @title_only
148
- ["slide", kind, *Array(@directives["class"]).flat_map { _1.to_s.split }, title_only].compact.join(" ")
166
+ ["slide", kind, *directive_classes, title_only].compact.join(" ")
167
+ end
168
+
169
+ def directive_classes
170
+ Array(@directives["class"]).flat_map { _1.to_s.split }
149
171
  end
150
172
 
151
173
  def style
data/lib/mp/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Mp
4
- VERSION = "0.1.1"
4
+ VERSION = "0.1.2"
5
5
  end
data/public/style.css CHANGED
@@ -27,6 +27,14 @@ section.slide.title-only > :is(h1, h2) { margin: 0; padding: 0; border: 0; }
27
27
  /* 左寄せ: <!-- _class: left --> */
28
28
  section.slide.left { align-items: stretch; text-align: left; }
29
29
 
30
+ /* 本文の右寄せ: <!-- _class: right -->。見出し、コード、埋め込みは動かさない */
31
+ :is(section.slide.right, section.slide.right > .column) > :not(h1, h2, .bg-layer, header, footer, .page-number, style, pre, .embed, .highlighter-rouge, .column) {
32
+ align-self: stretch;
33
+ text-align: right;
34
+ }
35
+ :is(section.slide.right, section.slide.right > .column) > :is(ul, ol) { padding-left: 0; list-style-position: inside; }
36
+ :is(section.slide.right, section.slide.right > .column) > blockquote { padding: 0 .7em 0 0; border-left: 0; border-right: 6px solid var(--accent, currentColor); }
37
+
30
38
  /* 中央寄せでも横幅いっぱいを基準に拡大する */
31
39
  section.slide > .fit { align-self: stretch; }
32
40
 
@@ -38,6 +46,22 @@ section.slide.columns {
38
46
  gap: 0 24px;
39
47
  }
40
48
  section.slide.columns > h2 { grid-column: 1 / -1; }
49
+ section.slide.columns > .column { grid-row: 2; display: flex; flex-direction: column; min-width: 0; min-height: 0; }
50
+
51
+ /* ![fit](a.png): 本文の残りの領域に画像全体を収める */
52
+ :is(section.slide, .column) > p.image-fit {
53
+ display: flex;
54
+ flex: 1;
55
+ align-self: stretch;
56
+ justify-content: center;
57
+ gap: 16px;
58
+ min-width: 0;
59
+ min-height: 0;
60
+ margin: 0;
61
+ }
62
+ :is(section.slide, .column) > p.image-fit > img { flex: 1; min-width: 0; width: 100%; height: 100%; object-fit: contain; }
63
+ :is(section.slide, .column) > p.image-fit > br { display: none; }
64
+ :is(section.slide, .column) > p.image-fit:has(+ :not(footer, .page-number)) { margin-bottom: .4em; }
41
65
 
42
66
  .fragment { visibility: hidden; }
43
67
  .fragment.shown { visibility: inherit; }
@@ -62,6 +86,7 @@ section.slide > .page-number { bottom: 20px; left: auto; right: 32px; }
62
86
  .embed {
63
87
  position: relative;
64
88
  flex: 1;
89
+ align-self: stretch;
65
90
  min-height: 0;
66
91
  min-width: 0;
67
92
  margin: 12px 0 24px;
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - takkanm
@@ -224,7 +224,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
224
224
  - !ruby/object:Gem::Version
225
225
  version: '0'
226
226
  requirements: []
227
- rubygems_version: 4.0.24
227
+ rubygems_version: 4.0.20
228
228
  specification_version: 4
229
229
  summary: Markdown を全画面プレゼンテーションにするツール(ターミナル / Web 埋め込み対応)
230
230
  test_files: []