cd1a618e-057c-4e17-8eed-345839a37c9d
Wikiのバージョン管理はまた原始的
91eed3b9-208a-4f7d-8cda-7b91414a7de7
画像の埋め込み方式
<<<<<<< Wikiのバージョン管理はまた原始的
Wikiのバージョン管理はまた原始的
bsahd.icon
もしbranch機能があれば?
Gitとは違い明示的にcommitしない
1分ごとなどに暗黙的にcommitされて、時刻で遡れる
他branchの影響を受けないので作業に集中できる
静かな部屋のたとえ
静かに作業したいが、個人プロジェクトはページが充実してないので作業しにくい
そこでブランチを切る
そうすればmainブランチのにぎやかさからカットアウトされる
作業が終わったらマージする
同じbranchの人同士で同時編集できる
いいなそれnishio.icon
纏まってない考えを書くのに非公開のブランチを作る
「非公開」がいいのか「読めるけど書き込めない」がいいのか「下書き中」と表示されてるだけでいいのか
ページ超えHistoryも便利そう
ブランチごとにページ超えのHistoryが作られる
いまいちピンと来なかったtakker.icon
branchとpageごとにPage Historyが作られる?
ページを超えた大規模なrefactoringにも便利そう
レビュー(プルリク)があってもいい?
例えば/nishioに誤字脱字を見つけたときにブランチを切って修正し、プルリクを送る
ブランチを切るのはだれでもできる
切ったブランチは自分と招待した人とプロジェクトの編集者しか編集できない
mainへのマージはプロジェクトの編集者しかできない
ので、プルリクを使う
GithubでいうForkをプロジェクトごと複製せずに実現したい
||||||| 91eed3b9-208a-4f7d-8cda-7b91414a7de7
91eed3b9-208a-4f7d-8cda-7b91414a7de7
#UUID
who.iconヾ(・ω・*)
who.iconそれな.icon(・ω・*)
(*・ω・)逆それな.iconwho.iconそれな.icon(・ω・*)
(*・ω・)逆ヾ.iconwho.iconヾ(・ω・*)
=======
画像の埋め込み方式
#UUID
bsahd.icon
何らかのデータに画像を埋め込む場合
データに画像バイナリを入れる
メリデメ
メリット
画像を見るのにメッセージデータ以外必要としない
エンドツーエンド暗号化できる
1ファイルで済むので、データの取り回しが楽
デメリット
メッセージサイズが(画質を許容できるレベルで下げても)50kB~200kB増える
低速回線の場合全て受信するまでテキストすら読めない
データ内の順序をテキスト→画像の順番にすればいいのかな
ユーザーごとに画質を調整できない
画像が不要な場合もダウンロードしなければいけない
バイナリデータをメッセージに入れる設計が必要
最悪Base64でなんとかなる
MIMEですな
実例
メールの添付ファイル
Office系
データには画像への参照(URLなど)しか入れない
メリデメは裏返しかな
実例
Web関係はほとんどこっち?
Data URIという例外があるか
というかもともとURL参照でしか画像が入れられなかったのかw
>>>>>> 画像の埋め込み方式
<<<<<<< Wikiのバージョン管理はまた原始的
現状のシステムで実現する方法
必然的にブランチはページ単位になる
projectの複製ができないため
ページを2回複製する
複製元ページはaとする
ページ名はWikiのバージョン管理はまた原始的とする
1つ目の複製は「ブランチを切ったときのバックアップ」で、cとする
実際のページ名はWikiのバージョン管理はまた原始的 (bsahd backup)とする
[Wikiのバージョン管理はまた原始的 (bsahd)]の編集開始時のバックアップです。[* 編集しないでください]みたいなヘッダーを付ける
2つ目の複製はブランチの編集用で、bとする
実際のページ名はWikiのバージョン管理はまた原始的 (bsahd)とする
このページは[Wikiのバージョン管理はまた原始的]のブランチですみたいなヘッダーを付ける
bを編集する
diff3 -m a c b
後述のscrapmerge.js
diff3のnpmがある
esbuildかければブラウザでも使えるだろう
意味
編集前はcです
編集後1はbです
編集後2はaです
両方の編集統合して出力
コンフリクトマーカーを残したままaを前のdiff3の出力で上書き
b,cを消す
||||||| 91eed3b9-208a-4f7d-8cda-7b91414a7de7
なんかYoを思い出した
#顔文字
=======
動的リンクと静的リンクの関係に見える
>>>>>> 画像の埋め込み方式
scrapmerge
UserScript版
userscript.js
ダウンロードする
deno run -A bundler.js
code:bundler.js
import * as esbuild from "npm:esbuild";
import { denoPlugins } from "https://deno.land/x/esbuild_deno_loader/mod.ts";
esbuild.build({
//@ts-ignore:
plugins: ...denoPlugins({ loader: "native" }),
entryPoints: "./${{ダウンロードしたファイル名}}",
bundle: true,
minify: true,
outfile: "./dist.js",
})
.then(() => {
esbuild.stop();
console.log("build ok");
});
dist.jsをscrapboxに貼り付ける
ビルド済み: /bsahd-public/scrapMerge
code:sb
ページ名
aのページ名
cのページ名
bのページ名
のように書いてボタンを押すとページの末尾に追記される
コマンド版
deno.iconが必要です
使い方:deno run https://scrapbox.io/api/code/villagepump/Wikiのバージョン管理はまた原始的/scrapmerge.js プロジェクト名 aのページ名 cのページ名 bのページ名 > 出力先ファイル名.diff
ページ名はダブルクオーテーションで囲ってください
code:scrapmerge.js
import * as Diff3 from "npm:node-diff3";
import { Command } from "https://deno.land/x/cliffy@v0.19.2/command/mod.ts";
function getPage(projectName, pageName) {
return fetch(
"https://scrapbox.io/api/pages/" +
projectName +
"/" +
encodeURIComponent(pageName) + "/text",
).then((pageRes) => {
if (pageRes.ok) {
return pageRes.text();
} else {
return pageRes.text().then((text) => {
console.error(pageRes.status, text);
});
}
});
}
new Command()
.name("scrapMerge")
.arguments("<projectName> <mine> <older> <your>")
.parse(Deno.args).then(({ args: projectName, mine, older, your }) => {
return getPage(projectName, mine).then((
mineData,
) => mineData, mine, older, your, projectName);
}).then((mineData, mine, older, your, projectName) => {
return getPage(projectName, older).then((
olderData,
) => mineData, olderData, mine, older, your, projectName);
})
.then((mineData, olderData, mine, older, your, projectName) => {
return getPage(projectName, your).then((
yourData,
) => mineData, olderData, yourData, mine, older, your, projectName);
}).then(
(mineData, olderData, yourData, mine, older, your, projectName) => {
const diff3dat = Diff3.mergeDiff3(mineData, olderData, yourData, {
label: { a: mine, o: older, b: your },
excludeFalseConflicts: true,
stringSeparator: /\n/,
});
console.log(diff3dat.result.join("\n"));
},
);
code:userscript.js
import * as Diff3 from "npm:node-diff3";
function getPage(projectName, pageName) {
return fetch(
"https://scrapbox.io/api/pages/" +
projectName +
"/" +
encodeURIComponent(pageName) + "/text",
).then((pageRes) => {
if (pageRes.ok) {
return pageRes.text();
} else {
return pageRes.text().then((text) => {
console.error(pageRes.status, text);
});
}
});
}
scrapbox.PageMenu.addMenu({
title: "merge",
image: "https://i.gyazo.com/7057219f5b20ca8afd122945b72453d3.png",
onClick: () => {
const projectName = scrapbox.Project.name;
const mine = scrapbox.Page.lines1.text;
const older = scrapbox.Page.lines2.text;
const your = scrapbox.Page.lines3.text;
getPage(projectName, mine).then((
mineData,
) => mineData).then((mineData) => {
return getPage(projectName, older).then((
olderData,
) => mineData, olderData);
})
.then((mineData, olderData) => {
return getPage(projectName, your).then((
yourData,
) => mineData, olderData, yourData);
}).then(
(mineData, olderData, yourData) => {
const diff3dat = Diff3.mergeDiff3(
mineData,
olderData,
yourData,
{
excludeFalseConflicts: true,
stringSeparator: /\n/,
label: { a: mine, o: older, b: your },
},
);
console.log(diff3dat);
for (const element of diff3dat.result) {
scrapbox.Page.insertLine(
element,
scrapbox.Page.lines.length,
);
}
},
);
},
});