wani 0.1.8
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 +7 -0
- data/LICENSE +21 -0
- data/README.md +262 -0
- data/assets/bootstrap.rb +9 -0
- data/assets/build.json +6 -0
- data/assets/fonts/IBMPlexSansJP-Bold.woff2 +0 -0
- data/assets/fonts/IBMPlexSansJP-Regular.woff2 +0 -0
- data/assets/highlight.css +117 -0
- data/assets/index.html +39 -0
- data/assets/rabbit.svg +1 -0
- data/assets/rouge.LICENSE +187 -0
- data/assets/runtime.LICENSE +21 -0
- data/assets/runtime.NOTICE +1292 -0
- data/assets/runtime.pr672.js +3143 -0
- data/assets/shark.svg +1 -0
- data/assets/speaker.html +2 -0
- data/assets/style.css +103 -0
- data/assets/time-expired.png +0 -0
- data/assets/wani.wasm +4 -0
- data/exe/wani +3 -0
- data/lib/wani/browser/application.rb +189 -0
- data/lib/wani/browser/bridge_progress.rb +19 -0
- data/lib/wani/browser/fonts.rb +60 -0
- data/lib/wani/browser/layout.rb +107 -0
- data/lib/wani/browser/presentation_timer.rb +66 -0
- data/lib/wani/browser/renderer.rb +80 -0
- data/lib/wani/cli.rb +134 -0
- data/lib/wani/core/fonts.rb +49 -0
- data/lib/wani/core/parser.rb +127 -0
- data/lib/wani/core/presentation.rb +15 -0
- data/lib/wani/core/safe_html.rb +74 -0
- data/lib/wani/core/validator.rb +31 -0
- data/lib/wani/fonts/http.rb +45 -0
- data/lib/wani/fonts/manager.rb +190 -0
- data/lib/wani/server/application.rb +92 -0
- data/lib/wani/server/http_server.rb +34 -0
- data/lib/wani/version.rb +3 -0
- data/lib/wani.rb +4 -0
- data/templates/images/workflow.svg +36 -0
- data/templates/slides.md +182 -0
- data/third_party/gems/kramdown-LICENSE +30 -0
- data/third_party/gems/kramdown-parser-gfm-LICENSE +21 -0
- data/third_party/gems/rexml-LICENSE +22 -0
- data/third_party/ibm-plex-sans-jp/LICENSE.txt +93 -0
- data/third_party/ibm-plex-sans-jp/README.md +39 -0
- data/third_party/ibm-plex-sans-jp/provenance.json +20 -0
- data/third_party/ruby-wasm-loader/LICENSE +21 -0
- data/third_party/ruby-wasm-loader/NOTICE +1292 -0
- data/third_party/ruby-wasm-loader/README.md +35 -0
- data/third_party/ruby-wasm-loader/browser.script.iife.js +3143 -0
- data/third_party/ruby-wasm-loader/provenance.json +10 -0
- metadata +159 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
require "uri"
|
|
2
|
+
require "json"
|
|
3
|
+
require_relative "../fonts/manager"
|
|
4
|
+
require_relative "../../wani"
|
|
5
|
+
|
|
6
|
+
module Wani
|
|
7
|
+
module Server
|
|
8
|
+
# Only the selected Markdown, images below its directory and fixed gem assets are public.
|
|
9
|
+
class Application
|
|
10
|
+
ASSETS = %w[index.html style.css highlight.css rouge.LICENSE bootstrap.rb speaker.html rabbit.svg shark.svg time-expired.png runtime.pr672.js wani.wasm runtime.LICENSE runtime.NOTICE build.json
|
|
11
|
+
fonts/IBMPlexSansJP-Regular.woff2 fonts/IBMPlexSansJP-Bold.woff2].freeze
|
|
12
|
+
TYPES = { ".html" => "text/html; charset=utf-8", ".css" => "text/css; charset=utf-8", ".rb" => "text/plain; charset=utf-8", ".js" => "text/javascript", ".wasm" => "application/wasm", ".md" => "text/plain; charset=utf-8", ".svg" => "image/svg+xml", ".png" => "image/png", ".jpg" => "image/jpeg", ".jpeg" => "image/jpeg", ".webp" => "image/webp", ".json" => "application/json", ".woff2" => "font/woff2" }.freeze
|
|
13
|
+
IMAGES = %w[.png .jpg .jpeg .webp .svg].freeze
|
|
14
|
+
|
|
15
|
+
def initialize(file, assets: File.join(Wani::ROOT, "assets"), diagnostics: nil)
|
|
16
|
+
@file = File.realpath(file)
|
|
17
|
+
raise ArgumentError, "Markdown is not a file: #{file}" unless File.file?(@file)
|
|
18
|
+
@root = File.dirname(@file)
|
|
19
|
+
@assets = File.realpath(assets)
|
|
20
|
+
@diagnostics = diagnostics
|
|
21
|
+
report_font(File.read(@file, encoding: "UTF-8")) if @diagnostics
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def call(raw_path)
|
|
25
|
+
path = decode(raw_path)
|
|
26
|
+
if path == "/talk/fonts.json"
|
|
27
|
+
return [200, { "Content-Type" => "application/json", "Cache-Control" => "no-store" }, JSON.generate(Fonts::Manager.new(@root).list)]
|
|
28
|
+
end
|
|
29
|
+
file = if path == "/"
|
|
30
|
+
File.join(@assets, "index.html")
|
|
31
|
+
elsif path == "/talk/slides.md"
|
|
32
|
+
@file
|
|
33
|
+
elsif path.start_with?("/assets/") && ASSETS.include?(path.delete_prefix("/assets/"))
|
|
34
|
+
contained(@assets, path.delete_prefix("/assets/"))
|
|
35
|
+
elsif path.start_with?("/talk/fonts/") && Fonts::Manager.new(@root).list.values.any? { |entry| entry.fetch("files").include?(path.delete_prefix("/talk/")) }
|
|
36
|
+
contained(@root, path.delete_prefix("/talk/"))
|
|
37
|
+
elsif path.start_with?("/talk/") && IMAGES.include?(File.extname(path).downcase)
|
|
38
|
+
contained(@root, path.delete_prefix("/talk/"))
|
|
39
|
+
else
|
|
40
|
+
return [404, {}, "Not found"]
|
|
41
|
+
end
|
|
42
|
+
return [404, {}, "Not found"] unless File.file?(file)
|
|
43
|
+
type = TYPES.fetch(File.extname(file).downcase, "text/plain; charset=utf-8")
|
|
44
|
+
headers = { "Content-Type" => type, "X-Content-Type-Options" => "nosniff", "Cache-Control" => "no-store" }
|
|
45
|
+
if type.start_with?("image/")
|
|
46
|
+
headers["Content-Security-Policy"] = "sandbox; default-src 'none'; style-src 'unsafe-inline'"
|
|
47
|
+
else
|
|
48
|
+
headers["Content-Security-Policy"] = "default-src 'self'; script-src 'self' 'unsafe-eval' 'wasm-unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' https: http:; connect-src 'self'; object-src 'none'; base-uri 'none'; frame-ancestors 'none'"
|
|
49
|
+
end
|
|
50
|
+
body = File.binread(file)
|
|
51
|
+
report_font(body.dup.force_encoding(Encoding::UTF_8)) if path == "/talk/slides.md" && @diagnostics
|
|
52
|
+
[200, headers, body]
|
|
53
|
+
rescue ArgumentError, EncodingError
|
|
54
|
+
[403, {}, "Forbidden"]
|
|
55
|
+
rescue Errno::ENOENT, Errno::ENOTDIR
|
|
56
|
+
[404, {}, "Not found"]
|
|
57
|
+
rescue Errno::EACCES
|
|
58
|
+
[403, {}, "Forbidden"]
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
private
|
|
62
|
+
|
|
63
|
+
def report_font(source)
|
|
64
|
+
message = begin
|
|
65
|
+
name = Core::Parser.new.parse(source).fonts["default"]
|
|
66
|
+
if name && !Core::Fonts.resolve(Fonts::Manager.new(@root).list, name)
|
|
67
|
+
"warning: Unregistered font: #{name}; using fallback"
|
|
68
|
+
end
|
|
69
|
+
rescue Core::Parser::Error, ArgumentError => error
|
|
70
|
+
"error: #{error.message}"
|
|
71
|
+
end
|
|
72
|
+
@diagnostics.call(message) if message && message != @last_diagnostic
|
|
73
|
+
@last_diagnostic = message
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def decode(raw)
|
|
77
|
+
raw = raw.split("?", 2).first
|
|
78
|
+
raise ArgumentError if raw.match?(/%(?![0-9a-fA-F]{2})/)
|
|
79
|
+
path = URI::RFC2396_PARSER.unescape(raw).force_encoding(Encoding::UTF_8)
|
|
80
|
+
raise ArgumentError unless path.valid_encoding? && path.start_with?("/")
|
|
81
|
+
raise ArgumentError if path.match?(/[\x00-\x1f\x7f\\%]/) || path.split("/").any? { |part| part == ".." || part == "." }
|
|
82
|
+
path
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def contained(root, relative)
|
|
86
|
+
resolved = File.realpath(File.join(root, relative))
|
|
87
|
+
raise ArgumentError unless resolved.start_with?(root + File::SEPARATOR)
|
|
88
|
+
resolved
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
require "webrick"
|
|
2
|
+
require_relative "application"
|
|
3
|
+
|
|
4
|
+
module Wani
|
|
5
|
+
module Server
|
|
6
|
+
class HTTPServer
|
|
7
|
+
def initialize(file, bind: "127.0.0.1", port: 8000, out: $stdout)
|
|
8
|
+
app = Application.new(file, diagnostics: ->(message) { out.puts(message); out.flush })
|
|
9
|
+
@server = WEBrick::HTTPServer.new(BindAddress: bind, Port: port,
|
|
10
|
+
Logger: WEBrick::Log.new($stderr, WEBrick::Log::WARN), AccessLog: [],
|
|
11
|
+
StartCallback: -> { out.puts "Wani: http://#{bind.include?(':') ? "[#{bind}]" : bind}:#{@server.listeners.first.addr[1]}/"; out.flush })
|
|
12
|
+
@server.mount_proc("/") do |request, response|
|
|
13
|
+
if %w[GET HEAD].include?(request.request_method)
|
|
14
|
+
status, headers, body = app.call(request.unparsed_uri)
|
|
15
|
+
response.status = status
|
|
16
|
+
headers.each { |key, value| response[key] = value }
|
|
17
|
+
response.body = body
|
|
18
|
+
else
|
|
19
|
+
response.status = 405
|
|
20
|
+
response["Allow"] = "GET, HEAD"
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def start
|
|
26
|
+
previous = %w[INT TERM].to_h { |signal| [signal, Signal.trap(signal) { @server.shutdown }] }
|
|
27
|
+
@server.start
|
|
28
|
+
ensure
|
|
29
|
+
previous&.each { |signal, handler| Signal.trap(signal, handler) }
|
|
30
|
+
@server.shutdown
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
data/lib/wani/version.rb
ADDED
data/lib/wani.rb
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="300" viewBox="0 0 1200 300" role="img" aria-labelledby="title desc">
|
|
2
|
+
<title id="title">Markdown から発表と PDF へ</title>
|
|
3
|
+
<desc id="desc">原稿を書く、ブラウザーで発表する、PDF を配布する、という3つの手順を矢印で結んだ図。</desc>
|
|
4
|
+
<defs>
|
|
5
|
+
<marker id="arrow" markerWidth="10" markerHeight="10" refX="8" refY="5" orient="auto">
|
|
6
|
+
<path d="M0 0 L10 5 L0 10 Z" fill="#527b65"/>
|
|
7
|
+
</marker>
|
|
8
|
+
</defs>
|
|
9
|
+
<rect width="1200" height="300" rx="24" fill="#f3f6f2"/>
|
|
10
|
+
<g fill="white" stroke="#91af99" stroke-width="3">
|
|
11
|
+
<rect x="35" y="50" width="310" height="200" rx="18"/>
|
|
12
|
+
<rect x="445" y="50" width="310" height="200" rx="18"/>
|
|
13
|
+
<rect x="855" y="50" width="310" height="200" rx="18"/>
|
|
14
|
+
</g>
|
|
15
|
+
<g stroke="#527b65" stroke-width="5" marker-end="url(#arrow)">
|
|
16
|
+
<path d="M365 150 H420"/>
|
|
17
|
+
<path d="M775 150 H830"/>
|
|
18
|
+
</g>
|
|
19
|
+
<g font-family="sans-serif" text-anchor="middle" fill="#20352e">
|
|
20
|
+
<g font-size="20" fill="#527b65">
|
|
21
|
+
<text x="190" y="95">01 / WRITE</text>
|
|
22
|
+
<text x="600" y="95">02 / PRESENT</text>
|
|
23
|
+
<text x="1010" y="95">03 / SHARE</text>
|
|
24
|
+
</g>
|
|
25
|
+
<g font-size="38" font-weight="bold">
|
|
26
|
+
<text x="190" y="158">Markdown</text>
|
|
27
|
+
<text x="600" y="158">Browser</text>
|
|
28
|
+
<text x="1010" y="158">PDF</text>
|
|
29
|
+
</g>
|
|
30
|
+
<g font-size="24" fill="#527b65">
|
|
31
|
+
<text x="190" y="205">slides.md</text>
|
|
32
|
+
<text x="600" y="205">wani serve</text>
|
|
33
|
+
<text x="1010" y="205">Slides + Notes</text>
|
|
34
|
+
</g>
|
|
35
|
+
</g>
|
|
36
|
+
</svg>
|
data/templates/slides.md
ADDED
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
---
|
|
2
|
+
time_limit: 5
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# はじめての Wani
|
|
6
|
+
|
|
7
|
+
Ruby と Markdown でプレゼンテーション。
|
|
8
|
+
|
|
9
|
+
- 左右キー・Space で移動
|
|
10
|
+
- F で全画面
|
|
11
|
+
- N で発表者ノート
|
|
12
|
+
|
|
13
|
+
<!-- page-footnote: Wani のサンプルへようこそ -->
|
|
14
|
+
|
|
15
|
+
<!-- notes:
|
|
16
|
+
最初に自己紹介をします。
|
|
17
|
+
ページを進めながら使える記法を紹介します。
|
|
18
|
+
原稿の先頭にある time_limit は発表時間(分)です。0 にするとタイマーを無効にできます。
|
|
19
|
+
-->
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
# 文章を強調する
|
|
24
|
+
|
|
25
|
+
**いちばん伝えたいこと**は太字にします。
|
|
26
|
+
|
|
27
|
+
*強調したい言葉*はアスタリスクで囲みます。
|
|
28
|
+
|
|
29
|
+
コマンドは `wani serve` のように文中に入れられます。
|
|
30
|
+
|
|
31
|
+
空行を入れると、新しい段落になります。
|
|
32
|
+
|
|
33
|
+
<!-- notes:
|
|
34
|
+
原稿では **太字**、*強調*、バッククォートで囲むコードを使っています。
|
|
35
|
+
タイトルはプレーンテキストになります。本文で表示の違いを見せます。
|
|
36
|
+
-->
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
# リストで整理する
|
|
41
|
+
|
|
42
|
+
- 原稿は Markdown で書く
|
|
43
|
+
- 画像は images フォルダーに置く
|
|
44
|
+
- ブラウザーで見た目を確認する
|
|
45
|
+
|
|
46
|
+
1. `wani check` で原稿を確認する
|
|
47
|
+
2. `wani serve` でサーバーを起動する
|
|
48
|
+
3. 表示された URL を開く
|
|
49
|
+
|
|
50
|
+
<!-- notes:
|
|
51
|
+
上は箇条書き、下は番号付きリストです。
|
|
52
|
+
原稿を編集したらブラウザーを再読み込みします。
|
|
53
|
+
-->
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
# 引用とリンク
|
|
58
|
+
|
|
59
|
+
> 一枚のスライドでは、一つのメッセージを伝えよう。
|
|
60
|
+
|
|
61
|
+
参考資料は [Ruby の公式サイト](https://www.ruby-lang.org/ja/) のようにリンクできます。
|
|
62
|
+
|
|
63
|
+
`[表示する文章](URL)` がリンクの書き方です。
|
|
64
|
+
|
|
65
|
+
<!-- page-footnote: リンクはクリックして開けます -->
|
|
66
|
+
|
|
67
|
+
<!-- notes:
|
|
68
|
+
引用は行頭に > を付けて書きます。
|
|
69
|
+
この引用文は書き方を紹介するためのサンプルです。
|
|
70
|
+
-->
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
# コードを見せる
|
|
75
|
+
|
|
76
|
+
```ruby
|
|
77
|
+
topics = ["Markdown", "Ruby", "WebAssembly"]
|
|
78
|
+
|
|
79
|
+
topics.each do |topic|
|
|
80
|
+
puts "Hello, #{topic}!"
|
|
81
|
+
end
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
複数行のコードはバッククォート3つで囲みます。
|
|
85
|
+
|
|
86
|
+
<!-- notes:
|
|
87
|
+
フェンスに ruby と言語名を書けますが、構文ハイライトは行いません。
|
|
88
|
+
コード内の記号や改行はそのまま表示します。
|
|
89
|
+
-->
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
# 表で比較する
|
|
94
|
+
|
|
95
|
+
| 書きたいもの | Markdown の記法 |
|
|
96
|
+
| --- | --- |
|
|
97
|
+
| ページのタイトル | `# タイトル` |
|
|
98
|
+
| 太字 | `**太字**` |
|
|
99
|
+
| 文中のコード | バッククォートで囲む |
|
|
100
|
+
| 次のページ | 空行を挟んだ `---` |
|
|
101
|
+
|
|
102
|
+
<!-- notes:
|
|
103
|
+
表の見出しの次に、ハイフンで区切りの行を書きます。
|
|
104
|
+
行数が多いときは、スライドを分けて読みやすくします。
|
|
105
|
+
-->
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
# 画像で伝える
|
|
110
|
+
|
|
111
|
+

|
|
112
|
+
|
|
113
|
+
`` で画像を表示します。
|
|
114
|
+
|
|
115
|
+
<!-- page-footnote: サンプル画像は images/workflow.svg にあります -->
|
|
116
|
+
|
|
117
|
+
<!-- notes:
|
|
118
|
+
この図は wani new で原稿と一緒にコピーされる SVG です。
|
|
119
|
+
PNG、JPEG、WebP も使えます。自分の画像を images フォルダーに置いて差し替えてください。
|
|
120
|
+
パスは slides.md の場所を基準に書きます。
|
|
121
|
+
-->
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
# 発表者ノートを書く
|
|
126
|
+
|
|
127
|
+
```markdown
|
|
128
|
+
<!-- notes:
|
|
129
|
+
**デモの前に**、操作の流れを説明します。
|
|
130
|
+
-->
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
N キーで、このページの実際のノートを確認できます。
|
|
134
|
+
ノートは発表者画面とノート付き PDF に表示します。
|
|
135
|
+
|
|
136
|
+
<!-- notes:
|
|
137
|
+
**デモの前に**、操作の流れを説明します。
|
|
138
|
+
これは発表者向けの補足です。通常のスライド本文には表示されません。
|
|
139
|
+
-->
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
# ページに脚注を付ける
|
|
144
|
+
|
|
145
|
+
```markdown
|
|
146
|
+
<!-- page-footnote: 出典:Wani サンプル資料 -->
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
このページの下部に、実際の脚注を表示しています。
|
|
150
|
+
出典や補足を、そのページだけに付けられます。
|
|
151
|
+
|
|
152
|
+
<!-- page-footnote: 出典:Wani サンプル資料 -->
|
|
153
|
+
|
|
154
|
+
<!-- notes:
|
|
155
|
+
コード欄は書き方の見本で、下部の脚注は実際のコメントから表示しています。
|
|
156
|
+
脚注はプレーンテキストです。PDF にも表示されます。
|
|
157
|
+
-->
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
# 発表と配布へ
|
|
162
|
+
|
|
163
|
+
- N キーで、このページの発表者ノートを開く
|
|
164
|
+
- 「PDF」でスライドを保存する
|
|
165
|
+
- 「ノート付き PDF」で説明も一緒に配布する
|
|
166
|
+
|
|
167
|
+
原稿を自分のテーマに書き換えて、発表を始めましょう。
|
|
168
|
+
|
|
169
|
+
<!-- page-footnote: ご清聴ありがとうございました -->
|
|
170
|
+
|
|
171
|
+
<!-- notes:
|
|
172
|
+
ノートは通常のスライド本文には表示されません。
|
|
173
|
+
発表者画面とノート付き PDF に表示します。
|
|
174
|
+
|
|
175
|
+
**最後に確認すること**
|
|
176
|
+
|
|
177
|
+
- 質問を受け付ける
|
|
178
|
+
- 参考資料の場所を伝える
|
|
179
|
+
|
|
180
|
+
ページごとの脚注は page-footnote コメントで指定します。
|
|
181
|
+
PDF には脚注とページ番号が残り、兎と鰐の装飾は表示されません。
|
|
182
|
+
-->
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
kramdown - fast, pure-Ruby Markdown-superset converter
|
|
2
|
+
Copyright (C) 2009-2013 Thomas Leitner <t_leitner@gmx.at>
|
|
3
|
+
|
|
4
|
+
Permission is hereby granted, free of charge, to any person obtaining a
|
|
5
|
+
copy of this software and associated documentation files (the
|
|
6
|
+
"Software"), to deal in the Software without restriction, including
|
|
7
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
8
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
9
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
10
|
+
the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included
|
|
13
|
+
in all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
16
|
+
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
17
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
18
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
19
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
20
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
21
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
Some test cases and the benchmark files are based on test cases from
|
|
25
|
+
the MDTest test suite:
|
|
26
|
+
|
|
27
|
+
MDTest
|
|
28
|
+
Copyright (c) 2007 Michel Fortin
|
|
29
|
+
<http://www.michelf.com/>
|
|
30
|
+
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
kramdown-parser-gfm
|
|
2
|
+
Copyright (C) 2019 Thomas Leitner <t_leitner@gmx.at>
|
|
3
|
+
|
|
4
|
+
Permission is hereby granted, free of charge, to any person obtaining a
|
|
5
|
+
copy of this software and associated documentation files (the
|
|
6
|
+
"Software"), to deal in the Software without restriction, including
|
|
7
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
8
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
9
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
10
|
+
the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included
|
|
13
|
+
in all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
16
|
+
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
17
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
18
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
19
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
20
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
21
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
Copyright (C) 1993-2013 Yukihiro Matsumoto. All rights reserved.
|
|
2
|
+
|
|
3
|
+
Redistribution and use in source and binary forms, with or without
|
|
4
|
+
modification, are permitted provided that the following conditions
|
|
5
|
+
are met:
|
|
6
|
+
1. Redistributions of source code must retain the above copyright
|
|
7
|
+
notice, this list of conditions and the following disclaimer.
|
|
8
|
+
2. Redistributions in binary form must reproduce the above copyright
|
|
9
|
+
notice, this list of conditions and the following disclaimer in the
|
|
10
|
+
documentation and/or other materials provided with the distribution.
|
|
11
|
+
|
|
12
|
+
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
13
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
14
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
15
|
+
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
16
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
17
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
18
|
+
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
19
|
+
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
20
|
+
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
21
|
+
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
22
|
+
SUCH DAMAGE.
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
Copyright © 2017 IBM Corp. with Reserved Font Name "Plex"
|
|
2
|
+
|
|
3
|
+
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
|
4
|
+
|
|
5
|
+
This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
-----------------------------------------------------------
|
|
9
|
+
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
|
10
|
+
-----------------------------------------------------------
|
|
11
|
+
|
|
12
|
+
PREAMBLE
|
|
13
|
+
The goals of the Open Font License (OFL) are to stimulate worldwide
|
|
14
|
+
development of collaborative font projects, to support the font creation
|
|
15
|
+
efforts of academic and linguistic communities, and to provide a free and
|
|
16
|
+
open framework in which fonts may be shared and improved in partnership
|
|
17
|
+
with others.
|
|
18
|
+
|
|
19
|
+
The OFL allows the licensed fonts to be used, studied, modified and
|
|
20
|
+
redistributed freely as long as they are not sold by themselves. The
|
|
21
|
+
fonts, including any derivative works, can be bundled, embedded,
|
|
22
|
+
redistributed and/or sold with any software provided that any reserved
|
|
23
|
+
names are not used by derivative works. The fonts and derivatives,
|
|
24
|
+
however, cannot be released under any other type of license. The
|
|
25
|
+
requirement for fonts to remain under this license does not apply
|
|
26
|
+
to any document created using the fonts or their derivatives.
|
|
27
|
+
|
|
28
|
+
DEFINITIONS
|
|
29
|
+
"Font Software" refers to the set of files released by the Copyright
|
|
30
|
+
Holder(s) under this license and clearly marked as such. This may
|
|
31
|
+
include source files, build scripts and documentation.
|
|
32
|
+
|
|
33
|
+
"Reserved Font Name" refers to any names specified as such after the
|
|
34
|
+
copyright statement(s).
|
|
35
|
+
|
|
36
|
+
"Original Version" refers to the collection of Font Software components as
|
|
37
|
+
distributed by the Copyright Holder(s).
|
|
38
|
+
|
|
39
|
+
"Modified Version" refers to any derivative made by adding to, deleting,
|
|
40
|
+
or substituting -- in part or in whole -- any of the components of the
|
|
41
|
+
Original Version, by changing formats or by porting the Font Software to a
|
|
42
|
+
new environment.
|
|
43
|
+
|
|
44
|
+
"Author" refers to any designer, engineer, programmer, technical
|
|
45
|
+
writer or other person who contributed to the Font Software.
|
|
46
|
+
|
|
47
|
+
PERMISSION & CONDITIONS
|
|
48
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
49
|
+
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
|
50
|
+
redistribute, and sell modified and unmodified copies of the Font
|
|
51
|
+
Software, subject to the following conditions:
|
|
52
|
+
|
|
53
|
+
1) Neither the Font Software nor any of its individual components,
|
|
54
|
+
in Original or Modified Versions, may be sold by itself.
|
|
55
|
+
|
|
56
|
+
2) Original or Modified Versions of the Font Software may be bundled,
|
|
57
|
+
redistributed and/or sold with any software, provided that each copy
|
|
58
|
+
contains the above copyright notice and this license. These can be
|
|
59
|
+
included either as stand-alone text files, human-readable headers or
|
|
60
|
+
in the appropriate machine-readable metadata fields within text or
|
|
61
|
+
binary files as long as those fields can be easily viewed by the user.
|
|
62
|
+
|
|
63
|
+
3) No Modified Version of the Font Software may use the Reserved Font
|
|
64
|
+
Name(s) unless explicit written permission is granted by the corresponding
|
|
65
|
+
Copyright Holder. This restriction only applies to the primary font name as
|
|
66
|
+
presented to the users.
|
|
67
|
+
|
|
68
|
+
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
|
69
|
+
Software shall not be used to promote, endorse or advertise any
|
|
70
|
+
Modified Version, except to acknowledge the contribution(s) of the
|
|
71
|
+
Copyright Holder(s) and the Author(s) or with their explicit written
|
|
72
|
+
permission.
|
|
73
|
+
|
|
74
|
+
5) The Font Software, modified or unmodified, in part or in whole,
|
|
75
|
+
must be distributed entirely under this license, and must not be
|
|
76
|
+
distributed under any other license. The requirement for fonts to
|
|
77
|
+
remain under this license does not apply to any document created
|
|
78
|
+
using the Font Software.
|
|
79
|
+
|
|
80
|
+
TERMINATION
|
|
81
|
+
This license becomes null and void if any of the above conditions are
|
|
82
|
+
not met.
|
|
83
|
+
|
|
84
|
+
DISCLAIMER
|
|
85
|
+
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
86
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
|
87
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
|
88
|
+
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
|
89
|
+
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
90
|
+
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
|
91
|
+
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
92
|
+
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
|
93
|
+
OTHER DEALINGS IN THE FONT SOFTWARE.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# IBM Plex Sans JP
|
|
2
|
+
|
|
3
|
+
IBM の公式 npm パッケージ [`@ibm/plex-sans-jp@3.0.0`](https://www.npmjs.com/package/@ibm/plex-sans-jp/v/3.0.0)
|
|
4
|
+
から、以下の完成版 WOFF2 を変更せずに同梱する。
|
|
5
|
+
|
|
6
|
+
- `assets/fonts/IBMPlexSansJP-Regular.woff2`(400 / 2,282,284 bytes)
|
|
7
|
+
- `assets/fonts/IBMPlexSansJP-Bold.woff2`(700 / 2,352,756 bytes)
|
|
8
|
+
|
|
9
|
+
元ファイルは `fonts/complete/woff2/hinted/` にある。サブセット化・改名・フォントデータの加工はしていない。
|
|
10
|
+
出所・バージョン・配布アーカイブと各ファイルの SHA-256 は `provenance.json` に記録する。
|
|
11
|
+
|
|
12
|
+
Copyright © 2017 IBM Corp. with Reserved Font Name "Plex"。
|
|
13
|
+
SIL Open Font License 1.1 により配布され、著作権表示とライセンス全文を `LICENSE.txt` に保持する。
|
|
14
|
+
アプリの MIT ライセンスとは区別する。
|
|
15
|
+
|
|
16
|
+
## 取得の再現
|
|
17
|
+
|
|
18
|
+
```sh
|
|
19
|
+
npm pack @ibm/plex-sans-jp@3.0.0 --pack-destination /tmp
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
`provenance.json` のアーカイブ SHA-256 と照合して展開し、上記2ファイルとパッケージの `LICENSE.txt` を取り出す。
|
|
23
|
+
Wani の通常利用・ビルド時にフォントのダウンロードや OS インストールは不要。
|
|
24
|
+
参照元: [IBM 公式リポジトリ](https://github.com/IBM/plex/tree/master/packages/plex-sans-jp)。
|
|
25
|
+
|
|
26
|
+
## PDF の文字抽出
|
|
27
|
+
|
|
28
|
+
検証した Chromium の PDF では、同じグリフに対応する文字が互換部首として抽出される場合がある
|
|
29
|
+
(例: `日` → `⽇`)。表示の字形とフォント埋め込みは確認し、内容比較のテストでは NFKC 正規化する。
|
|
30
|
+
PDF のテキストコピーが常に元のコードポイントと一致することまでは保証しない。
|
|
31
|
+
|
|
32
|
+
## 動作検証 (2026-10-26)
|
|
33
|
+
|
|
34
|
+
Linux / Ruby 4.0.7 / Node.js 24.22.1 / Chrome 156.0.8078.47。
|
|
35
|
+
Ruby は12件・85アサーション、ブラウザーは13件成功(35.8秒)。
|
|
36
|
+
Chrome の実フォント情報で日本語の Regular / Bold と Web フォント使用を確認し、
|
|
37
|
+
日本語 PDF の文字内容・Regular / Bold と FontFile2 の埋め込みを検査した。
|
|
38
|
+
太字の取得先を壊すと実描画テストは失敗し、復元後はフォント検証3件が成功(9.2秒)。
|
|
39
|
+
隔離環境の gem インストールでも2フォントのハッシュ一致、ライセンス同梱、HTTP配信を確認した。
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"package": "@ibm/plex-sans-jp",
|
|
3
|
+
"version": "3.0.0",
|
|
4
|
+
"repository": "https://github.com/IBM/plex/tree/master/packages/plex-sans-jp",
|
|
5
|
+
"tarball": "https://registry.npmjs.org/@ibm/plex-sans-jp/-/plex-sans-jp-3.0.0.tgz",
|
|
6
|
+
"tarball_sha256": "051484321fcffecc69c3d608b739c5fe0f558b0fd1de7958d96ca360d161de7f",
|
|
7
|
+
"license": "OFL-1.1",
|
|
8
|
+
"files": {
|
|
9
|
+
"IBMPlexSansJP-Bold.woff2": {
|
|
10
|
+
"sha256": "38336fbb169ae1b7b6ca2539332e1d59c9be222227659d23f8eb70ecda60337d",
|
|
11
|
+
"bytes": 2352756,
|
|
12
|
+
"source_path": "fonts/complete/woff2/hinted/IBMPlexSansJP-Bold.woff2"
|
|
13
|
+
},
|
|
14
|
+
"IBMPlexSansJP-Regular.woff2": {
|
|
15
|
+
"sha256": "ec27e9b75cd90a6f7abe96ede49d00b151eb5b1c2c886bfe9b4fc845f40be1ff",
|
|
16
|
+
"bytes": 2282284,
|
|
17
|
+
"source_path": "fonts/complete/woff2/hinted/IBMPlexSansJP-Regular.woff2"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2022 Yuta Saito
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|