インタラクティブペーパー
📄 Interactive Paper とは
Interactive Paper は
「文章 × アウトライン構造 × チェックリスト」
を組み合わせて整理できる、Web ベースのドキュメントツールです。
なお、ローカルで動作します。
使い方としては、生成AIにプロンプトを渡して、やることなどをインタラクティブペーパー用としてJSONを生成させて、インタラクティブペーパー(HTML)に取り込んでつかいます。なお、一から手入力でも使用するとは可能です。
/icons/hr.icon
✨ 特徴
セクション(H2)・小見出し(H3)で階層構造を整理できる
各階層ごとに本文(テキスト)を保持できる
チェックリスト(ToDo)を自由に追加
セクション/小見出し/項目をドラッグ&ドロップで並び替え
JSON 形式で保存・復元が可能
ブラウザのローカルストレージに自動保存
進捗率(達成率)を自動計算して表示
セクションを折りたたみ可能
セクション移動ボタン(↑↓)でワンタッチ並び替えも可
/icons/hr.icon
🔧 データ構造(JSON Schema)
Interactive Paper の保存形式は以下の JSON。
code:JSON
{
"schemaVersion": 3,
"title": "文書タイトル",
"sections": [
{
"id": "sec-xxxxxxx",
"title": "セクションタイトル",
"text": "本文テキスト",
"checklist": [
{
"id": "chk-xxxxxxx",
"text": "項目",
"checked": false
}
],
"subsections": [
{
"id": "sub-xxxxxxx",
"title": "小見出しタイトル",
"text": "テキスト",
"checklist": [
{
"id": "chk-yyyyyyy",
"text": "項目",
"checked": true
}
]
}
]
}
]
}
※ID はランダム生成(sec / sub / chk)
/icons/hr.icon
📂 階層構造
Interactive Paper の構造は 3 層。
code:txt
Section(H2)
├─ 本文
├─ Checklist(項目)
└─ Subsection(H3)
├─ 本文
└─ Checklist
※ID はランダム生成(sec / sub / chk)
/icons/hr.icon
🖱 操作方法
セクション追加
画面上部の
「+ セクション追加」
ボタンから作成。
小見出し追加
各セクションの右上にある
「+ 小見出し」
ボタン。
チェック項目追加
セクション直下 →「+ 項目」
小見出し内部 →「+ 項目」
並び替え(DnD)
セクション(H2)単位
小見出し(H3)単位
チェック項目(li)は
セクションを跨いで移動可
かつ
H2 → H3 / H3 → H2 どちらにも移動可
保存
ローカルストレージに自動保存
「JSON 書き出し」でファイルとして保存
「JSON 読み込み」で復元
/icons/hr.icon
📊 進捗バー(自動)
各セクションに進捗バーが付きます。
code:txt
計算方法:
code:txt
checked / total * 100
小見出し内の項目も含めて計算。
/icons/hr.icon
🔽 セクション折りたたみ
セクションタイトル横の
「▼」「▶」アイコン
で開閉できます。
/icons/hr.icon
↕ セクション移動ボタン
GUI でセクションを楽に上下移動できる。
code:txt
↑ ↓
/icons/hr.icon
🚀 こんな用途に向く
プロジェクト管理
会議議事録 + ToDo
研修資料
作業手順書
読書メモ
学習ログ
ライティング構成の下書き
/icons/hr.icon
✅ コピペ用:Interactive Paper JSON 生成プロンプト(完全版)
生成AIがインタラクティブペーパー用のJSONを生成するためのプロンプトです。
code:txt
あなたは「Interactive Paper」というアウトライン構造を持つドキュメントの **JSON データを作成するアシスタント** です。
以下のルールに従い、ユーザー入力から **完全に正しい JSON だけ** を生成してください。
---
## 【出力フォーマット】
出力は必ず次の JSON 構造に従うこと:
`json
{
"schemaVersion": 3,
"title": "文書タイトル",
"sections": [
{
"id": "sec-xxxxxxx",
"title": "セクションタイトル",
"text": "本文テキスト",
"checklist": [
{
"id": "chk-xxxxxxx",
"text": "項目",
"checked": false
}
],
"subsections": [
{
"id": "sub-xxxxxxx",
"title": "小見出しタイトル",
"text": "本文テキスト",
"checklist": [
{
"id": "chk-yyyyyyy",
"text": "項目",
"checked": false
}
]
}
]
}
]
}
`
---
## 【ID 形式ルール】
ID は以下の形式でランダム生成する:
- Section → "sec-" + 7文字の英数字
- Subsection → "sub-" + 7文字の英数字
- Checklist → "chk-" + 7文字の英数字
例:
- sec-a91k20d
- sub-h28da91
- chk-k391jd0
---
## 【構造ルール】
- sections[] の数はユーザー指示通り
- checklist[] と subsections[] は空でも配列を残す
- 階層は
**section → subsection → checklist**
の順で固定
- 不要なプロパティは追加禁止
(例:timestamp, note, priority 等)
---
## 【あなたの作業】
ユーザーのテキストを:
1. セクション
2. 小見出し
3. チェック項目
4. 本文
に分類し、
**上記フォーマットの JSON に変換して出力する。**
---
## 【回答形式】
**回答は JSON のみ。説明文は一切禁止。**
---
以上のルールに従って JSON を生成してください。
📃インタラクティブペーパーの構成
インタラクティブペーパーの構成は次のとおりです。
main.html、interactive-paper.css、interactive-paper.jsを同じフォルダに入れて使用してください。
code:txt
インタラクティブペーパー
├─ main.html
├─ interactive-paper.css
└─ interactive-paper.js
main.html
code:html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<title>Interactive Paper</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="interactive-paper.css" />
</head>
<body>
<header class="top-bar">
<div class="title-wrap">
<h1 id="page-title" contenteditable="true">インタラクティブ・ペーパー</h1>
</div>
<div class="top-controls">
<button id="add-section" type="button">+ セクション追加</button>
<button id="export-json" type="button">JSON書き出し</button>
<button id="import-json" type="button">JSON読み込み</button>
<input id="json-file-input" type="file" accept="application/json" style="display:none" />
</div>
</header>
<main class="main-area">
<div id="sections"></div>
</main>
<script src="interactive-paper.js"></script>
</body>
</html>
interactive-paper.css
code:css
/* 全体レイアウト */
body {
margin: 0;
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}
.top-bar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 8px 16px;
position: sticky;
top: 0;
z-index: 10;
}
.title-wrap h1 {
margin: 0;
font-size: 20px;
}
outline: none;
border-bottom: 1px dashed rgba(255, 255, 255, 0.4);
}
.top-controls {
display: flex;
gap: 8px;
}
.top-controls button {
padding: 4px 10px;
font-size: 13px;
border-radius: 4px;
border: none;
cursor: pointer;
}
}
}
}
/* メインエリア */
.main-area {
max-width: 960px;
margin: 16px auto 40px;
padding: 0 12px;
}
display: flex;
flex-direction: column;
gap: 12px;
}
/* セクション */
.section {
border-radius: 8px;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
padding: 8px 12px 10px;
}
.section.dragging {
opacity: 0.5;
border-style: dashed;
}
.section-header {
display: flex;
justify-content: space-between;
align-items: center;
gap: 6px;
}
.section-title {
margin: 0;
font-size: 18px;
}
outline: none;
padding: 2px 4px;
border-radius: 4px;
}
}
.section-tools {
display: flex;
align-items: center;
gap: 4px;
}
.section-tools button {
padding: 2px 6px;
font-size: 11px;
border-radius: 4px;
cursor: pointer;
}
/* 折りたたみボタン */
.section-tools .toggle-fold {
font-size: 14px;
font-weight: bold;
padding: 2px 6px;
}
/* セクション移動ボタン */
.section-tools .move-up,
.section-tools .move-down {
padding: 2px 6px;
font-size: 11px;
}
/* セクション本文 */
.section-body {
margin-top: 6px;
}
/* 折りたたみ状態 */
.section.collapsed .section-body {
display: none;
}
/* 進捗バー */
.progress-bar-wrap {
width: 100%;
height: 6px;
border-radius: 999px;
margin: 4px 0 8px;
overflow: hidden;
}
.progress-bar {
height: 6px;
width: 0%;
border-radius: 999px;
transition: width 0.2s ease-out, background-color 0.2s ease-out;
}
/* 本文テキスト */
.section-text {
padding: 4px 6px;
border-radius: 4px;
min-height: 20px;
margin-bottom: 6px;
}
outline: none;
}
}
/* チェックリスト */
.checklist {
list-style: none;
padding-left: 0;
margin: 4px 0 4px;
}
.checklist li {
display: flex;
align-items: center;
gap: 4px;
padding: 2px 4px;
border-radius: 4px;
}
.checklist li.dragging {
opacity: 0.5;
}
.check-main {
display: flex;
align-items: center;
flex: 1;
gap: 6px;
}
transform: scale(1.1);
}
.item-text {
flex: 1;
min-height: 18px;
padding: 2px 4px;
border-radius: 3px;
}
outline: none;
}
}
.id-note {
font-size: 10px;
}
.delete-item {
border: none;
background: transparent;
cursor: pointer;
font-size: 12px;
}
/* 小見出し */
.subsections {
margin-top: 6px;
border-top: 1px dashed #ddd; padding-top: 4px;
}
.subsection {
border-radius: 6px;
padding: 4px 6px;
margin-top: 4px;
}
.subsection.dragging {
opacity: 0.5;
border-style: dashed;
}
.subsection-title {
margin: 0 0 2px;
font-size: 15px;
}
outline: none;
border-radius: 4px;
padding: 1px 3px;
}
}
.subsection-tools {
margin-top: 4px;
display: flex;
justify-content: flex-end;
gap: 4px;
}
.subsection-tools button {
padding: 2px 6px;
font-size: 11px;
border-radius: 4px;
cursor: pointer;
}
interactive-paper.js
code:js
/* =========================================================
Interactive Paper - フルリセット版(DnD + 折りたたみ + 進捗バー + 移動ボタン)
========================================================= */
/* ------------------------------
ユーティリティ
------------------------------ */
const qs = (sel, base = document) => base.querySelector(sel);
/* ローカルストレージキー */
const STORAGE_KEY = "interactivePaper_v3";
/* データモデル */
let paperData = {
schemaVersion: 3,
title: "タイトル",
sections: [] // {id, title, text, checklist[], subsections[], collapsed?}
};
/* ------------------------------
ID 生成
------------------------------ */
function genId(prefix) {
return prefix + "-" + Math.random().toString(36).slice(2, 9);
}
/* ------------------------------
ローカルストレージ 保存
------------------------------ */
function saveToLocal() {
try {
const json = JSON.stringify(paperData, null, 2);
localStorage.setItem(STORAGE_KEY, json);
console.log("保存しました");
} catch (e) {
console.error("保存失敗:", e);
}
}
/* ------------------------------
ローカルストレージ 読込
------------------------------ */
function loadFromLocal() {
const saved = localStorage.getItem(STORAGE_KEY);
if (!saved) return;
try {
const data = JSON.parse(saved);
applyLoadedJSON(data);
} catch (e) {
console.error("読み込み失敗:", e);
}
}
/* ------------------------------
JSON を適用
------------------------------ */
function applyLoadedJSON(data) {
if (!data || typeof data !== "object") return;
paperData = {
schemaVersion: 3,
title: data.title || "タイトル",
sections: Array.isArray(data.sections) ? data.sections : []
};
qs("#page-title").textContent = paperData.title;
document.title = paperData.title || "Interactive Paper";
renderSections();
attachEditEvents();
}
/* ------------------------------
debounce 保存
------------------------------ */
let debounceTimer = null;
function debounceSave() {
clearTimeout(debounceTimer);
debounceTimer = setTimeout(() => {
collectAllData();
saveToLocal();
updateAllProgressBars();
}, 300);
}
/* =========================================================
描画処理
========================================================= */
/* すべてのセクション描画 */
function renderSections() {
const container = qs("#sections");
if (!container) return;
container.innerHTML = "";
(paperData.sections || []).forEach(secData => {
const el = renderOneSection(secData);
container.appendChild(el);
});
updateAllProgressBars();
}
/* セクション 1 つ描画 */
function renderOneSection(secData) {
if (!secData.id) secData.id = genId("sec");
const section = document.createElement("section");
section.className = "section";
section.dataset.secId = secData.id;
section.dataset.dnd = "section";
section.draggable = true;
if (secData.collapsed) {
section.classList.add("collapsed");
}
// ヘッダ
const header = document.createElement("div");
header.className = "section-header";
const h2 = document.createElement("h2");
h2.className = "section-title";
h2.contentEditable = "true";
h2.textContent = secData.title || "新しいセクション";
const tools = document.createElement("div");
tools.className = "section-tools";
// 折りたたみボタン
const foldBtn = document.createElement("button");
foldBtn.className = "toggle-fold";
foldBtn.type = "button";
foldBtn.textContent = secData.collapsed ? "?" : "▼";
const btnAddCheck = document.createElement("button");
btnAddCheck.className = "add-check-h2";
btnAddCheck.type = "button";
btnAddCheck.textContent = "+ 項目";
const btnAddSub = document.createElement("button");
btnAddSub.className = "add-subsection";
btnAddSub.type = "button";
btnAddSub.textContent = "+ 小見出し";
const btnUp = document.createElement("button");
btnUp.className = "move-up";
btnUp.type = "button";
btnUp.textContent = "↑";
const btnDown = document.createElement("button");
btnDown.className = "move-down";
btnDown.type = "button";
btnDown.textContent = "↓";
const btnDelSec = document.createElement("button");
btnDelSec.className = "delete-section";
btnDelSec.type = "button";
btnDelSec.textContent = "× セクション削除";
tools.append(foldBtn, btnAddCheck, btnAddSub, btnUp, btnDown, btnDelSec);
header.append(h2, tools);
// 本文
const body = document.createElement("div");
body.className = "section-body";
// 進捗バー
const progressWrap = document.createElement("div");
progressWrap.className = "progress-bar-wrap";
const progressBar = document.createElement("div");
progressBar.className = "progress-bar";
progressWrap.append(progressBar);
const textDiv = document.createElement("div");
textDiv.className = "section-text";
textDiv.contentEditable = "true";
textDiv.textContent = secData.text || "";
// H2直下チェックリスト
const ulH2 = document.createElement("ul");
ulH2.className = "checklist";
ulH2.dataset.scope = "h2";
(secData.checklist || []).forEach(item => {
const li = createChecklistItem(item);
ulH2.appendChild(li);
});
// 小見出しコンテナ
const subsWrap = document.createElement("div");
subsWrap.className = "subsections";
(secData.subsections || []).forEach(sub => {
const subEl = renderOneSubsection(sub);
subsWrap.appendChild(subEl);
});
body.append(progressWrap, textDiv, ulH2, subsWrap);
section.append(header, body);
return section;
}
/* 小見出し描画 */
function renderOneSubsection(subData) {
if (!subData.id) subData.id = genId("sub");
const wrap = document.createElement("div");
wrap.className = "subsection";
wrap.dataset.subId = subData.id;
wrap.dataset.dnd = "subsection";
wrap.draggable = true;
const h3 = document.createElement("h3");
h3.className = "subsection-title";
h3.contentEditable = "true";
h3.textContent = subData.title || "小見出し";
const textDiv = document.createElement("div");
textDiv.className = "section-text";
textDiv.contentEditable = "true";
textDiv.textContent = subData.text || "";
const ul = document.createElement("ul");
ul.className = "checklist";
ul.dataset.scope = "h3";
(subData.checklist || []).forEach(item => {
const li = createChecklistItem(item);
ul.appendChild(li);
});
const tools = document.createElement("div");
tools.className = "subsection-tools";
const btnAddCheck = document.createElement("button");
btnAddCheck.className = "add-check-h3";
btnAddCheck.type = "button";
btnAddCheck.textContent = "+ 項目";
const btnDelSub = document.createElement("button");
btnDelSub.className = "delete-subsection";
btnDelSub.type = "button";
btnDelSub.textContent = "× 小見出し削除";
tools.append(btnAddCheck, btnDelSub);
wrap.append(h3, textDiv, ul, tools);
return wrap;
}
/* チェックリストアイテム描画 */
function createChecklistItem(item) {
if (!item.id) item.id = genId("chk");
const li = document.createElement("li");
li.dataset.chkId = item.id;
li.dataset.dnd = "check";
li.draggable = true;
const main = document.createElement("div");
main.className = "check-main";
const input = document.createElement("input");
input.type = "checkbox";
input.checked = !!item.checked;
const textDiv = document.createElement("div");
textDiv.className = "item-text";
textDiv.contentEditable = "true";
textDiv.textContent = item.text || "";
main.append(input, textDiv);
const idSpan = document.createElement("span");
idSpan.className = "id-note";
idSpan.textContent = item.id;
const delBtn = document.createElement("button");
delBtn.className = "delete-item";
delBtn.title = "削除";
delBtn.type = "button";
delBtn.textContent = "×";
li.append(main, idSpan, delBtn);
return li;
}
/* =========================================================
DOM → paperData 反映
========================================================= */
function collectAllData() {
const titleEl = qs("#page-title");
paperData.title = (titleEl?.textContent || "タイトル").trim();
document.title = paperData.title || "Interactive Paper";
const sectionsWrap = qs("#sections");
if (!sectionsWrap) return;
const secEls = qsa(".section", sectionsWrap);
const sections = [];
secEls.forEach(secEl => {
const secId = secEl.dataset.secId || genId("sec");
const titleEl = qs(".section-title", secEl);
const bodyEl = qs(".section-body > .section-text", secEl);
const subsWrap = qs(".subsections", secEl);
const secObj = {
id: secId,
title: (titleEl?.textContent || "").trim(),
text: (bodyEl?.textContent || "").trim(),
checklist: [],
subsections: [],
collapsed: secEl.classList.contains("collapsed")
};
// H2 直下チェック
if (ulH2) {
qsa("li", ulH2).forEach(li => {
const chkId = li.dataset.chkId || genId("chk");
const textEl = qs(".item-text", li);
secObj.checklist.push({
id: chkId,
text: (textEl?.textContent || "").trim(),
checked: !!(input && input.checked)
});
});
}
// 小見出し
if (subsWrap) {
qsa(".subsection", subsWrap).forEach(subEl => {
const subId = subEl.dataset.subId || genId("sub");
const subTitleEl = qs(".subsection-title", subEl);
const subTextEl = qs(".section-text", subEl);
const subObj = {
id: subId,
title: (subTitleEl?.textContent || "").trim(),
text: (subTextEl?.textContent || "").trim(),
checklist: []
};
if (ulH3) {
qsa("li", ulH3).forEach(li => {
const chkId = li.dataset.chkId || genId("chk");
const textEl = qs(".item-text", li);
subObj.checklist.push({
id: chkId,
text: (textEl?.textContent || "").trim(),
checked: !!(input && input.checked)
});
});
}
secObj.subsections.push(subObj);
});
}
sections.push(secObj);
});
paperData.sections = sections;
}
/* =========================================================
進捗バー更新
========================================================= */
function updateAllProgressBars() {
qsa(".section").forEach(sec => {
const done = checks.filter(c => c.checked).length;
const all = checks.length || 1;
const percent = Math.round((done / all) * 100);
const bar = qs(".progress-bar", sec);
if (!bar) return;
bar.style.width = percent + "%";
// ざっくり色も変える
if (percent === 0) {
bar.style.backgroundColor = "#ef5350"; // 赤
} else if (percent < 50) {
bar.style.backgroundColor = "#ffb300"; // 黄
} else if (percent < 100) {
bar.style.backgroundColor = "#42a5f5"; // 青
} else {
bar.style.backgroundColor = "#66bb6a"; // 緑
}
});
}
/* =========================================================
編集系イベント(input / checkbox)
========================================================= */
function attachEditEvents() {
const container = qs("#sections");
if (!container) return;
// contenteditable
el.oninput = () => {
debounceSave();
};
});
// checkbox
chk.onchange = () => {
debounceSave();
};
});
updateAllProgressBars();
}
/* =========================================================
クリック系(追加・削除・折りたたみ・移動) - イベント委譲
========================================================= */
function setupClickHandlers() {
document.body.addEventListener("click", (e) => {
const btn = e.target.closest("button");
if (!btn) return;
// トップバー
if (btn.id === "add-section") {
handleAddSection();
return;
}
if (btn.id === "export-json") {
handleExportJSON();
return;
}
if (btn.id === "import-json") {
handleImportJSON();
return;
}
// 折りたたみ
if (btn.classList.contains("toggle-fold")) {
const sec = btn.closest(".section");
if (!sec) return;
sec.classList.toggle("collapsed");
btn.textContent = sec.classList.contains("collapsed") ? "?" : "▼";
debounceSave();
return;
}
// セクション ↑
if (btn.classList.contains("move-up")) {
const sec = btn.closest(".section");
if (!sec) return;
const prev = sec.previousElementSibling;
if (prev) prev.before(sec);
debounceSave();
return;
}
// セクション ↓
if (btn.classList.contains("move-down")) {
const sec = btn.closest(".section");
if (!sec) return;
const next = sec.nextElementSibling;
if (next) next.after(sec);
debounceSave();
return;
}
// 以下はセクション内の操作
if (btn.classList.contains("add-check-h2")) {
const secEl = btn.closest(".section");
if (!secEl) return;
if (!ul) return;
const li = createChecklistItem({ id: genId("chk"), text: "", checked: false });
ul.appendChild(li);
attachEditEvents();
debounceSave();
return;
}
if (btn.classList.contains("add-subsection")) {
const secEl = btn.closest(".section");
if (!secEl) return;
const subsWrap = qs(".subsections", secEl);
if (!subsWrap) return;
const subObj = {
id: genId("sub"),
title: "小見出し",
text: "",
checklist: []
};
const subEl = renderOneSubsection(subObj);
subsWrap.appendChild(subEl);
attachEditEvents();
debounceSave();
return;
}
if (btn.classList.contains("delete-section")) {
const secEl = btn.closest(".section");
if (!secEl) return;
secEl.remove();
debounceSave();
return;
}
if (btn.classList.contains("add-check-h3")) {
const subEl = btn.closest(".subsection");
if (!subEl) return;
if (!ul) return;
const li = createChecklistItem({ id: genId("chk"), text: "", checked: false });
ul.appendChild(li);
attachEditEvents();
debounceSave();
return;
}
if (btn.classList.contains("delete-subsection")) {
const subEl = btn.closest(".subsection");
if (!subEl) return;
subEl.remove();
debounceSave();
return;
}
if (btn.classList.contains("delete-item")) {
if (!li) return;
li.remove();
debounceSave();
return;
}
});
}
/* ------------------------------
トップバーの処理
------------------------------ */
function handleAddSection() {
const newSec = {
id: genId("sec"),
title: "新しいセクション",
text: "",
checklist: [],
subsections: [],
collapsed: false
};
paperData.sections.push(newSec);
renderSections();
attachEditEvents();
saveToLocal();
}
function handleExportJSON() {
collectAllData();
const blob = new Blob(
{ type: "application/json" }
);
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = (paperData.title || "interactive-paper") + ".json";
a.click();
URL.revokeObjectURL(url);
}
function handleImportJSON() {
const input = qs("#json-file-input");
if (!input) return;
input.value = "";
input.click();
input.onchange = () => {
const file = input.files0; if (!file) return;
const reader = new FileReader();
reader.onload = (e) => {
try {
const json = JSON.parse(e.target.result);
applyLoadedJSON(json);
saveToLocal();
} catch (err) {
alert("JSON の読み込みに失敗しました");
}
};
reader.readAsText(file, "utf-8");
};
}
/* =========================================================
DnD - セクション & 小見出し & チェックリスト
========================================================= */
let dragState = {
type: null, // "section" | "check" | "subsection"
elem: null
};
function setupDnD() {
const container = qs("#sections");
if (!container) return;
container.addEventListener("dragstart", onDragStart);
container.addEventListener("dragover", onDragOver);
container.addEventListener("drop", onDrop);
container.addEventListener("dragend", onDragEnd);
}
function onDragStart(e) {
const handle = e.target.closest("data-dnd"); if (!handle) return;
dragState.type = handle.dataset.dnd;
dragState.elem = handle;
e.dataTransfer.effectAllowed = "move";
e.dataTransfer.setData("text/plain", "");
handle.classList.add("dragging");
}
function onDragOver(e) {
if (!dragState.elem) return;
// チェック項目(どの checklist でもOK)
if (dragState.type === "check") {
const ul = e.target.closest("ul.checklist");
if (!li && !ul) return;
e.preventDefault();
e.dataTransfer.dropEffect = "move";
return;
}
const target = e.target.closest("data-dnd"); if (!target) return;
if (target === dragState.elem) return;
if (target.dataset.dnd !== dragState.type) return;
// section/subsection は同じ親コンテナ内のみ
if (dragState.type === "subsection") {
const originWrap = dragState.elem.closest(".subsections");
const targetWrap = target.closest(".subsections");
if (!originWrap || !targetWrap || originWrap !== targetWrap) return;
} else if (dragState.type === "section") {
const originParent = dragState.elem.parentElement;
const targetParent = target.parentElement;
if (!originParent || !targetParent || originParent !== targetParent) return;
}
e.preventDefault();
e.dataTransfer.dropEffect = "move";
}
function onDrop(e) {
if (!dragState.elem) return;
// チェック項目
if (dragState.type === "check") {
e.preventDefault();
e.stopPropagation();
const dragEl = dragState.elem;
let targetUl = null;
if (targetLi) {
targetUl = targetLi.closest("ul.checklist");
}
if (!targetUl) {
targetUl = e.target.closest("ul.checklist");
}
if (!targetUl) return;
const rect = targetLi ? targetLi.getBoundingClientRect() : null;
if (!targetLi) {
targetUl.appendChild(dragEl);
} else {
const isAfter = e.clientY > rect.top + rect.height / 2;
if (isAfter) {
targetUl.insertBefore(dragEl, targetLi.nextSibling);
} else {
targetUl.insertBefore(dragEl, targetLi);
}
}
debounceSave();
updateAllProgressBars();
return;
}
// セクション / サブセクション
const target = e.target.closest("data-dnd"); if (!target) return;
if (target === dragState.elem) return;
if (target.dataset.dnd !== dragState.type) return;
let parent = null;
if (dragState.type === "subsection") {
const originWrap = dragState.elem.closest(".subsections");
const targetWrap = target.closest(".subsections");
if (!originWrap || !targetWrap || originWrap !== targetWrap) return;
parent = originWrap;
} else if (dragState.type === "section") {
const originParent = dragState.elem.parentElement;
const targetParent = target.parentElement;
if (!originParent || !targetParent || originParent !== targetParent) return;
parent = originParent;
}
if (!parent) return;
const dragEl = dragState.elem;
const rect = target.getBoundingClientRect();
const isAfter = e.clientY > rect.top + rect.height / 2;
if (isAfter) {
parent.insertBefore(dragEl, target.nextSibling);
} else {
parent.insertBefore(dragEl, target);
}
debounceSave();
}
function onDragEnd() {
if (dragState.elem) {
dragState.elem.classList.remove("dragging");
}
dragState.type = null;
dragState.elem = null;
}
/* =========================================================
初期化
========================================================= */
window.addEventListener("DOMContentLoaded", () => {
const titleEl = qs("#page-title");
if (titleEl) {
titleEl.addEventListener("input", () => {
debounceSave();
});
}
setupClickHandlers();
setupDnD();
loadFromLocal();
if (paperData.sections.length === 0) {
paperData.sections.push({
id: genId("sec"),
title: "新しいセクション",
text: "",
checklist: [],
subsections: [],
collapsed: false
});
renderSections();
attachEditEvents();
saveToLocal();
} else {
attachEditEvents();
}
});
/icons/hr.icon
Sample集
インタラクティブペーパーの説明書
引っ越し手続き
プロジェクト管理
会議議事録 + ToDo
研修資料
作業手順書
読書メモ
JSON
インタラクティブペーパーの説明書
code:json
{
"schemaVersion": 3,
"title": "インタラクティブペーパーの説明",
"sections": [
{
"id": "sec-a91k20d",
"title": "Interactive Paper とは",
"text": "Interactive Paper は「文章 × アウトライン構造 × チェックリスト」を組み合わせて整理できる、Web ベースのドキュメントツール。ローカル環境で動作し、生成AIに JSON を作らせて取り込む使い方が便利。一から手入力して使うことも可能。",
"checklist": [
{
"id": "chk-h28dj91",
"text": "Interactive Paper の概要を理解した",
"checked": false
},
{
"id": "chk-t37ka22",
"text": "JSON を生成して取り込む方法を理解した",
"checked": false
}
],
"subsections": [
{
"id": "sub-f28ka10",
"title": "特徴",
"text": "・H2(セクション)と H3(小見出し)で階層整理\n・各階層に本文を保持\n・チェックリストの追加が自由\n・ドラッグ&ドロップで並び替え\n・JSON形式で保存・復元\n・ローカルストレージに自動保存\n・進捗率(達成率)を自動表示\n・セクション折りたたみ\n・上下移動ボタンでワンタッチ並び替え",
"checklist": [
{
"id": "chk-a30dm28",
"text": "特徴を一通り理解した",
"checked": false
}
]
}
]
},
{
"id": "sec-b82kd19",
"title": "データ構造(JSON Schema)",
"text": "Interactive Paper は schemaVersion / title / sections の 3 要素で構成される。ID は sec / sub / chk 形式でランダム生成される。",
"checklist": [
{
"id": "chk-s18da90",
"text": "JSON の基本構造を理解した",
"checked": false
}
],
"subsections": [
{
"id": "sub-c18vn20",
"title": "基本構造",
"text": "{\n \"schemaVersion\": 3,\n \"title\": \"文書タイトル\",\n \"sections\": [\n {\n \"id\": \"sec-xxxxxxx\",\n \"title\": \"セクションタイトル\",\n \"text\": \"本文テキスト\",\n \"checklist\": \n { \"id\": \"chk-xxxxxxx\", \"text\": \"項目\", \"checked\": false }\n ,\n \"subsections\": [\n {\n \"id\": \"sub-xxxxxxx\",\n \"title\": \"小見出しタイトル\",\n \"text\": \"テキスト\",\n \"checklist\": \n { \"id\": \"chk-yyyyyyy\", \"text\": \"項目\", \"checked\": true }\n \n }\n ]\n }\n ]\n}", "checklist": [
{
"id": "chk-j28sk11",
"text": "データ構造が 3 層であることを理解した",
"checked": false
}
]
},
{
"id": "sub-w27dk32",
"title": "階層構造",
"text": "Section(H2)\n ├─ 本文\n ├─ Checklist\n └─ Subsection(H3)\n ├─ 本文\n └─ Checklist",
"checklist": [
{
"id": "chk-m20sk82",
"text": "階層構造の違いを説明できる",
"checked": false
}
]
}
]
},
{
"id": "sec-c39dm20",
"title": "操作方法",
"text": "基本的な操作手順をまとめたセクション。",
"checklist": [
{
"id": "chk-h93sj20",
"text": "セクション追加・移動などの操作を理解した",
"checked": false
}
],
"subsections": [
{
"id": "sub-x10ba33",
"title": "追加操作",
"text": "・セクション追加:画面上部の「+ セクション追加」\n・小見出し追加:セクション右上の「+ 小見出し」\n・項目追加:セクション直下 or 小見出し内部で「+ 項目」",
"checklist": [
{
"id": "chk-k20am31",
"text": "各追加ボタンの位置を把握した",
"checked": false
}
]
},
{
"id": "sub-t38sm88",
"title": "並び替え",
"text": "・セクション(H2)単位で DnD\n・小見出し(H3)単位で DnD\n・チェック項目はセクション間を自在に移動可能\n・H2 ↔ H3 の移動も可能",
"checklist": [
{
"id": "chk-p20aj77",
"text": "ドラッグ操作の仕組みを理解した",
"checked": false
}
]
},
{
"id": "sub-a20bx11",
"title": "保存と復元",
"text": "・ローカルストレージに自動保存\n・「JSON 書き出し」でダウンロード\n・「JSON 読み込み」で復元可能",
"checklist": [
{
"id": "chk-q39sn14",
"text": "JSON の保存・復元を理解した",
"checked": false
}
]
}
]
},
{
"id": "sec-d51am88",
"title": "進捗バー",
"text": "各セクションに進捗バーが付き、チェック済み項目の割合を自動計算して表示する。",
"checklist": [
{
"id": "chk-r18ka70",
"text": "進捗計算の仕組みを理解した",
"checked": false
}
],
"subsections": [
{
"id": "sub-n20dk91",
"title": "計算方法",
"text": "checked / total * 100\n(小見出し内の項目も含めて計算)",
"checklist": [
{
"id": "chk-t39md81",
"text": "進捗バーの更新タイミングを把握した",
"checked": false
}
]
}
]
},
{
"id": "sec-e18sm22",
"title": "セクション折りたたみ & 移動",
"text": "セクションタイトル横の「▼」「▶」で折りたたみ可能。上下移動ボタンで簡単に並び替えができる。",
"checklist": [
{
"id": "chk-w23ka55",
"text": "セクション折りたたみ操作を理解した",
"checked": false
}
],
"subsections": []
},
{
"id": "sec-f29dn60",
"title": "こんな用途に向く",
"text": "Interactive Paper は幅広い用途に使える。",
"checklist": [
{
"id": "chk-k29xj01",
"text": "用途を自分の作業に当てはめられる",
"checked": false
}
],
"subsections": [
{
"id": "sub-q39sn14",
"title": "使用例",
"text": "・プロジェクト管理\n・会議議事録 + ToDo\n・研修資料\n・作業手順書\n・読書メモ\n・学習ログ\n・文章構成の下書き",
"checklist": [
{
"id": "chk-f82ka10",
"text": "使ってみたい用途を1つ選んだ",
"checked": false
}
]
}
]
}
]
}
引っ越し手続き
code:json
{
"schemaVersion": 3,
"title": "県内引っ越し・県外引っ越しの手続きまとめ",
"sections": [
{
"id": "sec-a91k20d",
"title": "県内引っ越しの手続き",
"text": "県内での引っ越しは、同じ都道府県内で住所を移す場合に必要な手続き。転出届は不要だが、転居届やライフラインの変更などが必要となる。",
"checklist": [
{
"id": "chk-h28dj91",
"text": "市区町村役場で転居届を提出する",
"checked": false
},
{
"id": "chk-l20am30",
"text": "マイナンバーカードの住所変更を行う",
"checked": false
},
{
"id": "chk-p30dk10",
"text": "運転免許証の住所変更を行う",
"checked": false
},
{
"id": "chk-x28sj20",
"text": "電気・水道・ガスの住所変更または開始/停止手続きをする",
"checked": false
},
{
"id": "chk-m39sd81",
"text": "郵便物の転送届を出す",
"checked": false
}
],
"subsections": [
{
"id": "sub-f28ka10",
"title": "学校・勤務先など",
"text": "県内であっても、学校や勤務先への住所連絡は必要。",
"checklist": [
{
"id": "chk-w27dk32",
"text": "勤務先へ住所変更届を提出する",
"checked": false
},
{
"id": "chk-a30dm28",
"text": "子どもの学校への住所変更・通学区域の確認",
"checked": false
}
]
}
]
},
{
"id": "sec-b82kd19",
"title": "県外引っ越しの手続き",
"text": "県外への引っ越しは、必要な手続きが県内より多く、転出届と転入届の両方が必要。またライフラインや学校・勤務先の手続きも広範囲になる。",
"checklist": [
{
"id": "chk-s18da90",
"text": "旧住所の市区町村で転出届を提出する",
"checked": false
},
{
"id": "chk-d19am23",
"text": "新住所の市区町村で転入届を提出する",
"checked": false
},
{
"id": "chk-t20vm82",
"text": "国民健康保険・国民年金の住所変更(該当者のみ)",
"checked": false
},
{
"id": "chk-k39dj11",
"text": "ガスの閉栓手続き・開栓立ち会い予約",
"checked": false
},
{
"id": "chk-x27sb18",
"text": "インターネット回線の移転手続きまたは新規契約",
"checked": false
},
{
"id": "chk-f30mc21",
"text": "車庫証明・自動車登録の住所変更(必要な場合)",
"checked": false
}
],
"subsections": [
{
"id": "sub-c18vn20",
"title": "郵便・金融・保険など",
"text": "住所変更は多岐にわたるため、早めに一覧化しておくと進めやすい。",
"checklist": [
{
"id": "chk-m20sk82",
"text": "郵便物の転送届を出す(1年間有効)",
"checked": false
},
{
"id": "chk-a18sn02",
"text": "銀行・クレジットカードの住所変更を行う",
"checked": false
},
{
"id": "chk-h93sj20",
"text": "生命保険・自動車保険などの住所変更を行う",
"checked": false
}
]
},
{
"id": "sub-x10ba33",
"title": "学校・勤務先関連",
"text": "転校や勤務先への手続きが必要になるため、早めの準備が重要。",
"checklist": [
{
"id": "chk-q29dn51",
"text": "子どもの転校手続き(在籍校で書類受取)",
"checked": false
},
{
"id": "chk-z38sn14",
"text": "新住所の学校への連絡・入学手続き",
"checked": false
},
{
"id": "chk-b27dk11",
"text": "勤務先の住所変更手続き",
"checked": false
}
]
}
]
}
]
}
プロジェクト管理
code:json
{
"schemaVersion": 3,
"title": "プロジェクト管理サンプル",
"sections": [
{
"id": "sec-a91k20d",
"title": "プロジェクト概要",
"text": "このプロジェクトは、企画から開発、リリースまでの一連の工程を管理するためのサンプルです。",
"checklist": [
{
"id": "chk-h28dj91",
"text": "プロジェクトの目的を明確化する",
"checked": false
},
{
"id": "chk-p30dk10",
"text": "主要メンバーをアサインする",
"checked": false
}
],
"subsections": [
{
"id": "sub-f28ka10",
"title": "スコープ定義",
"text": "プロジェクトの対象範囲(スコープ)を定め、やること・やらないことを明確にする。",
"checklist": [
{
"id": "chk-w27dk32",
"text": "スコープ文書を作成する",
"checked": false
},
{
"id": "chk-a30dm28",
"text": "関係者にスコープをレビューしてもらう",
"checked": false
}
]
}
]
},
{
"id": "sec-b82kd19",
"title": "タスク管理",
"text": "プロジェクトの進行に必要なタスクを整理し、担当者と期限を設定する。",
"checklist": [
{
"id": "chk-s18da90",
"text": "タスク一覧を作成する",
"checked":false
},
{
"id": "chk-d19am23",
"text": "予定・期限を設定する",
"checked": false
}
],
"subsections": [
{
"id": "sub-c18vn20",
"title": "優先度設定",
"text": "タスクに優先度を割り当て、重要なタスクから取り組めるようにする。",
"checklist": [
{
"id": "chk-m20sk82",
"text": "タスクに優先度(高・中・低)を設定する",
"checked": false
},
{
"id": "chk-a18sn02",
"text": "優先タスクをチームに共有する",
"checked": false
}
]
}
]
},
{
"id": "sec-c39dm20",
"title": "進捗管理",
"text": "タスクや成果物の進行状況を定期的に確認し、必要に応じて調整する。",
"checklist": [
{
"id": "chk-h93sj20",
"text": "定例ミーティングを設定する",
"checked": false
},
{
"id": "chk-x10dn52",
"text": "遅延タスクの原因を確認する",
"checked": false
}
],
"subsections": [
{
"id": "sub-x10ba33",
"title": "報告・レビュー",
"text": "進捗をまとめて関係者に共有し、認識のズレをなくす。",
"checklist": [
{
"id": "chk-q29dn51",
"text": "週次または月次レポートを作成する",
"checked": false
},
{
"id": "chk-z38sn14",
"text": "レビュー会議を実施する",
"checked": false
}
]
}
]
}
]
}
会議議事録 + ToDo
code:json
{
"schemaVersion": 3,
"title": "会議議事録 + ToDo サンプル",
"sections": [
{
"id": "sec-a91k20d",
"title": "会議概要",
"text": "プロジェクト定例会議の議事録サンプル。進捗確認、課題共有、次回までのToDoを整理する。",
"checklist": [
{
"id": "chk-h28dj91",
"text": "議事録を関係者へ共有する",
"checked": false
}
],
"subsections": [
{
"id": "sub-f28ka10",
"title": "会議情報",
"text": "日時:2025年5月1日 10:00?11:00\n場所:オンライン(Google Meet)\n参加者:Aさん、Bさん、Cさん",
"checklist": []
}
]
},
{
"id": "sec-b82kd19",
"title": "議題1:進捗報告",
"text": "各メンバーから現在のタスク進捗について報告が行われた。",
"checklist": [
{
"id": "chk-s18da90",
"text": "進捗内容をタスク管理表に反映する",
"checked": false
}
],
"subsections": [
{
"id": "sub-c18vn20",
"title": "メンバー別報告",
"text": "Aさん:デザイン案90%完了\nBさん:バックエンドAPI開発50%完了\nCさん:ユーザーテストシナリオ作成中",
"checklist": []
}
]
},
{
"id": "sec-c39dm20",
"title": "議題2:課題共有",
"text": "現在発生している課題について共有し、対応方針を検討した。",
"checklist": [
{
"id": "chk-h93sj20",
"text": "課題対応の優先度を再確認する",
"checked": false
}
],
"subsections": [
{
"id": "sub-x10ba33",
"title": "共有された課題",
"text": "・APIレスポンスが一部遅延している\n・ユーザーテストの参加者が不足している\n・デザイン修正の追加要望が増加",
"checklist": [
{
"id": "chk-q29dn51",
"text": "API遅延の原因調査(担当:Bさん)",
"checked": false
},
{
"id": "chk-z38sn14",
"text": "テスト参加者の再募集(担当:Cさん)",
"checked": false
},
{
"id": "chk-b27dk11",
"text": "デザイン修正要望を整理(担当:Aさん)",
"checked": false
}
]
}
]
},
{
"id": "sec-d51am88",
"title": "議題3:次回までのToDo整理",
"text": "次回会議までに対応すべきタスクを明確化し、担当者を割り当てた。",
"checklist": [],
"subsections": [
{
"id": "sub-n20dk91",
"title": "ToDo一覧",
"text": "次回会議日:2025年5月8日(木)",
"checklist": [
{
"id": "chk-r18ka70",
"text": "UIデザイン最終案の提出(担当:Aさん/期限:5月6日)",
"checked": false
},
{
"id": "chk-s28la12",
"text": "API遅延改善案の提示(担当:Bさん/期限:5月7日)",
"checked": false
},
{
"id": "chk-t39md81",
"text": "ユーザーテスト参加者リスト確定(担当:Cさん/期限:5月6日)",
"checked": false
}
]
}
]
}
]
}
研修資料
code:json
{
"schemaVersion": 3,
"title": "研修資料サンプル",
"sections": [
{
"id": "sec-a91k20d",
"title": "研修概要",
"text": "この研修資料は、新入社員向けの基礎研修を想定したサンプルです。目的・内容・到達目標をまとめています。",
"checklist": [
{
"id": "chk-h28dj91",
"text": "研修目的を受講者と共有する",
"checked": false
}
],
"subsections": [
{
"id": "sub-f28ka10",
"title": "研修の目的",
"text": "・組織の基本ルールや役割を理解する\n・業務に必要な基礎スキルを習得する\n・チームコミュニケーションの基本を身につける",
"checklist": [
{
"id": "chk-a30dm28",
"text": "研修の目的を事前資料に明記する",
"checked": false
}
]
}
]
},
{
"id": "sec-b82kd19",
"title": "研修内容",
"text": "研修で扱うテーマやカリキュラムをまとめたセクションです。",
"checklist": [
{
"id": "chk-s18da90",
"text": "全カリキュラムの進行表を準備する",
"checked": false
}
],
"subsections": [
{
"id": "sub-c18vn20",
"title": "テーマ1:会社理解",
"text": "・会社のビジョン・ミッション\n・組織構造と各部署の役割\n・就業ルールとコンプライアンス",
"checklist": [
{
"id": "chk-m20sk82",
"text": "会社紹介スライドを用意する",
"checked": false
}
]
},
{
"id": "sub-w27dk32",
"title": "テーマ2:業務基礎スキル",
"text": "・情報共有の仕方\n・報連相の基本\n・タスク管理とスケジュール管理",
"checklist": [
{
"id": "chk-l19dm22",
"text": "ワークシートを配布する",
"checked": false
}
]
},
{
"id": "sub-a20bx11",
"title": "テーマ3:コミュニケーション",
"text": "・チーム内コミュニケーション\n・オンライン会議のポイント\n・ビジネスマナーの基礎",
"checklist": [
{
"id": "chk-q39sn14",
"text": "ロールプレイ用のシナリオを準備する",
"checked": false
}
]
}
]
},
{
"id": "sec-c39dm20",
"title": "研修ワーク",
"text": "研修内で実施する演習やディスカッションの内容をまとめます。",
"checklist": [
{
"id": "chk-h93sj20",
"text": "ワークの進行役を決める",
"checked": false
}
],
"subsections": [
{
"id": "sub-x10ba33",
"title": "ワーク1:ケーススタディ",
"text": "実際の業務で起こり得るケースに対して解決策を考えるワーク。",
"checklist": [
{
"id": "chk-q29dn51",
"text": "ケーススタディ資料を印刷する",
"checked": false
}
]
},
{
"id": "sub-t38sm88",
"title": "ワーク2:グループディスカッション",
"text": "テーマに沿って考えをまとめ、発表するトレーニング。",
"checklist": [
{
"id": "chk-p20aj77",
"text": "発表用のテンプレートを共有する",
"checked": false
}
]
}
]
},
{
"id": "sec-d51am88",
"title": "研修後のフォロー",
"text": "研修後の振り返りや実務への定着を図るためのアクションをまとめています。",
"checklist": [
{
"id": "chk-r18ka70",
"text": "受講者アンケートを実施する",
"checked": false
},
{
"id": "chk-s28la12",
"text": "現場でのフォローアップ面談を設定する",
"checked": false
}
],
"subsections": [
{
"id": "sub-n20dk91",
"title": "振り返りポイント",
"text": "・研修で学んだこと\n・実践してみたいこと\n・難しかった点の整理",
"checklist": [
{
"id": "chk-t39md81",
"text": "受講者に振り返りシートを配布する",
"checked": false
}
]
}
]
}
]
}
作業手順書
code:json
{
"schemaVersion": 3,
"title": "作業手順書サンプル",
"sections": [
{
"id": "sec-a91k20d",
"title": "作業概要",
"text": "この手順書は、作業を安全かつ確実に実施するための標準的な手順を示したサンプルです。",
"checklist": [
{
"id": "chk-h28dj91",
"text": "作業開始前に手順書を確認した",
"checked": false
}
],
"subsections": [
{
"id": "sub-f28ka10",
"title": "必要な道具・環境",
"text": "・作業用PC\n・安全装備(必要な場合)\n・関連マニュアル\n・ネットワーク接続環境",
"checklist": [
{
"id": "chk-a30dm28",
"text": "必要な道具が揃っているか確認する",
"checked": false
}
]
}
]
},
{
"id": "sec-b82kd19",
"title": "手順1:事前準備",
"text": "作業に取りかかる前に、事前の確認と環境整備を行う。",
"checklist": [
{
"id": "chk-s18da90",
"text": "作業対象の情報を確認する",
"checked": false
},
{
"id": "chk-d19am23",
"text": "関連するシステムや機器の状態を確認する",
"checked": false
}
],
"subsections": [
{
"id": "sub-c18vn20",
"title": "チェック項目",
"text": "作業対象に異常がないか、必要なアクセス権があるか確認する。",
"checklist": [
{
"id": "chk-m20sk82",
"text": "ログイン可能かテストする",
"checked": false
}
]
}
]
},
{
"id": "sec-c39dm20",
"title": "手順2:作業実施",
"text": "実際の作業工程を示します。順番を守って実行してください。",
"checklist": [
{
"id": "chk-h93sj20",
"text": "手順通りに作業を進める",
"checked": false
}
],
"subsections": [
{
"id": "sub-x10ba33",
"title": "作業工程",
"text": "1. システムを起動する\n2. 対象データを読み込む\n3. 必要な処理を実行する\n4. 結果を保存する",
"checklist": [
{
"id": "chk-q29dn51",
"text": "処理結果の整合性を確認する",
"checked": false
}
]
}
]
},
{
"id": "sec-d51am88",
"title": "手順3:作業後処理",
"text": "作業完了後に実施する確認や後片づけの内容。",
"checklist": [
{
"id": "chk-r18ka70",
"text": "ログを保存・共有する",
"checked": false
},
{
"id": "chk-s28la12",
"text": "機器や環境を元の状態に戻す",
"checked": false
}
],
"subsections": [
{
"id": "sub-n20dk91",
"title": "作業完了チェック",
"text": "作業内容に漏れがないか最終確認する。",
"checklist": [
{
"id": "chk-t39md81",
"text": "関係者へ作業完了を報告する",
"checked": false
}
]
}
]
}
]
}
読書メモ
code:json
{
"schemaVersion": 3,
"title": "読書メモ サンプル",
"sections": [
{
"id": "sec-a91k20d",
"title": "書籍情報",
"text": "タイトル:〇〇〇〇\n著者:△△△△\n出版年:2025年\n読んだ日:2025/05/01",
"checklist": [
{
"id": "chk-h28dj91",
"text": "読書メモを最後まで書く",
"checked": false
}
],
"subsections": [
{
"id": "sub-f28ka10",
"title": "読む目的",
"text": "この本を読む目的を整理しておくと、理解度や読後の振り返りがしやすくなる。",
"checklist": [
{
"id": "chk-a30dm28",
"text": "読んだ目的を一文で書く",
"checked": false
}
]
}
]
},
{
"id": "sec-b82kd19",
"title": "重要ポイント・要約",
"text": "本の中で重要だった部分、心に残った内容、キーワードなどを書き留める。",
"checklist": [
{
"id": "chk-s18da90",
"text": "章ごとの重要ポイントをまとめる",
"checked": false
}
],
"subsections": [
{
"id": "sub-c18vn20",
"title": "印象に残った点",
"text": "・○○の考え方が新しかった\n・具体例が豊富で理解しやすかった\n・△△の部分は難しく感じた",
"checklist": []
}
]
},
{
"id": "sec-c39dm20",
"title": "気づき・学び",
"text": "本を通して得た学びや、自分の生活・仕事にどう活かせるかを整理する。",
"checklist": [
{
"id": "chk-h93sj20",
"text": "3つ以上の学びを書き出す",
"checked": false
}
],
"subsections": [
{
"id": "sub-x10ba33",
"title": "活用アイデア",
"text": "・日常の行動に取り入れたいこと\n・仕事の改善に応用できるアイデア\n・新しく試したい習慣",
"checklist": [
{
"id": "chk-z38sn14",
"text": "学びのうち1つを実際に行動する",
"checked": false
}
]
}
]
},
{
"id": "sec-d51am88",
"title": "引用・抜き書き",
"text": "印象深い文章や引用したい言葉をメモしておく。",
"checklist": [],
"subsections": [
{
"id": "sub-n20dk91",
"title": "引用メモ",
"text": "例:\n「□□□」\n「△△△が□□を変える」",
"checklist": []
}
]
},
{
"id": "sec-e28sm62",
"title": "次に読む本・関連書籍",
"text": "読んだ内容から派生して興味を持った本や参考文献をまとめる。",
"checklist": [
{
"id": "chk-r18ka70",
"text": "次に読む本を1冊選ぶ",
"checked": false
}
],
"subsections": []
}
]
}