Cosenseを読書ノートとして使うときのちょっとした工夫
井戸端アドベントカレンダー2025
雑に、気軽に使えるCosnseを読書ノートとして使っているmeganii.icon
Evernoteは同期の問題で断念
NotionやObsidianはなんだかきっちり、かっちり使わないといけないという謎の強迫観念があるので読書ノートとしては使わなくなった
Notionはタグでフィルタ整理できるのは便利だけど、雑に使うにはつらいwogikaze.icon
Scrapboxで読書管理をするときのじぶんルール - SIS Labで書いたことが継続している
読書ノート用のCosenseプロジェウトに設定しているちょっとした工夫をまとめてみる
本のページはタイトルを非表示にして書影だけを表示する
https://gyazo.com/e957fec97713e0a3a691ba4289aa31ce
表示を縦長にして、書影が綺麗に表示されるようにするのがポイント
本が増えると賑やかになって楽しい
楽しいのが大事
いいなこれsta.iconnishio.iconmtane0412.iconyamanoku.icon
ちょっと縦長にしてるのも芸が細かいnishio.icon
自作フィルターボタンで、本のページと自分のメモを区別する
https://gyazo.com/695f3938997613ae405833c404e4f18c
本が増えて賑やかになるのは楽しいのだけど、自分が書いたメモが埋もれてしまうので、フィルタできるようにしている
Web Clip的なものも「B: ページタイトル」でページを作っているので、除外している
本の章を切り出したとき、書名は非表示にする
https://gyazo.com/e3759c3854c9e87e8d076701795cf195
『How to Make Sense of Any Mess』の例
ページタイトルに同じ書名の文字列が羅列しないのでビジーにならず、スッキリする
見た目大事
接頭語で名前空間を分けUserScriptとUserCSSでアイコンに置き換え視認性を上げる
スクボのタイトルで同名の別概念をどう表現するかのひとつの案
ITILの例
https://gyazo.com/107d876dd66a110eda6e50238d879e44
https://gyazo.com/7f8a16f99df29348f0be833d641cb8b8
見た目大事
良いseibe.icon
[人名]タグ(リンク)に下表のinfoboxを付けて著者一覧を自動生成する
table:infoboxの例
生誕 その人物が「生まれた日付」の日付情報だけ抜き出せ。日付以外の情報(例えば生まれた場所)は不要。「生誕」と「死没」は、「~」や「-」といった区切り文字で区切られている。その場合、区切り文字で区切られた前の日付を「生誕」とせよ。ページ内容から判断できない場合は空白のままとせよ。
死没 その人物が「死んだ日付」の日付情報だけ抜き出せ。日付以外の情報(例えば都道府県)は不要。「生誕」と「死没」は、「~」や「-」といった区切り文字で区切られている。その場合、区切り文字で区切られた後の日付を「死没」と判断せよ。ページ内容から判断できない場合は空白のままとせよ。
年齢 「生誕」と「今年」(「死没」)の項目からその人物の年齢を計算せよ。死没している場合、「没」を末尾に追加せよ(例えば「50歳没」などの表記)。計算できない場合は空白とせよ。
何をした人? ページタイトルだけではなく、どのような人物か、どんな仕事をしたかを記述せよ。
今年 今年は「2025年」です。ページ内容に関わらず、「2025年」とせよ。
https://gyazo.com/b5006d6a620f7eded952c7b73a10bda1
infoboxは既定で非表示にして、表示したいときだけ表示ボタンを押す
https://gyazo.com/cd872cb6699352215d0049ad93dca535
抜け漏れがあると埋めたくなる盆栽要素
infoboxもとい文芸的データベースはもっと活用できそうなので試してみたい
XTwitterのブックマークボタンを押したら、Cosenseに今日のブックマークページを作る
AndroidのXTwitter用ブラウザとしてEdgeを利用して、PWA版XTwitterからTamperMonkeyのScriptを実行
https://gyazo.com/e66986c1d4123035a7ddc482e197cf24
見直す確率が高くなり、参照することも増えた
なんでメモを取ったのか一言あるとさらに見返しやすい
良いmtane0412.icon
#UserScript
with ChatGPT
code:script.js
// ▼▼▼ 設定箇所: ここに対応したい接頭語とCSSクラス名を追加・編集します ▼▼▼
const PREFIX_CONFIG = [
{ prefix: 'ITIL:', className: 'icon-itil' },
{ prefix: 'Azure:', className: 'icon-azure' },
{ prefix: 'AWS:', className: 'icon-aws' },
// { prefix: 'GCP:', className: 'icon-gcp' },
];
const PROCESSED_ATTRIBUTE = 'data-prefix-icon-processed';
const DEBOUNCE_DELAY = 100; // 処理を遅延させる時間 (ミリ秒)
/**
* 指定されたDOMノード(またはその子孫)内の未処理リンクをアイコン化する関数
*/
const processNode = (targetNode) => {
if (targetNode.nodeType !== Node.ELEMENT_NODE) return;
const links = targetNode.querySelectorAll(a.page-link:not([${PROCESSED_ATTRIBUTE}]));
links.forEach(link => {
const text = link.textContent.trim();
for (const config of PREFIX_CONFIG) {
if (text.startsWith(config.prefix)) {
const prefixLength = config.prefix.length;
const childSpans = link.children;
if (childSpans.length >= prefixLength) {
for (let i = 0; i < prefixLength; i++) {
childSpansi.classList.add('prefix-char-hidden');
}
const iconSpan = document.createElement('span');
iconSpan.className = config.className;
link.prepend(iconSpan);
link.setAttribute(PROCESSED_ATTRIBUTE, 'true');
break;
}
}
}
// 切り出した書籍名に非表示用のクラス付加
const match = text.match(/\|\s『.+?』$/);
if (match) {
const startIndex = match.index;
const endIndex = startIndex + match0.length;
const chars = link.querySelectorAll('span.char-index');
for (let i = startIndex; i < endIndex && i < chars.length; i++) {
charsi.classList.add('prefix-char-hidden');
}
link.setAttribute(PROCESSED_ATTRIBUTE, 'true');
}
});
};
// --- 実行と監視のロジック (デバウンス版) ---
// 1. ページ初期読み込み時に、ページ全体を対象として一度実行
processNode(document.body);
// 2. DOMの変更を監視するための MutationObserver
let debounceTimer = null;
const observer = new MutationObserver(() => {
// 既にタイマーがセットされていれば、それをキャンセル
clearTimeout(debounceTimer);
// 新しいタイマーをセット。指定時間後に処理を一度だけ実行する
debounceTimer = setTimeout(() => {
processNode(document.body);
}, DEBOUNCE_DELAY);
});
// 監視を開始
observer.observe(document.body, {
childList: true,
subtree: true
});
#UserCSS
code:style.css
/* 『で始まるページタイトルは書籍ページとする */
.grid li.page-list-itemdata-page-title^="『" a .header {
position: absolute;
padding: 10px;
top: 0;
bottom: 0;
left: 0;
}
.grid li.page-list-itemdata-page-title^="『" a .title{
color: transparent;
}
.grid li.page-list-itemdata-page-title^="『" a .icon img {
width: auto;
height: 100%;
margin: 10px auto;
}
/* 顔写真が切れないようにする*/
.grid li.page-list-itemdata-page-links*="'人名'" a .icon img {
width: auto;
height: 100%;
margin: 10px auto;
}
.line span.text:has(.modal-image) {
text-align: center;
}
/* infobox非表示*/
.page-sidebar { display: none; }
.page-column:has(.page-sidebar) {
grid-template-columns: minmax(200px, 960px) min-content;
grid-template-areas: "page menu"
}
/* 1. 【共通】接頭語のテキストを非表示にするルール */
.page-link .prefix-char-hidden {
display: none;
}
/* 2. 【共通】すべてのアイコンに適用する基本スタイル */
.page-link spanclass*="icon-"::before {
content: '';
display: inline-block;
width: 16px;
height: 16px;
background-image: var(--icon-image);
background-size: contain;
background-repeat: no-repeat;
background-position: center;
margin-right: 4px;
vertical-align: middle;
}
/* 3. 【個別】各アイコンに画像URLを変数として定義 */
/* ::beforeではなく、span本体に定義するのがポイント */
.page-link span.icon-itil {
--icon-image: url('https://example.com/itil-icon.png');
}
.page-link span.icon-azure {
--icon-image: url('https://example.com/azure-icon.png');
}
.page-link span.icon-aws {
--icon-image: url('https://example.com/aws-icon.png');
}
infobox 表示/非表示ボタン
code:script.js
scrapbox.PageMenu.addMenu({
title: "Infobox",
image: 'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path fill="%23848484" d="M308.5 135.3c7.1-6.3 9.9-16.2 6.2-25c-2.3-5.3-4.8-10.5-7.6-15.5L304 89.4c-3-5-6.3-9.9-9.8-14.6c-5.7-7.6-15.7-10.1-24.7-7.1l-28.2 9.3c-10.7-8.8-23-16-36.2-20.9L199 27.1c-1.9-9.3-9.1-16.7-18.5-17.8C173.9 8.4 167.2 8 160.4 8l-.7 0c-6.8 0-13.5 .4-20.1 1.2c-9.4 1.1-16.6 8.6-18.5 17.8L115 56.1c-13.3 5-25.5 12.1-36.2 20.9L50.5 67.8c-9-3-19-.5-24.7 7.1c-3.5 4.7-6.8 9.6-9.9 14.6l-3 5.3c-2.8 5-5.3 10.2-7.6 15.6c-3.7 8.7-.9 18.6 6.2 25l22.2 19.8C32.6 161.9 32 168.9 32 176s.6 14.1 1.7 20.9L11.5 216.7c-7.1 6.3-9.9 16.2-6.2 25c2.3 5.3 4.8 10.5 7.6 15.6l3 5.2c3 5.1 6.3 9.9 9.9 14.6c5.7 7.6 15.7 10.1 24.7 7.1l28.2-9.3c10.7 8.8 23 16 36.2 20.9l6.1 29.1c1.9 9.3 9.1 16.7 18.5 17.8c6.7 .8 13.5 1.2 20.4 1.2s13.7-.4 20.4-1.2c9.4-1.1 16.6-8.6 18.5-17.8l6.1-29.1c13.3-5 25.5-12.1 36.2-20.9l28.2 9.3c9 3 19 .5 24.7-7.1c3.5-4.7 6.8-9.5 9.8-14.6l3.1-5.4c2.8-5 5.3-10.2 7.6-15.5c3.7-8.7 .9-18.6-6.2-25l-22.2-19.8c1.1-6.8 1.7-13.8 1.7-20.9s-.6-14.1-1.7-20.9l22.2-19.8zM112 176a48 48 0 1 1 96 0 48 48 0 1 1 -96 0zM504.7 500.5c6.3 7.1 16.2 9.9 25 6.2c5.3-2.3 10.5-4.8 15.5-7.6l5.4-3.1c5-3 9.9-6.3 14.6-9.8c7.6-5.7 10.1-15.7 7.1-24.7l-9.3-28.2c8.8-10.7 16-23 20.9-36.2l29.1-6.1c9.3-1.9 16.7-9.1 17.8-18.5c.8-6.7 1.2-13.5 1.2-20.4s-.4-13.7-1.2-20.4c-1.1-9.4-8.6-16.6-17.8-18.5L583.9 307c-5-13.3-12.1-25.5-20.9-36.2l9.3-28.2c3-9 .5-19-7.1-24.7c-4.7-3.5-9.6-6.8-14.6-9.9l-5.3-3c-5-2.8-10.2-5.3-15.6-7.6c-8.7-3.7-18.6-.9-25 6.2l-19.8 22.2c-6.8-1.1-13.8-1.7-20.9-1.7s-14.1 .6-20.9 1.7l-19.8-22.2c-6.3-7.1-16.2-9.9-25-6.2c-5.3 2.3-10.5 4.8-15.6 7.6l-5.2 3c-5.1 3-9.9 6.3-14.6 9.9c-7.6 5.7-10.1 15.7-7.1 24.7l9.3 28.2c-8.8 10.7-16 23-20.9 36.2L315.1 313c-9.3 1.9-16.7 9.1-17.8 18.5c-.8 6.7-1.2 13.5-1.2 20.4s.4 13.7 1.2 20.4c1.1 9.4 8.6 16.6 17.8 18.5l29.1 6.1c5 13.3 12.1 25.5 20.9 36.2l-9.3 28.2c-3 9-.5 19 7.1 24.7c4.7 3.5 9.5 6.8 14.6 9.8l5.4 3.1c5 2.8 10.2 5.3 15.5 7.6c8.7 3.7 18.6 .9 25-6.2l19.8-22.2c6.8 1.1 13.8 1.7 20.9 1.7s14.1-.6 20.9-1.7l19.8 22.2zM464 304a48 48 0 1 1 0 96 48 48 0 1 1 0-96z"/></svg>',
onClick: () => {
const selector = document.querySelector('#disable-user-css');
if (selector) {
selector.remove();
} else {
const style = document.createElement('style');
style.id = 'disable-user-css'; // 任意のIDを設定して、後で削除しやすくする
style.innerHTML = `
.page-sidebar { display: block !important; }
.page-column:has(.page-sidebar) {
grid-template-columns: minmax(200px, 3fr) minmax(170px, 1fr) min-content !important;
grid-template-areas: "page sidebar menu" !important;
}
`;
document.head.appendChild(style);
}
}});
カスタムフィルタ
code:style.css
.custom-page-filter.tool-btn .fas { color: var(--tool-light-color)}
code:script.js
function createCustomFilterButton() {
const div = document.createElement('div');
div.className = 'custom-page-filter';
const a = document.createElement('a');
a.className = 'custom-page-filter tool-btn';
a.setAttribute('role', 'button');
a.setAttribute('tabindex', '0');
a.setAttribute('id', 'customFilterButton');
const span = document.createElement('span');
span.className = 'fas fa-filter';
a.appendChild(span);
div.appendChild(a);
return div;
}
function handleFilterButtonClick() {
const style = document.getElementById("bfilter");
if (style) {
style.remove();
} else {
document.head.insertAdjacentHTML(
"beforeend",
`<style id="bfilter">
.page-list-itemdata-page-title^='『' { display: none !important; }
.page-list-itemdata-page-title^='B:' { display: none !important; }
.page-list-itemdata-page-links*="'人名'" { display: none !important; }
.page-list-itemdata-page-links*="'用語'" { display: none !important; }
#customFilterButton.filtered .fas { color: var(--tool-color) !important; }
</style>`
);
document.getElementById("customFilterButton").classList.add("filtered");
}
console.log('hide');
}
function setupCustomFilter() {
const targetNode = document.querySelector('.quick-launch > .flex-box');
if (!targetNode) {
console.warn("Target element '.quick-launch > .flex-box' not found.");
return;
}
if (!document.getElementById('customFilterButton')) {
targetNode.appendChild(createCustomFilterButton());
const button = document.getElementById("customFilterButton");
button.addEventListener('click', handleFilterButtonClick);
}
}
setupCustomFilter();
document.addEventListener('DOMContentLoaded', setupCustomFilter);
window.scrapbox.addListener("layout:changed", setupCustomFilter);