Tweetを取り込むPopup menu
より(一部改変)
install方法
code:import.js
import '/api/code/bluemountain-theme/Tweetを取り込むPopup menu/script.js';
以下code
code:script.js
import {insertText} from '/api/code/bluemountain-theme/scrapbox-insert-text/script.js';
import {convertWholeText} from '/api/code/bluemountain-theme/Tweetを取り込むPopup menu/convert.js';
scrapbox.PopupMenu.addButton({
title: 'Tweet', // Font Awesomeでないと文字化けします
onClick: text => {
if (!/https:\/\/twitter\.com\S+\/status\/\d+/.test(text)) return; // URLがなければ何もしない
const cursor = document.getElementById('text-input')
Promise.all(text.split('\n').map(line => {
const matches = line.match(/^\s+|.*/g);
const indent = /^\s+$/.test(matches0)? matches0 : ''; const content = /^\s+$/.test(matches0)? matches1 : matches0; return convertWholeText(content, indent)
})).then(lines => insertText({text: lines.join('\n'), cursor: cursor}));
// 入力しやすいよう選択範囲を先に消しておく
return '';
},
});
tweet情報を整形して返す
code:convert.js
import {getTweetInfo} from '/api/code/bluemountain-theme/Tweetを取り込むPopup menu/getTweetInfo.js';
// 複数のURLを含んだテキストをまとめて変換する
export async function convertWholeText(text,indent) {
const tweetRegExp = /https:\/\/twitter\.com\S+\/status\/\d+(?:\?s=\d+)?/g;
const urls = text.match(tweetRegExp) ?? [];
if (urls.length === 0) return undefined;
const tweets = (await Promise.all(urls.map(url => getTweetInfo({tweetUrl: url}))))
.map(tweetInfo => convert({
tweetInfo,
indent,
}));
console.log(tweets);
let map = {};
for (const originalUrl of urls) {
const i = urls.indexOf(originalUrl);
}
//console.log(map);
const result = text.replace(tweetRegExp, match => mapmatch ?? match); //console.log(result);
return result;
}
引用の形を決めるところ
この関数をいじってお好みのformatにしてください
code:convert.js
function convert({tweetInfo, indent}) {
return [...tweetInfo.content.map(text => ${indent}> ${text}),
${indent}> \t@[${tweetInfo.signatureID}.icon] [${tweetInfo.date.href} ${tweetInfo.date.text}]].join('\n'); //@blu3mo 改変
}
tweet取得処理
code:getTweetInfo.js
export async function getTweetInfo({tweetUrl} = {}) {
if (!window.getTweetInfo) {
return;
}
try {
const tweet = await window.getTweetInfo(https://publish.twitter.com/oembed?url=${tweetUrl})
.then(req => req.response);
// 埋め込み用HTMLを解析する
const dummy = document.createElement('div');
dummy.insertAdjacentHTML('beforeend', tweet.html);
console.log(tweet.html);
// <blockquote>を取得
const blockquote =dummy.getElementsByTagName('blockquote')?.0; // 要素に分解
// tweet本文をscrapbox記法に変換
contentDOM?.getElementsByTagName('a')
?.forEach?.(link => link.innerHTML = [${link.href} ${link.textContent}]);
contentDOM?.getElementsByTagName('br')
?.forEach?.(br => br.innerHTML =\n);
// 各種情報を詰め込んで返す
return {
author: {
name: tweet.author_name,
url: tweet.author_url,
},
content: contentDOM?.textContent.split('\n'),
signatureID: signatureDOM?.textContent.split('@').pop().slice(0, -2), //@blu3mo idのみ返すように改変
date : {
href: dateDOM?.href,
text: dateDOM?.textContent,
},
};
} catch(e) {
console.error(e);
}
}