Skip to content

Instantly share code, notes, and snippets.

@drobune
Last active March 14, 2025 07:14
Show Gist options
  • Save drobune/642da67627d7ff0bc23ac2eb88603697 to your computer and use it in GitHub Desktop.
Save drobune/642da67627d7ff0bc23ac2eb88603697 to your computer and use it in GitHub Desktop.
cosense_to_google_docs
// 代表的なページタイプを取得して、最終的な移行計画を作成
const fileContent = await window.fs.readFile('tdwda.json', { encoding: 'utf8' });
// ページタイトルとIDのマッピングを作成(後でディレクトリ構造に使用)
const titleToIdMap = {};
const pagePattern = /"title":"([^"]+)","created":(\d+),"updated":(\d+),"id":"([^"]+)","views":(\d+)/g;
let match;
while ((match = pagePattern.exec(fileContent))) {
const title = match[1];
const id = match[4];
titleToIdMap[title] = id;
}
// サンプルページのIDを取得
const samplePageIds = [
"IDRアンケート",
"IDRアプリデザイン仕様",
"過ごし方の提案のJSON",
"IDR ユーザーレベルとバッジについて"
];
const samplePageIdMap = {};
samplePageIds.forEach(title => {
if (titleToIdMap[title]) {
samplePageIdMap[title] = titleToIdMap[title];
}
});
// 改良した変換関数
function convertToMarkdown(lines) {
const markdown = [];
let inCodeBlock = false;
let codeLanguage = "";
lines.forEach(line => {
// 空行はそのまま
if (line === "") {
markdown.push("");
return;
}
// コードブロック処理
if (line.startsWith("code:")) {
inCodeBlock = true;
codeLanguage = line.substring(5).trim() || "";
markdown.push("```" + codeLanguage);
return;
}
if (inCodeBlock) {
// コードブロック終了判定(空白行またはコードブロック以外の開始)
if (line === " " || line.trim() === "") {
inCodeBlock = false;
markdown.push("```");
return;
}
// コードブロック内はそのまま
markdown.push(line);
return;
}
// 見出し変換
if (/^\[(\*{1,6}) (.+)\]$/.test(line)) {
const match = line.match(/^\[(\*{1,6}) (.+)\]$/);
const level = Math.min(match[1].length, 6); // Markdownの見出しは6段階まで
const text = match[2];
markdown.push("#".repeat(level) + " " + text);
return;
}
// リンク変換
let processedLine = line;
// 名前付きリンク: [テキスト https://example.com]
processedLine = processedLine.replace(/\[([^\]]+) (https?:\/\/[^\]]+)\]/g, "[$1]($2)");
// シンプルリンク: [https://example.com]
processedLine = processedLine.replace(/\[(https?:\/\/[^\]]+)\]/g, "[$1]($1)");
// ユーザーアイコン: [user.icon]
processedLine = processedLine.replace(/\[([^\.]+)\.icon\]/g, "**@$1**");
// タグ: #タグ
processedLine = processedLine.replace(/#([A-Za-z0-9_\-]+)/g, "**#$1**");
// インデント処理
const indentMatch = processedLine.match(/^( +)/);
if (indentMatch) {
const indentLevel = indentMatch[1].length;
// レベルに応じてリストや引用に変換
if (indentLevel === 1) {
processedLine = "- " + processedLine.substring(indentMatch[1].length);
} else {
processedLine = " ".repeat(indentLevel - 1) + "- " + processedLine.substring(indentMatch[1].length);
}
}
markdown.push(processedLine);
});
// コードブロックが閉じられていない場合
if (inCodeBlock) {
markdown.push("```");
}
return markdown.join("\n");
}
// 最初のサンプルページの抽出と変換
console.log("サンプルページの変換例:");
// サンプルページIDを使用して内容を抽出
const pageExtracts = {};
for (const title in samplePageIdMap) {
const id = samplePageIdMap[title];
const pagePattern = new RegExp(`"title":"${title.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}"[^}]*"lines":\\[(.*?)\\]`, 's');
const pageMatch = pagePattern.exec(fileContent);
if (pageMatch) {
const linesJson = pageMatch[1];
const linePattern = /"([^"]*)"/g;
const lines = [];
let lineMatch;
while ((lineMatch = linePattern.exec(linesJson))) {
lines.push(lineMatch[1]);
}
pageExtracts[title] = lines;
}
}
// サンプルページの変換を表示
for (const title in pageExtracts) {
const lines = pageExtracts[title];
const markdown = convertToMarkdown(lines);
console.log(`\n=== ${title} ===`);
console.log(markdown.substring(0, 500) + "...");
}
// 最終的な移行プラン
console.log("\n\n==== cosenseからGoogle Docsへの移行計画 ====");
// 1. ディレクトリ構造の提案
console.log("\n1. ディレクトリ構造の提案:");
console.log(`
Google Driveに以下のようなフォルダ構造を作成することをお勧めします:
- tdwda/
- IDR/
- アンケート/
- 実装計画/
- デザイン/
- 要件定義/
- マーケティング/
- メンバー/
- その他/
`);
// 2. 変換プロセス
console.log("\n2. 変換プロセス:");
console.log(`
各ページをMarkdownに変換し、Google Docsにインポートする手順:
1. Cosenseデータからページデータを抽出
2. 各ページをMarkdown形式に変換
3. Google Docsへのインポート方法:
a. Markdownを直接Google Docsにペースト
b. Google DocsアドオンのDocs to Markdownを使用
c. Google DocsへのMarkdownインポート機能を持つ外部ツールを使用
`);
// 3. テンプレート
console.log("\n3. Google Docsテンプレート:");
console.log(`
各ドキュメントには以下のテンプレートを使用することをお勧めします:
---
タイトル: [ページタイトル]
作成日: [日付]
更新日: [日付]
タグ: [関連タグ]
---
# [ページタイトル]
[本文内容]
---
関連ドキュメント:
- [関連ドキュメント1](リンク)
- [関連ドキュメント2](リンク)
`);
// 4. スタイリングガイドライン
console.log("\n4. スタイリングガイドライン:");
console.log(`
Google Docsでのページレスデザインの実現方法:
1. ドキュメントの余白を最小限に設定する
2. シンプルなフォントを使用(Google Fonts から Roboto または Noto Sans JP を推奨)
3. 見出しスタイルを適切に使用
4. ドキュメント全体で一貫したカラースキームを使用
`);
// 5. 自動化ツール
console.log("\n5. 自動化ツール:");
console.log(`
以下のツールを使用して移行プロセスを自動化できます:
1. Node.jsスクリプト: JSONからMarkdownへの変換
2. Google Apps Script: Google Driveへのファイル自動作成
3. Markdownエディタ: VS Code + Markdown Preview Enhanced
`);
// 6. 付録: 変換ルール
console.log("\n6. 付録: 記法変換ルール一覧:");
console.log(`
| Cosense記法 | Markdown記法 | 備考 |
|------------|-------------|------|
| [*** 見出し] | ### 見出し | * の数に応じてレベル変更 |
| [リンク] | [リンク](URL) | 内部リンクの場合はドキュメント名を参照 |
| [テキスト https://...] | [テキスト](https://...) | 名前付きリンク |
| [[ページ名]] | [ページ名](ページ名.md) | 内部リンク |
| code:言語名 | \`\`\`言語名 | コードブロック |
| [user.icon] | **@user** | ユーザーアイコン |
| #タグ | **#タグ** | タグ |
|  インデント | - インデント | インデントをリストに変換 |
`);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment