Interface¶ ↑
: author
Kouhei Sutou
: institution
ClearCode Inc.
: content-source
RubyKaigi 2018
: date
2018-06-01
: start-time
2018-06-01T09:40:00+09:00
: end-time
2018-06-01T10:40:00+09:00
: theme
.
Ad: Silver sponsor¶ ↑
# img # src = images/clear-code-rubykaigi-2018-silver-sponsor.png # relative_height = 100 # reflect_ratio = 0.1
Slide properties¶ ↑
: enable-title-on-image
false
Interface?¶ ↑
A | B ^ Here
API¶ ↑
Library | Program ^ API
Web API¶ ↑
Server | HTTP | Client ^^^^^^^^ Web API
CLI¶ ↑
Program | command | User ^^^^^^^^^^^ Command Line Interface
My activitiesnas a Rubyist¶ ↑
* Expand "Ruby ready" areas * Maintain libraries
The number of developing libraries¶ ↑
About 130
Ruby anywhere¶ ↑
There are many interfaces
This talk's content¶ ↑
* Show my knowledge\n from my activities\n (('note:自分の活動で得られた知見を紹介')) * Perspective:"Interface"\n (('note:切り口:「インターフェイス」'))
RSS Parser¶ ↑
Makes Rubyn ((*Web feed*))n ready
RSS Parser - History¶ ↑
* 2003-05: The first release * 2004-01: Ruby bundles this * Became a Ruby committer
RSS Parser - Interface¶ ↑
RSS Parser | Programmers ^ API
RSS Parser - API¶ ↑
* Map RSS structure to * classes and * methods
Map to classes¶ ↑
<rss> RSS::Rss <channel> RSS::Rss::Channel <title>...</title> String <item> RSS::Rss::Channel::Item <title>...</title> String <item> <item> RSS::Rss::Channel::Item <title>...</title> String <item> </channel> </rss>
Map to methods¶ ↑
<rss> rss <channel> rss.channel <title>...</title> rss.channel.title <item> rss.channel.items[0] <title>...</title> rss.channel.items[0].title <item> <item> rss.channel.items[1] <title>...</title> rss.channel.items[1].title <item> </channel> </rss>
Pros¶ ↑
Users can guess API from their data
Example¶ ↑
<rss> # Want /rss/channel/item/title! <channel> rss.channel.items.each do |item| <title>...</title> <item> HERE: <title>...</title> p item.title <item> <item> HERE: <title>...</title> <item> </channel> end </rss>
Cons¶ ↑
Verbosen for expert
Cons - Interface¶ ↑
RSS Parser | Not experts Good RSS Parser | Experts Verbose
Example¶ ↑
<rss> # Want item/title! <channel> # Don't want to care <title>...</title> # about channel. <item> rss.items.each do |item| HERE: <title>...</title> p item.title <item> <item> HERE: <title>...</title> <item> end </channel> </rss>
Cons¶ ↑
Not generic
Web feed types¶ ↑
* RSS 0.9*/2.0 * Really Simple Syndication * RSS 1.0 * RDF Site Summary * Atom * RFC 4287
Differences¶ ↑
They are ((NOT)) compatible
Differences - Interface¶ ↑
RSS Parser | RSS 0.9*/2.0 RSS Parser | RSS 1.0 RSS Parser | Atom ^ Different structures
What users want¶ ↑
Processn all feed typesn in the same way
+ High level API¶ ↑
# coderay ruby # RSS 0.9*/20 rss.items # /rss/channel/item # RSS 1.0 rdf.items # /RDF/item # Atom feed.items # /feed/entry
+ High level API¶ ↑
Users | RSS Parser | RSS 0.9*/2.0 Users | RSS Parser | RSS 1.0 Users | RSS Parser | Atom ^ ^ Common API Different structures
RSS Parser - Design¶ ↑
* Premise:(('note:前提:')) * Users can confirm their data\n (('note:ユーザーは自分たちのデータを確認できる')) * Easy to use:(('note:使いやすくするために:')) * Map data structure to Ruby\n (('note:データの構造をそのままRubyの世界に対応させる')) * + common feed type aware API\n (('note:さらにフィードの種類に依存しない共通APIも用意'))
Knowledge - RSS Parser¶ ↑
* Premise is important for API\n (('note:API設計に前提は大事')) * Different API layer for\n different type users\n (('note:違う種類のユーザーには違うAPIのレイヤーを'))
RSS Parser - Omit¶ ↑
Validationn isn important
Rabbit¶ ↑
Makes Rubyn ((presentation))n ready
Rabbit - History¶ ↑
* 2004-07: The first release * 2010: Matz starts using Rabbit * Since RubyKaigi 2010?
Rabbit - Pitch¶ ↑
(('tag:center')) (('tag:large')) A presentation tooln for ((Rubyist))
((' '))
Rabbit - Run¶ ↑
# coderay console % rake
Run - Interface¶ ↑
Rabbit | rake | Rubyist ^^^^^^^^ CLI for Rubyist
Rabbit - Publish¶ ↑
# coderay console % rake publish:rubygems
publish:rubygems¶ ↑
# coderay console % rake gem Generates pkg/XXX.gem % gem push pkg/XXX.gem
Rabbit Slide Show¶ ↑
# img # src = images/rabbit-slide-show.png # relative_height = 78
(('tag:center')) (('tag:small')) ((<URL:slide.rabbit-shocker.org/>))
Slide properties¶ ↑
: enable-title-on-image
false
Publish - Interface¶ ↑
Rabbit | gem push | Rubyist ^^^^^^^^^^^^ Like a normal library No Web browser Your slides are versioned
Slide as a Gem¶ ↑
# coderay console % rake gem % gem unpack pkg/*.gem % tree rabbit-slide*
PDF in gem¶ ↑
# coderay console % tree rabbit-slide* ├── README.rd ... ├── pdf │ └── rubykaigi-2018-interface.pdf ...
Publish PDF in gem¶ ↑
(1) Receive published notifications from rubygems.org (2) Render PDF in gems for Web browser
(('tag:center')) (('tag:xx-small')) ((<URL:github.com/rabbit-shocker/slide.rabbit-shocker.org>))
Receive notifications¶ ↑
# coderay console % curl \ -H 'Authorization:...' \ -F 'gem_name=*' \ -F 'url=https://slide.rabbit-shocker.org/web-hook-receiver/' \ https://rubygems.org/api/v1/web_hooks
(('tag:center')) (('tag:xx-small')) ((<URL:guides.rubygems.org/rubygems-org-api/#webhook-methods>))
Notification - Interface¶ ↑
slide.rabbit-shocker.org | RubyGems.org ^ Web hook
Render PDF¶ ↑
Combine the following gems
* poppler - PDF parser * cairo - 2D graphics library
poppler & cairo¶ ↑
Makes Rubyn ((PDF))n ready
poppler - History¶ ↑
* 2006-07: The first release * 2018-05: The latest release
poppler - Parse¶ ↑
# coderay ruby pdf = Poppler::Document.new(content) pdf.each do |page| # Convert each page to PNG end
poppler - Interface¶ ↑
poppler | path | PDF poppler |content| PDF ^^^^^^^^^ Input
cairo - History¶ ↑
* 2003-10: The initial commit * 2005-09: I started developing * Sent several patches and\n got commit bit and more * 2005-10: The first release * 2018-05: The latest release
cairo - Outputs¶ ↑
((PNG)), PDF, SVG, X, Quarts, Win32, …
(('tag:xx-small')) See also: More about cairo gem in Japanesen ((<URL:magazine.rubyist.net/articles/0019/0019-cairo.html>))
cairo - To PNG¶ ↑
# coderay ruby iw, ih = image_width, image_height Cairo::ImageSurface.new(iw, ih) do |surface| Cairo::Context.new(surface) do |context| width, height = page.size x_scale = iw / width.to_f y_scale = ih / height.to_f context.scale(x_scale, y_scale) context.render_poppler_page(page) # Render surface.write_to_png("XXX.png") # Save end end
cairo - Interface¶ ↑
cairo |Poppler::Page| PNG ^^^^^^^^^^^^^^^ Input
PDF on the Web - Link¶ ↑
# img # src = images/pdf-clickable.png # relative_height = 100 # reflect_ratio = 0.05
Slide properties¶ ↑
: enable-title-on-image
false
Link in image in HTML¶ ↑
# coderay html <map id="XXX"> <area href="..." shape="rect" coords="X,Y,W,H"> </map> <img usemap="#XXX">
poppler - coords¶ ↑
# coderay ruby pdf.each do |page| page.link_mapping.each do |mapping| href = mapping.action x, y, w, h = mapping.area.to_a coords = "#{x},#{y},#{w},#{h}" # Generate <area> end end
Link - Interface¶ ↑
PDF |poppler| HTML ^^^^^^^^^ Extract information
Rabbit - Input¶ ↑
* Source * RD (Ruby Document), Markdown(('note:, PDF, image, ...')) * Theme * Ruby scripts
Input - Interface¶ ↑
Rabbit |texts| Rubyist ^^^^^^^ Version controllable Like normal programs
Knowledge - Rabbit¶ ↑
* Pitch is important for interface\n (('note:インターフェイス設計にピッチは大事')) * "for ((*Rubyist*))" for Rabbit * Use similar way for the original
Rabbit - Theme¶ ↑
Define viewn by Rubyn (('note:Rubyで見た目を定義'))
Theme - Layers¶ ↑
* Customize parameters * Normal Ruby codes to\n control render something
Theme - Parameters¶ ↑
# coderay ruby # CSS selector inspired API: # title-slide author { # margin_top: 2px; # margin_bottom: 1px; # } match(TitleSlide, Author) do |authors| authors.margin_top = @space * 2 authors.margin_bottom = @space end
Theme - Render¶ ↑
# coderay ruby match(Slide) do |slides| loader = ImageLoader.new("mini-kame-taro.png") slides.add_post_draw_proc do x = ... # Compute the next tortoise position loader.draw(canvas, x, y, parameters) end end
(('note:The')) Tortoise and (('note:the')) Harenin Rabbitn(('note:Rabbitでうさぎとかめ'))¶ ↑
# img # src = images/the-tortoise-and-the-hare.png # relative_width = 100 # reflect_ratio = 0.05
Slide properties¶ ↑
: enable-title-on-image
false
Hare - Slide positionn(('note:うさぎはスライド位置'))¶ ↑
# img # src = images/the-tortoise-and-the-hare-hare.png # relative_width = 100 # reflect_ratio = 0.05
Slide properties¶ ↑
: enable-title-on-image
false
Tortoise - Timern(('note:かめはタイマー'))¶ ↑
# img # src = images/the-tortoise-and-the-hare-tortoise.png # relative_width = 100 # reflect_ratio = 0.05
Slide properties¶ ↑
: enable-title-on-image
false
Slown(('note:遅い'))¶ ↑
# img # src = images/the-tortoise-and-the-hare-slow.png # relative_width = 100 # reflect_ratio = 0.05
Slide properties¶ ↑
: enable-title-on-image
false
Goodn(('note:ちょうどいい'))¶ ↑
# img # src = images/the-tortoise-and-the-hare-good.png # relative_width = 100 # reflect_ratio = 0.05
Slide properties¶ ↑
: enable-title-on-image
false
Fastn(('note:速い'))¶ ↑
# img # src = images/the-tortoise-and-the-hare-fast.png # relative_width = 100 # reflect_ratio = 0.05
Slide properties¶ ↑
: enable-title-on-image
false
Knowledge - Rabbit¶ ↑
* Product name is important for interface\n (('note:インターフェイス設計にピッチは大事')) * Rabbit isn't Hare😜 * ...
TODO¶ ↑
i18n
Jekyll
rake only
twitter.com/darashi/status/909994900694769664
gdb b rb_raise