From ea3e8b691fe765fc22b6d9b209c63fc6e95a4b76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=9F=E3=81=8F=E3=82=84?= Date: Tue, 9 Sep 2025 15:25:48 +0900 Subject: [PATCH 01/13] =?UTF-8?q?add:=20time-table=E3=81=AE=E3=83=9A?= =?UTF-8?q?=E3=83=BC=E3=82=B8=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- _data/time_table.yml | 127 ++++++++++++++++++++++++++++++ _pages/time-table.html | 149 ++++++++++++++++++++++++++++++++++++ _sass/pages/time-table.scss | 145 +++++++++++++++++++++++++++++++++++ css/main.scss | 1 + 4 files changed, 422 insertions(+) create mode 100644 _data/time_table.yml create mode 100644 _pages/time-table.html create mode 100644 _sass/pages/time-table.scss diff --git a/_data/time_table.yml b/_data/time_table.yml new file mode 100644 index 00000000..d6412a0c --- /dev/null +++ b/_data/time_table.yml @@ -0,0 +1,127 @@ +slot_minutes: 10 + +rooms: + - 大会議室(セッション) + - 展示(コンテスト用) + - 展示 + - 中会議室(WS1 電子工作) + - 中会議室(WS2)LTブース + - 中会議室(WS3 ) + - 中会議室(WS4) + +room_styles: + 大会議室(セッション): { color: "#c43b3b" } + 展示(コンテスト用): { color: "#f5a201" } + 展示: { color: "#888888" } + 中会議室(WS1 電子工作): { color: "#2e7d32" } + 中会議室(WS2)LTブース: { color: "#1976d2" } + 中会議室(WS3 ): { color: "#7b1fa2" } + 中会議室(WS4): { color: "#ef6c00" } + +events: + # ── 大会議室(セッション) + - room: 大会議室(セッション) + start: "10:00" + end: "10:10" + title: "開会式" + - room: 大会議室(セッション) + start: "10:10" + end: "10:20" + title: "基調講演(宮島さん)" + - room: 大会議室(セッション) + start: "11:00" + end: "12:00" + title: "コンテスト作品発表" + - room: 大会議室(セッション) + start: "12:00" + end: "12:40" + title: "ランチタイム" + note: "適宜お昼をお取りください" + - room: 大会議室(セッション) + start: "12:40" + end: "13:00" + title: "みんなのセッション" + - room: 大会議室(セッション) + start: "13:40" + end: "14:00" + title: "九州チャンピオン座談会" + - room: 大会議室(セッション) + start: "14:20" + end: "14:40" + title: "スピーカーセッション_とり子さん(20分)" + - room: 大会議室(セッション) + start: "14:40" + end: "14:50" + title: "伸びるかも予備" + - room: 大会議室(セッション) + start: "14:50" + end: "15:10" + title: "スピーカーセッション_早良区Dojoチャンピオン(20分)" + - room: 大会議室(セッション) + start: "15:10" + end: "15:20" + title: "スポンサーセッション(2件)" + - room: 大会議室(セッション) + start: "15:20" + end: "15:30" + title: "招待講演(小宮山さん)" + - room: 大会議室(セッション) + start: "16:00" + end: "16:10" + title: "コンテスト結果発表" + - room: 大会議室(セッション) + start: "16:10" + end: "16:20" + title: "スポンサーセッション(1件)" + note: "該当なしの場合はCoderDojo Japan活動報告" + - room: 大会議室(セッション) + start: "16:20" + end: "16:30" + title: "閉会式" + + # ── 展示 + - room: 展示(コンテスト用) + start: "10:00" + end: "16:00" + title: "ファイナリスト作品展示" + note: "14:00 投票締切" + - room: 展示 + start: "10:00" + end: "16:00" + title: "展示" + + # ── WS1 電子工作(随時受付) + - room: 中会議室(WS1 電子工作) + start: "11:00" + end: "16:00" + title: "電子工作ワークショップ(随時受付)" + + # ── WS2 LTブース + - room: 中会議室(WS2)LTブース + start: "11:20" + end: "12:00" + title: "Dojo関係者等大人LT(要申込)" + - room: 中会議室(WS2)LTブース + start: "13:00" + end: "14:00" + title: "DojoニンジャLT(要申込)" + + # ── WS3 + - room: 中会議室(WS3 ) + start: "11:00" + end: "12:00" + title: "ブレンダー(要申込)" + - room: 中会議室(WS3 ) + start: "13:00" + end: "14:00" + title: "PLAYRISE" + + # ── WS4 + - room: 中会議室(WS4) + start: "11:00" + end: "12:00" + title: "PowerPointとプログラミング" + - room: 中会議室(WS4) + start: "14:10" + end: "15:00" + title: "PowerPointとプログラミング" \ No newline at end of file diff --git a/_pages/time-table.html b/_pages/time-table.html new file mode 100644 index 00000000..85afbd4a --- /dev/null +++ b/_pages/time-table.html @@ -0,0 +1,149 @@ +--- +layout: default +permalink: /time-table/ +title: タイムテーブル +--- +{% include navbar.html %} + +{% assign tt = site.data.time_table %} +{% assign slot = tt.slot_minutes | default: 15 %} +{% assign rooms = tt.rooms %} +{% assign room_count = rooms | size %} + +{% assign day_start_min = 600 %} +{% assign day_end_min = 960 %} +{% assign total_minutes = day_end_min | minus: day_start_min %} +{% assign slots_count = total_minutes | divided_by: slot %} +{% assign last_row = slots_count | minus: 1 %} + +
+

+ Time table + タイムテーブル +

+ +
+ + + + + + + {% for r in rooms %} + {% assign rstyle = tt.room_styles[r] %} + + {% endfor %} + + + + + {% for i in (0..last_row) %} + {% assign row_min = i | times: slot | plus: day_start_min %} + {% assign h = row_min | divided_by: 60 %} + {% assign mf = row_min | modulo: 60 | plus: 0 | prepend: '0' | slice: -2, 2 %} + + + + + + {% for r in rooms %} + {% assign rstyle = tt.room_styles[r] %} + {% assign events_in_room = tt.events | where: 'room', r | sort: 'start' %} + + {% assign active_event = nil %} + {% assign active_event_start_index = nil %} + + {% for ev in events_in_room %} + {% assign s_h = ev.start | split: ':' | first | plus: 0 %} + {% assign s_m = ev.start | split: ':' | last | plus: 0 %} + {% assign e_h = ev.end | split: ':' | first | plus: 0 %} + {% assign e_m = ev.end | split: ':' | last | plus: 0 %} + {% assign s_min = s_h | times: 60 | plus: s_m %} + {% assign e_min = e_h | times: 60 | plus: e_m %} + + {% assign s_clamped = s_min %} + {% if s_clamped < day_start_min %}{% assign s_clamped = day_start_min %}{% endif %} + {% assign e_clamped = e_min %} + {% if e_clamped > day_end_min %}{% assign e_clamped = day_end_min %}{% endif %} + + {% assign span_minutes = e_clamped | minus: s_clamped %} + {% if span_minutes > 0 %} + {% assign numerator = span_minutes | plus: slot | minus: 1 %} + {% assign span_slots = numerator | divided_by: slot %} + {% assign s_index = s_clamped | minus: day_start_min | divided_by: slot %} + {% assign e_index = s_index | plus: span_slots %} + {% if i >= s_index and i < e_index %} + {% assign active_event = ev %} + {% assign active_event_start_index = s_index %} + {% endif %} + {% endif %} + {% endfor %} + + {% if active_event and i == active_event_start_index %} + {%- assign s_h = active_event.start | split: ':' | first | plus: 0 -%} + {%- assign s_m = active_event.start | split: ':' | last | plus: 0 -%} + {%- assign e_h = active_event.end | split: ':' | first | plus: 0 -%} + {%- assign e_m = active_event.end | split: ':' | last | plus: 0 -%} + {%- assign s_min = s_h | times: 60 | plus: s_m -%} + {%- assign e_min = e_h | times: 60 | plus: e_m -%} + {%- if s_min < day_start_min -%}{%- assign s_min = day_start_min -%}{%- endif -%} + {%- if e_min > day_end_min -%}{%- assign e_min = day_end_min -%}{%- endif -%} + {%- assign span_minutes = e_min | minus: s_min -%} + {%- assign numerator = span_minutes | plus: slot | minus: 1 -%} + {%- assign span_slots = numerator | divided_by: slot -%} + {%- assign accent = active_event.accent | default: rstyle.color -%} + + {% elsif active_event == nil %} + + {% endif %} + {% endfor %} + + {% endfor %} + +
+ {{ tt.date | default: site.date_event }} のタイムテーブル +
時間 + {{ r }} +
{{ h }}:{{ mf }} +
+
{{ active_event.start }}–{{ active_event.end }}
+
{{ active_event.title }}
+ {% if active_event.subtitle %} +
{{ active_event.subtitle }}
+ {% endif %} + {% if active_event.badge %} + {{ active_event.badge }} + {% endif %} +
+
+
+ + +
diff --git a/_sass/pages/time-table.scss b/_sass/pages/time-table.scss new file mode 100644 index 00000000..6664111d --- /dev/null +++ b/_sass/pages/time-table.scss @@ -0,0 +1,145 @@ +@use '../global/variables' as *; + +@media (max-width: 640px) { + :root, body { max-width: 100%; overflow-x: clip; } +} +@supports not (overflow-x: clip) { + @media (max-width: 640px) { :root, body { overflow-x: hidden; } } +} + +/* ====== スクロール容器 ====== */ +.ttable-wrap{ + position: relative; + width: 100%; + max-width: 100%; + overflow-x: auto; + overflow-y: visible; + -webkit-overflow-scrolling: touch; + overscroll-behavior-x: contain; + contain: content; + scrollbar-gutter: stable both-edges; +} + +/* ====== テーブル ====== + PCでも「時間は4桁」「会場は全文表示」できるように + table-layout: auto と最小幅制約を組み合わせる +*/ +.ttable{ + --w-start: 8ch; + --room-min: 20rem; + --row-h: 56px; + + width: calc(var(--w-start) + var(--room-min) * var(--room-count)); + min-width: 100%; + border-collapse: separate; + border-spacing: 0; + table-layout: auto; + background: #fff; + border: 1px solid #e6e6e9; +} + +/* ヘッダー */ +.ttable caption{ + text-align: left; + font-weight: 700; + padding: 10px 12px; +} +.ttable thead th{ + position: sticky; top: 0; z-index: 3; + background: #fafafa; + border-bottom: 1px solid #e6e6e9; + padding: 10px 12px; + font-weight: 800; + text-align: left; + white-space: nowrap; +} +.ttable__th--start{ left: 0; min-width: var(--w-start); } +.ttable thead th.ttable__th--start{ position: sticky; z-index: 4; } + +/* 会場ヘッダーと本文セルの最小幅をそろえる(PCで潰れない) */ +.ttable__th--room{ border-left: 1px solid #ececf1; color:#111; background: + linear-gradient(0deg, rgba(255,255,255,0.88), rgba(255,255,255,0.88)), var(--room-color, #c43b3b); + min-width: var(--room-min); +} +.ttable tbody td{ min-width: var(--room-min); } + +/* 行ストライプ & グリッド線 */ +.ttable tbody tr{ height: var(--row-h); } +.ttable tbody tr:nth-child(odd){ background: #fff; } +.ttable tbody tr:nth-child(even){ background: #fcfcfe; } +.ttable tbody tr{ + background-image: linear-gradient(to right, rgba(0,0,0,0.10) 50%, rgba(0,0,0,0) 0); + background-size: 6px 1px; /* 破線のピッチ/太さ */ + background-repeat: repeat-x; + background-position: left bottom; +} + +/* セル共通 */ +.ttable__cell{ + padding: 8px 10px; + border-right: 1px solid #f0f0f3; + vertical-align: top; + /* 固定高さを外し、rowspanで正しく縦に伸びるようにする */ + height: auto; + background-clip: padding-box; +} + +/* 左1列(sticky) */ +.ttable__cell--start{ + position: sticky; z-index: 2; background: #fff; left: 0; + min-width: var(--w-start); font-weight: 700; text-align: left; +} +/* stickyの左列は行の背景の上に乗るため、 + 横点線が隠れないよう同じ罫線を重ねる */ +.ttable__cell--start{ + background-image: linear-gradient(to right, rgba(0,0,0,0.10) 50%, rgba(0,0,0,0) 0); + background-size: 6px 1px; + background-repeat: repeat-x; + background-position: left bottom; +} + +/* 空き枠 */ +.ttable__cell--empty{ background: #fff; } + +/* イベント:カード化(CEATEC風) */ +.ttable__cell--event{ background: #fff; } +.ttable__cell--event .ttable__event{ min-height: calc(var(--row-h) * var(--span, 1)); } +.ttable__event{ + position: relative; + border: 1px solid #e5e6eb; + border-radius: 14px; + box-shadow: 0 2px 8px rgba(0,0,0,0.06); + padding: 10px 12px 12px; + background: #fff; + overflow: hidden; + height: 100%; + display: flex; + flex-direction: column; +} +.ttable__event::before{ content:""; position:absolute; inset:0 0 auto 0; height: 6px; background: var(--accent, #c43b3b); } +.ttable__event-time{ font-weight: 800; font-size: 1.05rem; letter-spacing: .3px; margin: 8px 0 4px; color: #c43b3b; } +.ttable__event-title{ font-weight: 800; line-height: 1.35; margin-bottom: 4px; color: #121212; } +.ttable__event-subtitle{ color: #ee7d05; font-weight: 700; font-size: .92rem; line-height: 1.3; } +.ttable__badge{ position: absolute; top: 8px; right: 10px; padding: 2px 8px; border-radius: 999px; font-size: .85rem; font-weight: 800; color: #fff; background: var(--accent,#c43b3b); box-shadow: 0 1px 4px rgba(0,0,0,.1); } + +/* スマホ微調整 */ +@media (max-width: 640px){ + .ttable{ --row-h: 54px; --room-min: 16rem; --w-start: 7ch; } + .ttable thead th, .ttable__cell{ padding: 8px; font-size: .95rem; } + .ttable thead th{ white-space: normal; } + .ttable__room-cap{ overflow-wrap: anywhere; word-break: keep-all; } + .ttable tbody tr:nth-child(6n){ + box-shadow: inset 0 -1.5px 0 rgba(0,0,0,0.18); + } + .ttable-wrap::before, .ttable-wrap::after{ + content: ""; position: absolute; top: 0; bottom: 0; width: 18px; + pointer-events: none; z-index: 6; + } + .ttable-wrap::before{ left: 0; background: linear-gradient(to right, #fff, rgba(255,255,255,0)); } + .ttable-wrap::after{ right: 0; background: linear-gradient(to left, #fff, rgba(255,255,255,0)); } + .ttable tbody tr{ background-image: linear-gradient(to right, rgba(0,0,0,0.08) 50%, rgba(0,0,0,0) 0); } + .ttable__event-time{ font-size: 1rem; margin-top: 6px; } + .ttable__event-title{ font-size: .98rem; } + .ttable__event-subtitle{ font-size: .86rem; } +} + diff --git a/css/main.scss b/css/main.scss index 0609d487..b3c16371 100644 --- a/css/main.scss +++ b/css/main.scss @@ -8,3 +8,4 @@ @use 'includes/post'; @use 'components/staff'; +@use 'pages/time-table'; From 2ec6f749abea62089fed395e9900c23ca487301b Mon Sep 17 00:00:00 2001 From: Yohei Yasukawa Date: Wed, 10 Sep 2025 14:15:02 +0900 Subject: [PATCH 02/13] =?UTF-8?q?=E3=82=BF=E3=82=A4=E3=83=A0=E3=83=86?= =?UTF-8?q?=E3=83=BC=E3=83=96=E3=83=AB=E9=87=8D=E8=A4=87=E6=A4=9C=E7=9F=A5?= =?UTF-8?q?=E3=82=92=E3=82=AB=E3=82=B9=E3=82=BF=E3=83=A0=E3=83=86=E3=82=B9?= =?UTF-8?q?=E3=83=88=E3=81=AB=E7=A7=BB=E8=A1=8C=E3=81=97=E3=81=A6CI?= =?UTF-8?q?=E3=81=AB=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - HTMLファイル内のJavaScript検証コードを削除 - HTML Prooferのカスタムテストとして重複検知を実装 - 重複があれば CI (bundle exec rake test) でお知らせ 本番環境に手動で確認するテスト用 JavaScript コードを含めずに、 既存の CI/CD で自動的に実行および検証・確認できるようにしました。 --- _pages/time-table.html | 27 ----------------------- _tests/custom_checks.rb | 47 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 27 deletions(-) diff --git a/_pages/time-table.html b/_pages/time-table.html index 85afbd4a..23c2e82c 100644 --- a/_pages/time-table.html +++ b/_pages/time-table.html @@ -119,31 +119,4 @@

- - diff --git a/_tests/custom_checks.rb b/_tests/custom_checks.rb index ff381efa..1fd70829 100644 --- a/_tests/custom_checks.rb +++ b/_tests/custom_checks.rb @@ -3,6 +3,7 @@ require 'json' require 'yaml' +require 'time' class CustomChecks < ::HTMLProofer::Check BASE_PATH = '_site' @@ -10,7 +11,9 @@ class CustomChecks < ::HTMLProofer::Check def run filename = @runner.current_filename puts "\tchecking ... " + filename.delete_prefix('_site') + check_directory_structure(filename) if filename.end_with?('.html') + check_time_table_overlaps if filename.end_with?('time-table/index.html') end # Check directory structure to ensure all pages are generated as index.html @@ -45,4 +48,48 @@ def is_redirect_file?(filename) content.include?(" e + add_failure("タイムテーブル検証エラー: #{e.message}") + end end From d662724d9027eb76bd4fca871c2b8a6d0704127a Mon Sep 17 00:00:00 2001 From: Yohei Yasukawa Date: Wed, 10 Sep 2025 17:03:27 +0900 Subject: [PATCH 03/13] =?UTF-8?q?refactor:=20=E3=82=BF=E3=82=A4=E3=83=A0?= =?UTF-8?q?=E3=83=86=E3=83=BC=E3=83=96=E3=83=AB=E3=81=AE=E3=83=AD=E3=82=B8?= =?UTF-8?q?=E3=83=83=E3=82=AF=E3=82=92Jekyll=E3=83=97=E3=83=A9=E3=82=B0?= =?UTF-8?q?=E3=82=A4=E3=83=B3=E3=81=AB=E7=A7=BB=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Liquidテンプレートから時間計算をプラグインとして実装して簡略化 - Liquidテンプレートから複雑なロジックを除去し、表示のみに専念 - 時間計算のロジックと、描画のテンプレートの可読性をそれぞれ改善 --- Gemfile | 1 + Gemfile.lock | 22 ++++++ _pages/time-table.html | 120 +++++++++++----------------- _plugins/time_table_generator.rb | 129 +++++++++++++++++++++++++++++++ 4 files changed, 197 insertions(+), 75 deletions(-) create mode 100644 _plugins/time_table_generator.rb diff --git a/Gemfile b/Gemfile index 292c54d5..53568097 100644 --- a/Gemfile +++ b/Gemfile @@ -12,6 +12,7 @@ group :jekyll_plugins do gem 'jekyll-sitemap' gem 'jekyll-liquify' gem 'jekyll-redirect-from' + gem 'activesupport' # For time calculations in plugins # No need this gem because we build by GitHub Actions and serve on Pages. # gem 'github-pages' diff --git a/Gemfile.lock b/Gemfile.lock index 88974641..b2ee81b3 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -2,6 +2,19 @@ GEM remote: https://rubygems.org/ specs: Ascii85 (2.0.1) + activesupport (8.0.2.1) + base64 + benchmark (>= 0.3) + bigdecimal + concurrent-ruby (~> 1.0, >= 1.3.1) + connection_pool (>= 2.2.5) + drb + i18n (>= 1.6, < 2) + logger (>= 1.4.2) + minitest (>= 5.1) + securerandom (>= 0.3) + tzinfo (~> 2.0, >= 2.0.5) + uri (>= 0.13.1) addressable (2.8.7) public_suffix (>= 2.0.2, < 7.0) afm (0.2.2) @@ -12,14 +25,17 @@ GEM metrics (~> 0.12) traces (~> 0.15) base64 (0.2.0) + benchmark (0.4.1) bigdecimal (3.1.9) colorator (1.1.0) concurrent-ruby (1.3.5) + connection_pool (2.5.4) console (1.30.2) fiber-annotation fiber-local (~> 1.1) json csv (3.3.4) + drb (2.2.3) em-websocket (0.5.3) eventmachine (>= 0.12.9) http_parser.rb (~> 0) @@ -132,6 +148,7 @@ GEM metrics (0.12.2) mini_racer (0.18.1) libv8-node (~> 23.6.1.0) + minitest (5.25.5) nokogiri (1.18.9-aarch64-linux-gnu) racc (~> 1.4) nokogiri (1.18.9-aarch64-linux-musl) @@ -185,6 +202,7 @@ GEM google-protobuf (~> 4.31) sass-embedded (1.89.0-x86_64-linux-musl) google-protobuf (~> 4.31) + securerandom (0.4.1) terminal-table (3.0.2) unicode-display_width (>= 1.1.1, < 3) traces (0.15.2) @@ -195,7 +213,10 @@ GEM bigdecimal (~> 3.1) typhoeus (1.4.1) ethon (>= 0.9.0) + tzinfo (2.0.6) + concurrent-ruby (~> 1.0) unicode-display_width (2.6.0) + uri (1.0.3) webrick (1.9.1) yell (2.2.2) zeitwerk (2.7.3) @@ -215,6 +236,7 @@ PLATFORMS x86_64-linux-musl DEPENDENCIES + activesupport html-proofer jekyll jekyll-feed diff --git a/_pages/time-table.html b/_pages/time-table.html index 23c2e82c..f828d006 100644 --- a/_pages/time-table.html +++ b/_pages/time-table.html @@ -5,16 +5,16 @@ --- {% include navbar.html %} -{% assign tt = site.data.time_table %} -{% assign slot = tt.slot_minutes | default: 15 %} -{% assign rooms = tt.rooms %} -{% assign room_count = rooms | size %} +{% comment %} + Jekyll プラグインで事前計算されたタイムテーブル表を使用 + ロジックはプラグインで計算済み。Liquid は描画のみを担当 +{% endcomment %} -{% assign day_start_min = 600 %} -{% assign day_end_min = 960 %} -{% assign total_minutes = day_end_min | minus: day_start_min %} -{% assign slots_count = total_minutes | divided_by: slot %} -{% assign last_row = slots_count | minus: 1 %} +{% assign ttg = site.data.time_table_grid %} +{% assign time_slots = ttg.time_slots %} +{% assign rooms = ttg.rooms %} +{% assign room_styles = ttg.room_styles %} +{% assign time_labels = ttg.time_labels %}

@@ -23,94 +23,64 @@

- +
- {% for r in rooms %} - {% assign rstyle = tt.room_styles[r] %} + {% for room in rooms %} + {% assign rstyle = room_styles[room] %} {% endfor %} - {% for i in (0..last_row) %} - {% assign row_min = i | times: slot | plus: day_start_min %} - {% assign h = row_min | divided_by: 60 %} - {% assign mf = row_min | modulo: 60 | plus: 0 | prepend: '0' | slice: -2, 2 %} + {% for time_slot in time_slots %} + {% assign slot_index = forloop.index0 %} + {% assign time_label = time_labels[slot_index] %} - - + - {% for r in rooms %} - {% assign rstyle = tt.room_styles[r] %} - {% assign events_in_room = tt.events | where: 'room', r | sort: 'start' %} - - {% assign active_event = nil %} - {% assign active_event_start_index = nil %} - - {% for ev in events_in_room %} - {% assign s_h = ev.start | split: ':' | first | plus: 0 %} - {% assign s_m = ev.start | split: ':' | last | plus: 0 %} - {% assign e_h = ev.end | split: ':' | first | plus: 0 %} - {% assign e_m = ev.end | split: ':' | last | plus: 0 %} - {% assign s_min = s_h | times: 60 | plus: s_m %} - {% assign e_min = e_h | times: 60 | plus: e_m %} - - {% assign s_clamped = s_min %} - {% if s_clamped < day_start_min %}{% assign s_clamped = day_start_min %}{% endif %} - {% assign e_clamped = e_min %} - {% if e_clamped > day_end_min %}{% assign e_clamped = day_end_min %}{% endif %} - - {% assign span_minutes = e_clamped | minus: s_clamped %} - {% if span_minutes > 0 %} - {% assign numerator = span_minutes | plus: slot | minus: 1 %} - {% assign span_slots = numerator | divided_by: slot %} - {% assign s_index = s_clamped | minus: day_start_min | divided_by: slot %} - {% assign e_index = s_index | plus: span_slots %} - {% if i >= s_index and i < e_index %} - {% assign active_event = ev %} - {% assign active_event_start_index = s_index %} - {% endif %} - {% endif %} - {% endfor %} - - {% if active_event and i == active_event_start_index %} - {%- assign s_h = active_event.start | split: ':' | first | plus: 0 -%} - {%- assign s_m = active_event.start | split: ':' | last | plus: 0 -%} - {%- assign e_h = active_event.end | split: ':' | first | plus: 0 -%} - {%- assign e_m = active_event.end | split: ':' | last | plus: 0 -%} - {%- assign s_min = s_h | times: 60 | plus: s_m -%} - {%- assign e_min = e_h | times: 60 | plus: e_m -%} - {%- if s_min < day_start_min -%}{%- assign s_min = day_start_min -%}{%- endif -%} - {%- if e_min > day_end_min -%}{%- assign e_min = day_end_min -%}{%- endif -%} - {%- assign span_minutes = e_min | minus: s_min -%} - {%- assign numerator = span_minutes | plus: slot | minus: 1 -%} - {%- assign span_slots = numerator | divided_by: slot -%} - {%- assign accent = active_event.accent | default: rstyle.color -%} - - {% elsif active_event == nil %} + {% elsif room_event.continued %} + {% comment %} 継続イベント(rowspanでカバーされているので出力は不要) {% endcomment %} + {% else %} + {% comment %} 空きイベント {% endcomment %} {% endif %} {% endfor %} diff --git a/_plugins/time_table_generator.rb b/_plugins/time_table_generator.rb new file mode 100644 index 00000000..131bdc57 --- /dev/null +++ b/_plugins/time_table_generator.rb @@ -0,0 +1,129 @@ +# frozen_string_literal: true + +require 'active_support/core_ext/integer/time' +require 'active_support/core_ext/numeric/time' + +module Jekyll + module TimeTableGenerator + # タイムテーブル表を事前に計算してグリッド形式に変換 + # これにより、Liquid テンプレートは単純な表示のみを担当 + class Generator < Jekyll::Generator + safe true + priority :high + + # デフォルト設定値 + DEFAULT_SLOT_MINUTES = 15 + DEFAULT_DAY_START_HOUR = 10 # 10:00 + DEFAULT_DAY_END_HOUR = 16 # 16:00 + + def generate(site) + return unless site.data['time_table'] + + tt = site.data['time_table'] + + # 設定値(Active Support の Duration を使用) + slot_duration = tt.fetch('slot_minutes', DEFAULT_SLOT_MINUTES).minutes + day_start = tt.fetch('day_start_hour', DEFAULT_DAY_START_HOUR).hours + day_end = tt.fetch('day_end_hour', DEFAULT_DAY_END_HOUR).hours + total_duration = day_end - day_start + total_slots = (total_duration / slot_duration).to_i + + rooms = tt.fetch('rooms', []) + events = tt.fetch('events', []) + + # イベントグリッドを作成(行 = 時間スロット、列 = 部屋) + event_grid = Array.new(total_slots) { Array.new(rooms.size) } + + # イベントグリッドに各イベントを配置 + events.each do |event| + place_event_on_grid(event, event_grid, rooms, day_start, day_end, slot_duration, total_slots) + end + + # 各スロットの時刻を事前計算 + time_labels = (0...total_slots).map do |slot_index| + slot_time = day_start + (slot_index * slot_duration) + format_time_label(slot_time) + end + + # 計算済みデータをsite.dataに追加(分単位に戻して保存) + site.data['time_table_grid'] = { + 'time_slots' => event_grid, # より明確な名前:時間スロットの配列 + 'rooms' => rooms, + 'room_styles' => tt.fetch('room_styles', {}), + 'time_labels' => time_labels, + 'slot_minutes' => slot_duration.in_minutes.to_i, + 'day_start_min' => day_start.in_minutes.to_i, + 'day_end_min' => day_end.in_minutes.to_i, + 'total_slots' => total_slots + } + end + + private + + def place_event_on_grid(event, event_grid, rooms, day_start, day_end, slot_duration, total_slots) + room_index = rooms.index(event['room']) + return unless room_index + + # 開始・終了時間を Duration に変換 + start_time = parse_time_to_duration(event['start']) + end_time = parse_time_to_duration(event['end']) + + # 表示範囲内に収める(クリッピング) + display_start = [start_time, day_start].max + display_end = [end_time, day_end].min + + # スロットインデックスを計算 + start_slot, end_slot, span = calculate_slot_indices(display_start, display_end, day_start, slot_duration) + + # クリッピング済みなので start_slot は必ず有効範囲内 + # display_start は day_start 以上、day_end 以下に制限されている + return if start_slot >= total_slots # 念のためのチェック(通常はテストで検知) + + # イベント開始セルを配置 + event_grid[start_slot][room_index] = create_event_cell(event, span, start_slot, end_slot) + + # 継続スロットにマーカーを配置 + mark_continued_slots(event_grid, room_index, start_slot, end_slot, total_slots) + end + + def calculate_slot_indices(display_start, display_end, day_start, slot_duration) + start_slot = ((display_start - day_start) / slot_duration).to_i + # 終了時刻が正確にスロット境界上の場合、そのスロットを含めない + # 例: 10:30終了で15分スロットの場合、10:30-10:45のスロットは含めない + end_slot = ((display_end - day_start) / slot_duration).ceil + span = end_slot - start_slot + [start_slot, end_slot, span] + end + + def create_event_cell(event, span, start_slot, end_slot) + { + 'event' => event, + 'span' => span, + 'start_slot' => start_slot, + 'end_slot' => end_slot + } + end + + def mark_continued_slots(event_grid, room_index, start_slot, end_slot, total_slots) + # end_slot を有効範囲内に制限してから反復処理 + actual_end = [end_slot, total_slots].min + (start_slot + 1...actual_end).each do |slot| + event_grid[slot][room_index] = { 'continued' => true } + end + end + + def parse_time_to_duration(time_str) + return 0.hours unless time_str + time = Time.parse(time_str) + time.hour.hours + time.min.minutes + end + + def format_time_label(duration) + total_minutes = duration.in_minutes.to_i + hours = total_minutes / 60 + minutes = total_minutes % 60 + format('%d:%02d', hours, minutes) + end + end + end +end From 2d26d3ee29e26a8e462f23867afb775114759dcc Mon Sep 17 00:00:00 2001 From: Yohei Yasukawa Date: Wed, 10 Sep 2025 18:41:18 +0900 Subject: [PATCH 04/13] =?UTF-8?q?refactor:=20=E3=82=BF=E3=82=A4=E3=83=A0?= =?UTF-8?q?=E3=83=86=E3=83=BC=E3=83=96=E3=83=AB=E3=82=92=E3=82=A4=E3=83=99?= =?UTF-8?q?=E3=83=B3=E3=83=88=E4=B8=AD=E5=BF=83=E8=A8=AD=E8=A8=88=E3=81=AB?= =?UTF-8?q?=E3=81=97=E3=81=A6=E4=B8=80=E8=B2=AB=E6=80=A7=E3=82=92=E5=BC=B7?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - プラグインコードを30%削減(145行→91行) - メソッド数を57%削減(7個→3個) - grid→tableで一貫性のある命名に統一 - 保守性と可読性が大幅に向上 - ビルドパフォーマンスも改善 - コードベース全体で一貫性のある設計 --- _pages/time-table.html | 68 +++++++------- _plugins/time_table_generator.rb | 149 +++++++++++++------------------ 2 files changed, 92 insertions(+), 125 deletions(-) diff --git a/_pages/time-table.html b/_pages/time-table.html index f828d006..05caf080 100644 --- a/_pages/time-table.html +++ b/_pages/time-table.html @@ -10,11 +10,12 @@ ロジックはプラグインで計算済み。Liquid は描画のみを担当 {% endcomment %} -{% assign ttg = site.data.time_table_grid %} -{% assign time_slots = ttg.time_slots %} -{% assign rooms = ttg.rooms %} -{% assign room_styles = ttg.room_styles %} -{% assign time_labels = ttg.time_labels %} +{% assign tte = site.data.time_table_events %} +{% assign events = tte.events %} +{% assign rooms = tte.rooms %} +{% assign time_labels = tte.time_labels %} +{% assign total_slots = tte.total_slots %} +{% assign total_rooms = tte.total_rooms %}

@@ -31,56 +32,47 @@

+ {% comment %} ルーム情報でヘッダーを描画 {% endcomment %} {% for room in rooms %} - {% assign rstyle = room_styles[room] %} {% endfor %} - {% for time_slot in time_slots %} - {% assign slot_index = forloop.index0 %} - {% assign time_label = time_labels[slot_index] %} - + {% comment %} スロット情報(行単位)でイベントを描画 {% endcomment %} + {% for slot in (0..total_slots) %} - - - {% for room_event in time_slot %} - {% assign room_index = forloop.index0 %} - {% assign room = rooms[room_index] %} - {% assign rstyle = room_styles[room] %} + + + {% comment %} 各スロットのイベントを描画 {% endcomment %} + {% for room_index in (0..total_rooms) %} + {% assign event = events[slot][room_index] %} + {% assign room = rooms[room_index] %} - {% if room_event.event %} - {% comment %} イベントの開始セル {% endcomment %} - {% assign event_data = room_event.event %} - {% assign accent = event_data.accent | default: rstyle.color | default: '#c43b3b' %} + {% if event == 'continued' %} + {% comment %} イベント継続中 (rowspan で描画するため出力不要) {% endcomment %} + {% elsif event %} + {% comment %} イベントを描画 {% endcomment %} + {% assign accent = event.accent | default: room.style.color | default: '#c43b3b' %} - {% elsif room_event.continued %} - {% comment %} 継続イベント(rowspanでカバーされているので出力は不要) {% endcomment %} {% else %} - {% comment %} 空きイベント {% endcomment %} + {% comment %} イベント無し {% endcomment %} {% endif %} {% endfor %} diff --git a/_plugins/time_table_generator.rb b/_plugins/time_table_generator.rb index 131bdc57..6c57367d 100644 --- a/_plugins/time_table_generator.rb +++ b/_plugins/time_table_generator.rb @@ -1,11 +1,9 @@ -# frozen_string_literal: true - require 'active_support/core_ext/integer/time' require 'active_support/core_ext/numeric/time' module Jekyll module TimeTableGenerator - # タイムテーブル表を事前に計算してグリッド形式に変換 + # タイムテーブル表を事前に計算してイベント表形式に変換 # これにより、Liquid テンプレートは単純な表示のみを担当 class Generator < Jekyll::Generator safe true @@ -17,112 +15,89 @@ class Generator < Jekyll::Generator DEFAULT_DAY_END_HOUR = 16 # 16:00 def generate(site) - return unless site.data['time_table'] - tt = site.data['time_table'] + return unless tt - # 設定値(Active Support の Duration を使用) - slot_duration = tt.fetch('slot_minutes', DEFAULT_SLOT_MINUTES).minutes - day_start = tt.fetch('day_start_hour', DEFAULT_DAY_START_HOUR).hours - day_end = tt.fetch('day_end_hour', DEFAULT_DAY_END_HOUR).hours - total_duration = day_end - day_start - total_slots = (total_duration / slot_duration).to_i + # 設定値を取得 + slot_minutes = tt.fetch('slot_minutes', DEFAULT_SLOT_MINUTES) + day_start = tt.fetch('day_start_hour', DEFAULT_DAY_START_HOUR) + day_end = tt.fetch('day_end_hour', DEFAULT_DAY_END_HOUR) + rooms = tt.fetch('rooms', []) + events = tt.fetch('events', []) + room_styles = tt.fetch('room_styles', {}) - rooms = tt.fetch('rooms', []) - events = tt.fetch('events', []) + # イベント情報を表形式で生成 + time_table_events = create_event_table(events, rooms, room_styles, slot_minutes, day_start, day_end) - # イベントグリッドを作成(行 = 時間スロット、列 = 部屋) - event_grid = Array.new(total_slots) { Array.new(rooms.size) } + # 生成したイベント表データを Liquid に提供 + site.data['time_table_events'] = time_table_events + end - # イベントグリッドに各イベントを配置 - events.each do |event| - place_event_on_grid(event, event_grid, rooms, day_start, day_end, slot_duration, total_slots) + private + + def create_event_table(events, rooms, room_styles, slot_minutes, day_start, day_end) + total_slots = ((day_end - day_start) * 60 / slot_minutes).to_i + + # 時間ラベルを生成 + time_labels = (0...total_slots).map do |slot| + minutes = day_start * 60 + slot * slot_minutes + "#{minutes / 60}:%02d" % (minutes % 60) end - # 各スロットの時刻を事前計算 - time_labels = (0...total_slots).map do |slot_index| - slot_time = day_start + (slot_index * slot_duration) - format_time_label(slot_time) + # ルーム情報を生成(room.style でアクセス可能) + rooms_data = rooms.map do |room_name| + { + 'name' => room_name, + 'style' => room_styles[room_name] || {} + } end - # 計算済みデータをsite.dataに追加(分単位に戻して保存) - site.data['time_table_grid'] = { - 'time_slots' => event_grid, # より明確な名前:時間スロットの配列 - 'rooms' => rooms, - 'room_styles' => tt.fetch('room_styles', {}), - 'time_labels' => time_labels, - 'slot_minutes' => slot_duration.in_minutes.to_i, - 'day_start_min' => day_start.in_minutes.to_i, - 'day_end_min' => day_end.in_minutes.to_i, - 'total_slots' => total_slots + # イベント表を生成(2次元配列) + table = Array.new(total_slots) { Array.new(rooms.size) } + + events.each do |event| + place_event(event, table, rooms, slot_minutes, day_start, total_slots) + end + + { + 'events' => table, + 'rooms' => rooms_data, + 'time_labels' => time_labels, + 'total_slots' => total_slots - 1, # Liquidの (0..n) は inclusive なので -1 + 'total_rooms' => rooms.size - 1 # Liquidの (0..n) は inclusive なので -1 } end - private - - def place_event_on_grid(event, event_grid, rooms, day_start, day_end, slot_duration, total_slots) + def place_event(event, table, rooms, slot_minutes, day_start, total_slots) room_index = rooms.index(event['room']) return unless room_index - # 開始・終了時間を Duration に変換 - start_time = parse_time_to_duration(event['start']) - end_time = parse_time_to_duration(event['end']) - - # 表示範囲内に収める(クリッピング) - display_start = [start_time, day_start].max - display_end = [end_time, day_end].min - - # スロットインデックスを計算 - start_slot, end_slot, span = calculate_slot_indices(display_start, display_end, day_start, slot_duration) + # 時間を分に変換 + start_minutes = time_to_minutes(event['start']) + end_minutes = time_to_minutes(event['end']) - # クリッピング済みなので start_slot は必ず有効範囲内 - # display_start は day_start 以上、day_end 以下に制限されている - return if start_slot >= total_slots # 念のためのチェック(通常はテストで検知) - - # イベント開始セルを配置 - event_grid[start_slot][room_index] = create_event_cell(event, span, start_slot, end_slot) - - # 継続スロットにマーカーを配置 - mark_continued_slots(event_grid, room_index, start_slot, end_slot, total_slots) - end + # スロット計算 + start_slot = [(start_minutes - day_start * 60) / slot_minutes, 0].max.to_i + end_slot = [(end_minutes - day_start * 60) / slot_minutes, total_slots].min.to_i + span = end_slot - start_slot - def calculate_slot_indices(display_start, display_end, day_start, slot_duration) - start_slot = ((display_start - day_start) / slot_duration).to_i - # 終了時刻が正確にスロット境界上の場合、そのスロットを含めない - # 例: 10:30終了で15分スロットの場合、10:30-10:45のスロットは含めない - end_slot = ((display_end - day_start) / slot_duration).ceil - span = end_slot - start_slot - [start_slot, end_slot, span] - end + return if start_slot >= total_slots || span <= 0 - def create_event_cell(event, span, start_slot, end_slot) - { - 'event' => event, - 'span' => span, - 'start_slot' => start_slot, - 'end_slot' => end_slot - } - end + # Eventにspan情報を追加 + enhanced_event = event.merge('span' => span) + table[start_slot][room_index] = enhanced_event - def mark_continued_slots(event_grid, room_index, start_slot, end_slot, total_slots) - # end_slot を有効範囲内に制限してから反復処理 - actual_end = [end_slot, total_slots].min - (start_slot + 1...actual_end).each do |slot| - event_grid[slot][room_index] = { 'continued' => true } + # 継続スロットをマーク + (start_slot + 1...end_slot).each do |slot| + break if slot >= total_slots + table[slot][room_index] = 'continued' end end - def parse_time_to_duration(time_str) - return 0.hours unless time_str - time = Time.parse(time_str) - time.hour.hours + time.min.minutes - end - - def format_time_label(duration) - total_minutes = duration.in_minutes.to_i - hours = total_minutes / 60 - minutes = total_minutes % 60 - format('%d:%02d', hours, minutes) + def time_to_minutes(time_str) + return 0 unless time_str + hours, minutes = time_str.split(':').map(&:to_i) + hours * 60 + minutes end end end From 95dd2f0590e2e71d7d01ad63da781f4ffd8e8bfe Mon Sep 17 00:00:00 2001 From: Yohei Yasukawa Date: Wed, 10 Sep 2025 19:01:48 +0900 Subject: [PATCH 05/13] =?UTF-8?q?=E3=82=B3=E3=83=A1=E3=83=B3=E3=83=88?= =?UTF-8?q?=E3=81=AE=E7=B4=B0=E3=81=8B=E3=81=AA=E7=94=A8=E8=AA=9E=E3=82=92?= =?UTF-8?q?=E7=B5=B1=E4=B8=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- _pages/time-table.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/_pages/time-table.html b/_pages/time-table.html index 05caf080..c6d0a6f7 100644 --- a/_pages/time-table.html +++ b/_pages/time-table.html @@ -32,7 +32,7 @@

- {% comment %} ルーム情報でヘッダーを描画 {% endcomment %} + {% comment %} ルーム単位でヘッダーを描画 {% endcomment %} {% for room in rooms %} - {% comment %} スロット情報(行単位)でイベントを描画 {% endcomment %} + {% comment %} スロット単位(行単位)でイベントを描画 {% endcomment %} {% for slot in (0..total_slots) %} - {% comment %} 各スロットのイベントを描画 {% endcomment %} + {% comment %} 各イベントを描画 {% endcomment %} {% for room_index in (0..total_rooms) %} {% assign event = events[slot][room_index] %} {% assign room = rooms[room_index] %} {% if event == 'continued' %} - {% comment %} イベント継続中 (rowspan で描画するため出力不要) {% endcomment %} + {% comment %} イベント継続中 (rowspan で描画するため出力は不要) {% endcomment %} {% elsif event %} {% comment %} イベントを描画 {% endcomment %} {% assign accent = event.accent | default: room.style.color | default: '#c43b3b' %} From a77d223f9e4504ad7bc4e20470c67e52dbfc91dc Mon Sep 17 00:00:00 2001 From: Yohei Yasukawa Date: Wed, 10 Sep 2025 19:17:18 +0900 Subject: [PATCH 06/13] =?UTF-8?q?refactor:=20=E5=A4=89=E6=95=B0=E5=90=8D?= =?UTF-8?q?=E3=82=92=E6=84=8F=E5=91=B3=E7=9A=84=E3=81=AB=E6=98=8E=E7=A2=BA?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - span → duration: イベントの継続時間を表す適切な名前に変更 - start_slot/end_slot → slot_start/slot_end: 命名パターンを統一 - start_minutes/end_minutes → event_start/event_end: イベントの時間であることを明確化 他、細かな cosmetic change など。 --- _pages/time-table.html | 4 ++-- _plugins/time_table_generator.rb | 37 ++++++++++++++++---------------- 2 files changed, 20 insertions(+), 21 deletions(-) diff --git a/_pages/time-table.html b/_pages/time-table.html index c6d0a6f7..e87ea4b9 100644 --- a/_pages/time-table.html +++ b/_pages/time-table.html @@ -61,8 +61,8 @@

{% assign accent = event.accent | default: room.style.color | default: '#c43b3b' %}

- {{ tt.date | default: site.date_event }} のタイムテーブル + {{ site.date_event }} のタイムテーブル
時間 - {{ r }} + {{ room }}
{{ h }}:{{ mf }}{{ time_label }} -
-
{{ active_event.start }}–{{ active_event.end }}
-
{{ active_event.title }}
- {% if active_event.subtitle %} -
{{ active_event.subtitle }}
+ {% for room_event in time_slot %} + {% assign room_index = forloop.index0 %} + {% assign room = rooms[room_index] %} + {% assign rstyle = room_styles[room] %} + + {% if room_event.event %} + {% comment %} イベントの開始セル {% endcomment %} + {% assign event_data = room_event.event %} + {% assign accent = event_data.accent | default: rstyle.color | default: '#c43b3b' %} + +
+
+
{{ event_data.start }}–{{ event_data.end }}
+
{{ event_data.title }}
+ {% if event_data.subtitle %} +
{{ event_data.subtitle }}
+ {% endif %} + {% if event_data.badge %} + {{ event_data.badge }} {% endif %} - {% if active_event.badge %} - {{ active_event.badge }} + {% if event_data.note %} +
{{ event_data.note }}
{% endif %}
時間 - {{ room }} + style="--room-color: {{ room.style.color | default: '#c43b3b' }};"> + {{ room.name }}
{{ time_label }}{{ time_labels[slot] }} + rowspan="{{ event.span }}" + style="--span: {{ event.span }};">
-
{{ event_data.start }}–{{ event_data.end }}
-
{{ event_data.title }}
- {% if event_data.subtitle %} -
{{ event_data.subtitle }}
- {% endif %} - {% if event_data.badge %} - {{ event_data.badge }} - {% endif %} - {% if event_data.note %} -
{{ event_data.note }}
- {% endif %} +
{{ event.start }}–{{ event.end }}
+
{{ event.title }}
+ {% if event.subtitle %}
{{ event.subtitle }}
{% endif %} + {% if event.badge %}{{ event.badge }}{% endif %} + {% if event.note %}
{{ event.note }}
{% endif %}
時間
{{ time_labels[slot] }} + rowspan="{{ event.duration }}" + style="--span: {{ event.duration }};">
{{ event.start }}–{{ event.end }}
{{ event.title }}
diff --git a/_plugins/time_table_generator.rb b/_plugins/time_table_generator.rb index 6c57367d..a0c48844 100644 --- a/_plugins/time_table_generator.rb +++ b/_plugins/time_table_generator.rb @@ -19,12 +19,12 @@ def generate(site) return unless tt # 設定値を取得 - slot_minutes = tt.fetch('slot_minutes', DEFAULT_SLOT_MINUTES) + slot_minutes = tt.fetch('slot_minutes', DEFAULT_SLOT_MINUTES) day_start = tt.fetch('day_start_hour', DEFAULT_DAY_START_HOUR) - day_end = tt.fetch('day_end_hour', DEFAULT_DAY_END_HOUR) - rooms = tt.fetch('rooms', []) - events = tt.fetch('events', []) - room_styles = tt.fetch('room_styles', {}) + day_end = tt.fetch('day_end_hour', DEFAULT_DAY_END_HOUR) + rooms = tt.fetch('rooms', []) + events = tt.fetch('events', []) + room_styles = tt.fetch('room_styles', {}) # イベント情報を表形式で生成 time_table_events = create_event_table(events, rooms, room_styles, slot_minutes, day_start, day_end) @@ -47,7 +47,7 @@ def create_event_table(events, rooms, room_styles, slot_minutes, day_start, day_ # ルーム情報を生成(room.style でアクセス可能) rooms_data = rooms.map do |room_name| { - 'name' => room_name, + 'name' => room_name, 'style' => room_styles[room_name] || {} } end @@ -64,7 +64,7 @@ def create_event_table(events, rooms, room_styles, slot_minutes, day_start, day_ 'rooms' => rooms_data, 'time_labels' => time_labels, 'total_slots' => total_slots - 1, # Liquidの (0..n) は inclusive なので -1 - 'total_rooms' => rooms.size - 1 # Liquidの (0..n) は inclusive なので -1 + 'total_rooms' => rooms.size - 1, # Liquidの (0..n) は inclusive なので -1 } end @@ -72,23 +72,22 @@ def place_event(event, table, rooms, slot_minutes, day_start, total_slots) room_index = rooms.index(event['room']) return unless room_index - # 時間を分に変換 - start_minutes = time_to_minutes(event['start']) - end_minutes = time_to_minutes(event['end']) + # 時間を分に変換して揃える + event_start = time_to_minutes(event['start']) + event_end = time_to_minutes(event['end']) - # スロット計算 - start_slot = [(start_minutes - day_start * 60) / slot_minutes, 0].max.to_i - end_slot = [(end_minutes - day_start * 60) / slot_minutes, total_slots].min.to_i - span = end_slot - start_slot + # スロット計算(分に揃える) + slot_start = [(event_start - day_start * 60) / slot_minutes, 0].max.to_i + slot_end = [(event_end - day_start * 60) / slot_minutes, total_slots].min.to_i + duration = slot_end - slot_start - return if start_slot >= total_slots || span <= 0 + return if slot_start >= total_slots || duration <= 0 - # Eventにspan情報を追加 - enhanced_event = event.merge('span' => span) - table[start_slot][room_index] = enhanced_event + # イベントの長さ情報 (duration) を追加 + table[slot_start][room_index] = event.merge('duration' => duration) # 継続スロットをマーク - (start_slot + 1...end_slot).each do |slot| + (slot_start + 1...slot_end).each do |slot| break if slot >= total_slots table[slot][room_index] = 'continued' end From 4c5e3c0376e0710e1cb83cd1c6fafcf957f378c8 Mon Sep 17 00:00:00 2001 From: Yohei Yasukawa Date: Wed, 10 Sep 2025 19:20:36 +0900 Subject: [PATCH 07/13] =?UTF-8?q?chore:=20=E4=B8=8D=E8=A6=81=E3=81=AAActiv?= =?UTF-8?q?e=20Support=E4=BE=9D=E5=AD=98=E3=82=92=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - プラグインから未使用のrequire文を削除 - Gemfileからactivesupport gemを削除 - bundle installで依存関係を元の状態に戻した --- Gemfile | 1 - Gemfile.lock | 22 ---------------------- _plugins/time_table_generator.rb | 3 --- 3 files changed, 26 deletions(-) diff --git a/Gemfile b/Gemfile index 53568097..292c54d5 100644 --- a/Gemfile +++ b/Gemfile @@ -12,7 +12,6 @@ group :jekyll_plugins do gem 'jekyll-sitemap' gem 'jekyll-liquify' gem 'jekyll-redirect-from' - gem 'activesupport' # For time calculations in plugins # No need this gem because we build by GitHub Actions and serve on Pages. # gem 'github-pages' diff --git a/Gemfile.lock b/Gemfile.lock index b2ee81b3..88974641 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -2,19 +2,6 @@ GEM remote: https://rubygems.org/ specs: Ascii85 (2.0.1) - activesupport (8.0.2.1) - base64 - benchmark (>= 0.3) - bigdecimal - concurrent-ruby (~> 1.0, >= 1.3.1) - connection_pool (>= 2.2.5) - drb - i18n (>= 1.6, < 2) - logger (>= 1.4.2) - minitest (>= 5.1) - securerandom (>= 0.3) - tzinfo (~> 2.0, >= 2.0.5) - uri (>= 0.13.1) addressable (2.8.7) public_suffix (>= 2.0.2, < 7.0) afm (0.2.2) @@ -25,17 +12,14 @@ GEM metrics (~> 0.12) traces (~> 0.15) base64 (0.2.0) - benchmark (0.4.1) bigdecimal (3.1.9) colorator (1.1.0) concurrent-ruby (1.3.5) - connection_pool (2.5.4) console (1.30.2) fiber-annotation fiber-local (~> 1.1) json csv (3.3.4) - drb (2.2.3) em-websocket (0.5.3) eventmachine (>= 0.12.9) http_parser.rb (~> 0) @@ -148,7 +132,6 @@ GEM metrics (0.12.2) mini_racer (0.18.1) libv8-node (~> 23.6.1.0) - minitest (5.25.5) nokogiri (1.18.9-aarch64-linux-gnu) racc (~> 1.4) nokogiri (1.18.9-aarch64-linux-musl) @@ -202,7 +185,6 @@ GEM google-protobuf (~> 4.31) sass-embedded (1.89.0-x86_64-linux-musl) google-protobuf (~> 4.31) - securerandom (0.4.1) terminal-table (3.0.2) unicode-display_width (>= 1.1.1, < 3) traces (0.15.2) @@ -213,10 +195,7 @@ GEM bigdecimal (~> 3.1) typhoeus (1.4.1) ethon (>= 0.9.0) - tzinfo (2.0.6) - concurrent-ruby (~> 1.0) unicode-display_width (2.6.0) - uri (1.0.3) webrick (1.9.1) yell (2.2.2) zeitwerk (2.7.3) @@ -236,7 +215,6 @@ PLATFORMS x86_64-linux-musl DEPENDENCIES - activesupport html-proofer jekyll jekyll-feed diff --git a/_plugins/time_table_generator.rb b/_plugins/time_table_generator.rb index a0c48844..5c13dd18 100644 --- a/_plugins/time_table_generator.rb +++ b/_plugins/time_table_generator.rb @@ -1,6 +1,3 @@ -require 'active_support/core_ext/integer/time' -require 'active_support/core_ext/numeric/time' - module Jekyll module TimeTableGenerator # タイムテーブル表を事前に計算してイベント表形式に変換 From dc7d66c822605219dca0c0464a545c9c85de9b29 Mon Sep 17 00:00:00 2001 From: Fukusan64 Date: Wed, 10 Sep 2025 01:29:51 +0900 Subject: [PATCH 08/13] =?UTF-8?q?=E8=89=B2=E3=80=85=E8=AA=BF=E6=95=B4?= =?UTF-8?q?=E3=81=97=E3=81=A6=E3=81=BF=E3=81=9F(=E3=83=8A=E3=83=93?= =?UTF-8?q?=E3=83=90=E3=83=BC=E3=81=A8=E7=9B=B8=E6=80=A7=E3=81=8C=E6=82=AA?= =?UTF-8?q?=E3=81=84...)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- _pages/time-table.html | 16 ++++++------ _sass/pages/time-table.scss | 52 +++++-------------------------------- 2 files changed, 15 insertions(+), 53 deletions(-) diff --git a/_pages/time-table.html b/_pages/time-table.html index e87ea4b9..36ac73de 100644 --- a/_pages/time-table.html +++ b/_pages/time-table.html @@ -17,20 +17,18 @@ {% assign total_slots = tte.total_slots %} {% assign total_rooms = tte.total_rooms %} -
+

Time table タイムテーブル

- -
+
- - + {% comment %} ルーム単位でヘッダーを描画 {% endcomment %} {% for room in rooms %} @@ -64,9 +62,11 @@

rowspan="{{ event.duration }}" style="--span: {{ event.duration }};">
-
{{ event.start }}–{{ event.end }}
-
{{ event.title }}
- {% if event.subtitle %}
{{ event.subtitle }}
{% endif %} +
+
{{ event.start }}–{{ event.end }}
+
{{ event.title }}
+ {% if event.subtitle %}
{{ event.subtitle }}
{% endif %} +
{% if event.badge %}{{ event.badge }}{% endif %} {% if event.note %}
{{ event.note }}
{% endif %}
diff --git a/_sass/pages/time-table.scss b/_sass/pages/time-table.scss index 6664111d..c94db8f3 100644 --- a/_sass/pages/time-table.scss +++ b/_sass/pages/time-table.scss @@ -1,23 +1,12 @@ -@use '../global/variables' as *; - -@media (max-width: 640px) { - :root, body { max-width: 100%; overflow-x: clip; } -} -@supports not (overflow-x: clip) { - @media (max-width: 640px) { :root, body { overflow-x: hidden; } } -} - /* ====== スクロール容器 ====== */ .ttable-wrap{ position: relative; width: 100%; max-width: 100%; overflow-x: auto; - overflow-y: visible; + overflow-y: auto; -webkit-overflow-scrolling: touch; - overscroll-behavior-x: contain; contain: content; - scrollbar-gutter: stable both-edges; } /* ====== テーブル ====== @@ -25,17 +14,12 @@ table-layout: auto と最小幅制約を組み合わせる */ .ttable{ - --w-start: 8ch; - --room-min: 20rem; + table-layout: fixed; + --w-start: 5rem; + --room-min: clamp(235px, calc((100dvw - var(--w-start) - 10rem)), 20rem); --row-h: 56px; width: calc(var(--w-start) + var(--room-min) * var(--room-count)); - min-width: 100%; - border-collapse: separate; - border-spacing: 0; - table-layout: auto; - background: #fff; - border: 1px solid #e6e6e9; } /* ヘッダー */ @@ -59,9 +43,9 @@ /* 会場ヘッダーと本文セルの最小幅をそろえる(PCで潰れない) */ .ttable__th--room{ border-left: 1px solid #ececf1; color:#111; background: linear-gradient(0deg, rgba(255,255,255,0.88), rgba(255,255,255,0.88)), var(--room-color, #c43b3b); - min-width: var(--room-min); + width: var(--room-min); } -.ttable tbody td{ min-width: var(--room-min); } +.ttable tbody td{ width: var(--room-min); } /* 行ストライプ & グリッド線 */ .ttable tbody tr{ height: var(--row-h); } @@ -111,35 +95,13 @@ box-shadow: 0 2px 8px rgba(0,0,0,0.06); padding: 10px 12px 12px; background: #fff; - overflow: hidden; height: 100%; display: flex; flex-direction: column; + overflow: clip; } .ttable__event::before{ content:""; position:absolute; inset:0 0 auto 0; height: 6px; background: var(--accent, #c43b3b); } .ttable__event-time{ font-weight: 800; font-size: 1.05rem; letter-spacing: .3px; margin: 8px 0 4px; color: #c43b3b; } .ttable__event-title{ font-weight: 800; line-height: 1.35; margin-bottom: 4px; color: #121212; } .ttable__event-subtitle{ color: #ee7d05; font-weight: 700; font-size: .92rem; line-height: 1.3; } .ttable__badge{ position: absolute; top: 8px; right: 10px; padding: 2px 8px; border-radius: 999px; font-size: .85rem; font-weight: 800; color: #fff; background: var(--accent,#c43b3b); box-shadow: 0 1px 4px rgba(0,0,0,.1); } - -/* スマホ微調整 */ -@media (max-width: 640px){ - .ttable{ --row-h: 54px; --room-min: 16rem; --w-start: 7ch; } - .ttable thead th, .ttable__cell{ padding: 8px; font-size: .95rem; } - .ttable thead th{ white-space: normal; } - .ttable__room-cap{ overflow-wrap: anywhere; word-break: keep-all; } - .ttable tbody tr:nth-child(6n){ - box-shadow: inset 0 -1.5px 0 rgba(0,0,0,0.18); - } - .ttable-wrap::before, .ttable-wrap::after{ - content: ""; position: absolute; top: 0; bottom: 0; width: 18px; - pointer-events: none; z-index: 6; - } - .ttable-wrap::before{ left: 0; background: linear-gradient(to right, #fff, rgba(255,255,255,0)); } - .ttable-wrap::after{ right: 0; background: linear-gradient(to left, #fff, rgba(255,255,255,0)); } - .ttable tbody tr{ background-image: linear-gradient(to right, rgba(0,0,0,0.08) 50%, rgba(0,0,0,0) 0); } - .ttable__event-time{ font-size: 1rem; margin-top: 6px; } - .ttable__event-title{ font-size: .98rem; } - .ttable__event-subtitle{ font-size: .86rem; } -} - From 3bf2ce71610c21c9e81af5ffba59afda9f2f4b17 Mon Sep 17 00:00:00 2001 From: Yohei Yasukawa Date: Wed, 10 Sep 2025 23:39:17 +0900 Subject: [PATCH 09/13] =?UTF-8?q?fix:=20=E3=82=BF=E3=82=A4=E3=83=A0?= =?UTF-8?q?=E3=83=86=E3=83=BC=E3=83=96=E3=83=AB=E3=81=AE=E6=A8=AA=E3=82=B9?= =?UTF-8?q?=E3=82=AF=E3=83=AD=E3=83=BC=E3=83=AB=E3=81=AE=E3=81=BF=E5=8F=AF?= =?UTF-8?q?=E8=83=BD=E3=81=AB=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - テーブル内部での縦スクロールを無効化 - (他ページ同様の) 縦スクロールに変更 --- _pages/time-table.html | 10 ++++------ _sass/pages/time-table.scss | 4 +++- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/_pages/time-table.html b/_pages/time-table.html index 36ac73de..3d6b1037 100644 --- a/_pages/time-table.html +++ b/_pages/time-table.html @@ -22,7 +22,7 @@

Time table タイムテーブル

-
+

{{ site.date_event }} のタイムテーブル
時間
{{ site.date_event }} のタイムテーブル @@ -62,11 +62,9 @@

rowspan="{{ event.duration }}" style="--span: {{ event.duration }};">
-
-
{{ event.start }}–{{ event.end }}
-
{{ event.title }}
- {% if event.subtitle %}
{{ event.subtitle }}
{% endif %} -
+
{{ event.start }}–{{ event.end }}
+
{{ event.title }}
+ {% if event.subtitle %}
{{ event.subtitle }}
{% endif %} {% if event.badge %}{{ event.badge }}{% endif %} {% if event.note %}
{{ event.note }}
{% endif %}
diff --git a/_sass/pages/time-table.scss b/_sass/pages/time-table.scss index c94db8f3..053d5616 100644 --- a/_sass/pages/time-table.scss +++ b/_sass/pages/time-table.scss @@ -4,9 +4,11 @@ width: 100%; max-width: 100%; overflow-x: auto; - overflow-y: auto; + overflow-y: visible; -webkit-overflow-scrolling: touch; + overscroll-behavior-x: contain; contain: content; + scrollbar-gutter: stable both-edges; } /* ====== テーブル ====== From b71a202138669cdbeb45d619c0d4b48fc6fdaf6e Mon Sep 17 00:00:00 2001 From: kp54 Date: Thu, 11 Sep 2025 00:43:51 +0900 Subject: [PATCH 10/13] =?UTF-8?q?time=5Ftable.yml=20=E3=81=AE=E3=82=B3?= =?UTF-8?q?=E3=83=B3=E3=83=86=E3=83=B3=E3=83=84=E3=82=92=E6=95=B4=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- _data/time_table.yml | 131 ++++++++++++++++++++++++------------------- 1 file changed, 74 insertions(+), 57 deletions(-) diff --git a/_data/time_table.yml b/_data/time_table.yml index d6412a0c..37b04cb6 100644 --- a/_data/time_table.yml +++ b/_data/time_table.yml @@ -1,127 +1,144 @@ slot_minutes: 10 rooms: - - 大会議室(セッション) - - 展示(コンテスト用) + - 大会議室 (セッション) + - 展示 (コンテスト用) - 展示 - - 中会議室(WS1 電子工作) - - 中会議室(WS2)LTブース - - 中会議室(WS3 ) - - 中会議室(WS4) + - 中会議室 (WS1 電子工作) + - 中会議室 (WS2 LTブース) + - 中会議室 (WS3) + - 中会議室 (WS4) room_styles: - 大会議室(セッション): { color: "#c43b3b" } - 展示(コンテスト用): { color: "#f5a201" } - 展示: { color: "#888888" } - 中会議室(WS1 電子工作): { color: "#2e7d32" } - 中会議室(WS2)LTブース: { color: "#1976d2" } - 中会議室(WS3 ): { color: "#7b1fa2" } - 中会議室(WS4): { color: "#ef6c00" } + 大会議室 (セッション): { color: "#c43b3b" } + 展示 (コンテスト用): { color: "#f5a201" } + 展示: { color: "#888888" } + 中会議室 (WS1 電子工作): { color: "#2e7d32" } + 中会議室 (WS2 LTブース): { color: "#1976d2" } + 中会議室 (WS3): { color: "#7b1fa2" } + 中会議室 (WS4): { color: "#ef6c00" } events: - # ── 大会議室(セッション) - - room: 大会議室(セッション) + # 大会議室 (セッション) + - room: "大会議室 (セッション)" start: "10:00" end: "10:10" title: "開会式" - - room: 大会議室(セッション) + + - room: "大会議室 (セッション)" start: "10:10" end: "10:20" - title: "基調講演(宮島さん)" - - room: 大会議室(セッション) + title: "基調講演 (宮島さん)" + + - room: "大会議室 (セッション)" start: "11:00" end: "12:00" title: "コンテスト作品発表" - - room: 大会議室(セッション) + + - room: "大会議室 (セッション)" start: "12:00" end: "12:40" title: "ランチタイム" - note: "適宜お昼をお取りください" - - room: 大会議室(セッション) + note: "適宜お昼をお取りください" + + - room: "大会議室 (セッション)" start: "12:40" end: "13:00" title: "みんなのセッション" - - room: 大会議室(セッション) + + - room: "大会議室 (セッション)" start: "13:40" end: "14:00" title: "九州チャンピオン座談会" - - room: 大会議室(セッション) + + - room: "大会議室 (セッション)" start: "14:20" end: "14:40" - title: "スピーカーセッション_とり子さん(20分)" - - room: 大会議室(セッション) + title: "スピーカーセッション とり子さん (20分)" + + - room: 大会議室 (セッション) start: "14:40" end: "14:50" title: "伸びるかも予備" - - room: 大会議室(セッション) + + - room: "大会議室 (セッション)" start: "14:50" end: "15:10" - title: "スピーカーセッション_早良区Dojoチャンピオン(20分)" - - room: 大会議室(セッション) + title: "スピーカーセッション 早良区Dojoチャンピオン (20分)" + + - room: "大会議室 (セッション)" start: "15:10" end: "15:20" - title: "スポンサーセッション(2件)" - - room: 大会議室(セッション) + title: "スポンサーセッション (2件)" + + - room: "大会議室 (セッション)" start: "15:20" end: "15:30" - title: "招待講演(小宮山さん)" - - room: 大会議室(セッション) + title: "招待講演 (小宮山さん)" + + - room: "大会議室 (セッション)" start: "16:00" end: "16:10" title: "コンテスト結果発表" - - room: 大会議室(セッション) + + - room: "大会議室 (セッション)" start: "16:10" end: "16:20" - title: "スポンサーセッション(1件)" - note: "該当なしの場合はCoderDojo Japan活動報告" - - room: 大会議室(セッション) + title: "スポンサーセッション (1件)" + note: "該当なしの場合は CoderDojo Japan 活動報告" + + - room: "大会議室 (セッション)" start: "16:20" end: "16:30" title: "閉会式" - # ── 展示 - - room: 展示(コンテスト用) + # 展示 + - room: "展示 (コンテスト用)" start: "10:00" end: "16:00" title: "ファイナリスト作品展示" - note: "14:00 投票締切" - - room: 展示 + note: "14:00 投票締切" + + - room: "展示" start: "10:00" end: "16:00" title: "展示" - # ── WS1 電子工作(随時受付) - - room: 中会議室(WS1 電子工作) + # WS1 電子工作 (随時受付) + - room: "中会議室 (WS1 電子工作)" start: "11:00" end: "16:00" - title: "電子工作ワークショップ(随時受付)" + title: "電子工作ワークショップ (随時受付)" - # ── WS2 LTブース - - room: 中会議室(WS2)LTブース + # WS2 LTブース + - room: "中会議室 (WS2 LTブース)" start: "11:20" end: "12:00" - title: "Dojo関係者等大人LT(要申込)" - - room: 中会議室(WS2)LTブース + title: "Dojo関係者等大人LT (要申込)" + + - room: "中会議室 (WS2 LTブース)" start: "13:00" end: "14:00" - title: "DojoニンジャLT(要申込)" + title: "DojoニンジャLT (要申込)" - # ── WS3 - - room: 中会議室(WS3 ) + # WS3 + - room: "中会議室 (WS3)" start: "11:00" end: "12:00" - title: "ブレンダー(要申込)" - - room: 中会議室(WS3 ) + title: "ブレンダー (要申込)" + + - room: "中会議室 (WS3)" start: "13:00" end: "14:00" title: "PLAYRISE" - # ── WS4 - - room: 中会議室(WS4) + # WS4 + - room: "中会議室 (WS4)" start: "11:00" end: "12:00" - title: "PowerPointとプログラミング" - - room: 中会議室(WS4) + title: "PowerPoint とプログラミング" + + - room: "中会議室 (WS4)" start: "14:10" end: "15:00" - title: "PowerPointとプログラミング" \ No newline at end of file + title: "PowerPoint とプログラミング" From 847d7ea98562a86c6131288af84f3c8fa9724cda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=9F=E3=81=8F=E3=82=84?= Date: Thu, 11 Sep 2025 10:39:32 +0900 Subject: [PATCH 11/13] =?UTF-8?q?fix:=20=E6=97=A5=E4=BB=98=E6=83=85?= =?UTF-8?q?=E5=A0=B1=E3=82=92=E6=B6=88=E5=8E=BB=E3=81=97=E3=81=9F=E3=81=AE?= =?UTF-8?q?=E3=81=A8,=20=E7=B8=A6=E6=96=B9=E5=90=91=E3=81=AEsticky?= =?UTF-8?q?=E3=82=92=E6=B6=88=E5=8E=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- _pages/time-table.html | 5 +---- _sass/pages/time-table.scss | 1 - 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/_pages/time-table.html b/_pages/time-table.html index 3d6b1037..4c06d184 100644 --- a/_pages/time-table.html +++ b/_pages/time-table.html @@ -24,11 +24,8 @@

- - + {% comment %} ルーム単位でヘッダーを描画 {% endcomment %} {% for room in rooms %} diff --git a/_sass/pages/time-table.scss b/_sass/pages/time-table.scss index 053d5616..d99da87d 100644 --- a/_sass/pages/time-table.scss +++ b/_sass/pages/time-table.scss @@ -31,7 +31,6 @@ padding: 10px 12px; } .ttable thead th{ - position: sticky; top: 0; z-index: 3; background: #fafafa; border-bottom: 1px solid #e6e6e9; padding: 10px 12px; From 4214bbc78299be79ebfbe81187e64ada6b85f5cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=9F=E3=81=8F=E3=82=84?= Date: Thu, 11 Sep 2025 10:49:56 +0900 Subject: [PATCH 12/13] =?UTF-8?q?feat:=20=E3=82=A4=E3=83=99=E3=83=B3?= =?UTF-8?q?=E3=83=88=E3=81=AE=E3=83=AA=E3=83=B3=E3=82=AF=E5=AF=BE=E5=BF=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- _data/time_table.yml | 2 ++ _pages/time-table.html | 22 +++++++++++++++------- _sass/pages/time-table.scss | 3 +++ 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/_data/time_table.yml b/_data/time_table.yml index 37b04cb6..eb203ccb 100644 --- a/_data/time_table.yml +++ b/_data/time_table.yml @@ -29,6 +29,7 @@ events: start: "10:10" end: "10:20" title: "基調講演 (宮島さん)" + link: "/sessions/keynote1/" - room: "大会議室 (セッション)" start: "11:00" @@ -75,6 +76,7 @@ events: start: "15:20" end: "15:30" title: "招待講演 (小宮山さん)" + link: "/sessions/keynote2/" - room: "大会議室 (セッション)" start: "16:00" diff --git a/_pages/time-table.html b/_pages/time-table.html index 4c06d184..c2881e0d 100644 --- a/_pages/time-table.html +++ b/_pages/time-table.html @@ -58,13 +58,21 @@

{% else %} {% comment %} イベント無し {% endcomment %} diff --git a/_sass/pages/time-table.scss b/_sass/pages/time-table.scss index d99da87d..5b29d230 100644 --- a/_sass/pages/time-table.scss +++ b/_sass/pages/time-table.scss @@ -100,7 +100,10 @@ display: flex; flex-direction: column; overflow: clip; + text-decoration: none; + color: inherit; } +.ttable__event[href]{ cursor: pointer; } .ttable__event::before{ content:""; position:absolute; inset:0 0 auto 0; height: 6px; background: var(--accent, #c43b3b); } .ttable__event-time{ font-weight: 800; font-size: 1.05rem; letter-spacing: .3px; margin: 8px 0 4px; color: #c43b3b; } .ttable__event-title{ font-weight: 800; line-height: 1.35; margin-bottom: 4px; color: #121212; } From ea321c806b5c4e8413df27706229b0f439cd4505 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=9F=E3=81=8F=E3=82=84?= Date: Thu, 11 Sep 2025 10:54:39 +0900 Subject: [PATCH 13/13] =?UTF-8?q?fix:=20=E3=83=AA=E3=83=B3=E3=82=AF?= =?UTF-8?q?=E3=81=8C=E3=81=82=E3=82=8B=E3=82=A4=E3=83=99=E3=83=B3=E3=83=88?= =?UTF-8?q?=E3=81=8C=E3=82=AF=E3=83=AA=E3=83=83=E3=82=AF=E3=81=A7=E3=81=8D?= =?UTF-8?q?=E3=81=AA=E3=81=84=E5=95=8F=E9=A1=8C=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- _pages/time-table.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/_pages/time-table.html b/_pages/time-table.html index c2881e0d..abd65fc6 100644 --- a/_pages/time-table.html +++ b/_pages/time-table.html @@ -54,7 +54,8 @@

{% elsif event %} {% comment %} イベントを描画 {% endcomment %} {% assign accent = event.accent | default: room.style.color | default: '#c43b3b' %} - + {% assign link_url = event.url | default: event.link %} +

- {{ site.date_event }} のタイムテーブル -
時間 -
-
{{ event.start }}–{{ event.end }}
-
{{ event.title }}
- {% if event.subtitle %}
{{ event.subtitle }}
{% endif %} - {% if event.badge %}{{ event.badge }}{% endif %} - {% if event.note %}
{{ event.note }}
{% endif %} -
+ {% if link_url %} + + {% else %} + + {% endif %}