Twitter to Scrapbox
public.icon
フォーマットだけ変えた。こんな感じになるように
Scrapbox英語に移行するのむずすぎ。文字通りのネットワーク効果がある
そしたら画像が追加できなくなったので、画像を追加するように書き換えたい
今の所Gyazoの拡張機能でだいぶ快適だから、緊急ではない code:javascript.js
code:
// ==UserScript==
// @name Twitter to Scrapbox
// @version 0.1
// @description Export selected tweets to Scrapbox format
// @author You
// @grant none
// ==/UserScript==
(function () {
("use strict");
const CONTENT_SELECTOR = "lang"; const TIME_SELECTOR = "time";
function getAccount(tweet) {
const accountElement = tweet.querySelector(ACCOUNT_SELECTOR);
if (accountElement) {
return accountElement.getAttribute("href").substring(1);
}
const spanElements = tweet.querySelectorAll("span");
const filteredSpanElements = Array.from(spanElements).filter((span) =>
span.innerText.startsWith("@")
);
if (filteredSpanElements.length > 0) {
return filteredSpanElements0.innerText.substring(1); }
return "";
}
function getTweetId(tweet) {
const permalink = tweet.querySelector(TWEET_LINK_SELECTOR);
if (!permalink) {
return "";
}
const tweetId = permalink.href.split("/status/")1.split("?")0; return tweetId;
}
function getDate(tweet) {
const timeElement = tweet.querySelector(TIME_SELECTOR);
if (timeElement) {
const date = new Date(timeElement.getAttribute("datetime"));
const monthNames = [
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
];
const day = date.getDate();
const year = date.getFullYear();
return ${month} ${day}, ${year};
}
return "";
}
function formatAccount(account, tweetId, date) {
const profileUrl = https://twitter.com/${account};
if (!tweetId) {
return [@${account} ${profileUrl}];
}
const tweetUrl = https://twitter.com/${account}/status/${tweetId};
return @[${account}] [${tweetUrl} ${date}];
}
function formatTweet(tweet) {
const account = getAccount(tweet);
const contentElement = tweet.querySelector(CONTENT_SELECTOR);
const content = contentElement ? contentElement.innerText : "";
const tweetId = getTweetId(tweet);
const date = getDate(tweet);
return > ${content}\n> ${formatAccount(account, tweetId, date)}\n;
}
function formatTweets(tweets) {
return tweets.map(formatTweet).join("\n");
}
function copyToClipboard(text) {
const el = document.createElement("textarea");
el.value = text;
document.body.appendChild(el);
el.select();
document.execCommand("copy");
document.body.removeChild(el);
}
function onButtonClick() {
const selection = window.getSelection();
let selectedTweets;
if (selection.isCollapsed) {
// 選択されていない場合
selectedTweets = Array.from(document.querySelectorAll(TWEET_SELECTOR));
} else {
// 選択されている場合
selectedTweets = Array.from(
selection.getRangeAt(0).cloneContents().querySelectorAll(TWEET_SELECTOR)
);
}
const formattedText = formatTweets(selectedTweets);
copyToClipboard(formattedText);
}
function addButton() {
const nav = document.querySelector("nav");
if (!nav) {
// navが存在しない場合、1秒後に再試行
setTimeout(addButton, 1000);
return;
}
const button = document.createElement("button");
button.textContent = "Export to Scrapbox";
button.style.position = "fixed";
button.style.top = "10px";
button.style.right = "10px";
button.style.zIndex = 1000;
button.style.backgroundColor = "#1da1f2";
button.style.border = "none";
button.style.borderRadius = "4px";
button.style.color = "white";
button.style.padding = "6px 12px";
button.style.fontSize = "14px";
button.style.cursor = "pointer";
button.addEventListener("click", onButtonClick);
document.body.appendChild(button);
}
addButton();
})();