scrapbox-url-customizer
Next version
scrapbox-url-customizer-2
/icons/hr.icon
移動した
/customize/外部リンクをscrapbox形式に変換するScriptいろいろ
/icons/hr.icon
https://gyazo.com/dd5646098129959f874f8af71204455f
https://gyazo.com/50db0b4f5347586c4e09f307203a640e
選択範囲にあるURLを外部リンク記法にするUserScript
daiiz-paste-urlの代替script
代数関数と超越関数 | 超越関数 - Wikipedia
install
/emoji/warning.iconurl-info-proxyを事前にinstallして下さい
2021-01-05
10:15:04 Wikiwandに対応した
2020-12-05
08:32:01 URL queryを保存するようにした
従来はURL queryを取り除いてしまっていたので、https://rashita.net/blog/?p=25427 などのページのタイトルを正しく取得できなかった
2020-12-03
19:29:51 GitHubのrepo URLの処理方法を変えた
2020-11-30
22:19:25 フラグメント識別子から取得した文字列から改行を除くようにした
2020-11-29
19:09:28 リンクにフラグメント識別子をつけ忘れてたのを直した
18:19:45 フラグメント識別子に部分的に対応した
指定された要素のtextContentをしゅとくする
兄弟要素の中身は取得できないので、Qiitaのようなサイトでは識別子に対応する見出しの文字を取得できない
既知の問題点
ctrl+v版
画像URLも無理やりtitleを取得しようとしてしまう
フラグメント識別子があっても見出しを取得できないサイトがある
e.g. Qiita
utf-8でないhtmlだと文字化けする
daiiz-paste-urlでも同様の問題があった
発生するURLの例:https://www.atmarkit.co.jp/ait/articles/1207/02/news142.html
文字コードを指定してfetchする
一部取得できないURLがある
https://www.oembed.com/
code
copy操作に介入するver.
URL以外のものが混じっていたら何もしない
scrapbox.ioの場合も何もしない
scrapbox-insert-textを使用した
cf. Element: paste イベント - Web API | MDN
code:script.js
import {convert} from '/api/code/takker/scrapbox-url-customizer/convert.js';
import {insertText} from '/api/code/takker/scrapbox-insert-text/script.js';
const cursor = document.getElementById('text-input');
cursor.addEventListener('paste', async (event) => {
const url = (event.clipboardData ?? window.clipboardData).getData('text');
if (!/^https?:\/\/\S+$/.test(url)) return;
if (/^https:\/\/scrapbox.io/.test(url)) return;
event.preventDefault();
const link = await convert(url);
insertText({text: link, cursor: cursor});
});
PopupMenu版
scrapbox-insert-textを使って書き込む
非同期関数を使うと、結果が返ってくるのを待つことなくpopup menuが終了してしまう
なので代わりに独自に入力処理を行うことにする
既知の問題
既に外部リンク記法が選択範囲内に混じっているとうまく行かない
コードブロック中のURLも問答無用で変換してしまう
code:popup.js
import {convertWholeText} from '/api/code/takker/scrapbox-url-customizer/convert.js';
import {insertText} from '/api/code/takker/scrapbox-insert-text/script.js';
scrapbox.PopupMenu.addButton({
title: 'URL',
onClick: text => {
if (!/https?:\/\/\S+/.test(text)) return; // URLがなければ何もしない
const cursor = document.getElementById('text-input')
convertWholeText(text).then(text => insertText({text: text, cursor: cursor}));
// 入力しやすいよう選択範囲を先に消しておく
return '';
},
});
core
code:convert.js
// 複数のURLを含んだテキストをまとめて変換する
export async function convertWholeText(text) {
const urls = text.match(/https?:\/\/\S+/g) ?? [];
if (urls.length === 0) return undefined;
const links = await Promise.all(urls.map(url => convert(url)));
let map = {};
for (const originalUrl of urls) {
const i = urls.indexOf(originalUrl);
if (!linksi) break;
maporiginalUrl= linksi;
}
//console.log(map);
const result = text.replace(/https?:\/\/\S+/g, match => mapmatch ?? match);
//console.log(result);
return result;
}
// urlを外部リンク記法に変換する
export async function convert(url) {
if (!window.getUrlInfo) {
alert('Please install "getUrlInfo from https://scrapbox.io/takker/url-info-proxy"');
return;
}
// hashを分離する
const urlObj = new URL(url);
console.log(urlObj);
let hash = urlObj.hash !== '' ? urlObj.hash.slice(1) : ''; // #をとる
URL.hrefにはフラグメント識別子まで含めたURLが入っているので使えない
代わりにURL.originとURL.pathnaemを使う
code:convert.js
let pureUrl = ${urlObj.origin}${urlObj.pathname}${urlObj.search};
特定のDomainに対して特別な処理をする
Github
code:convert.js
if (urlObj.hostname === 'github.com'
&& /^\/^\/+\/^\/+\/?$/.test(urlObj.pathname)) {
return [${pureUrl} ${urlObj.pathname.slice(1)}];
}
Wikiwand
Wikipediaにredirectする
code:convert.js
if (urlObj.hostname === 'www.wikiwand.com') {
pureUrl = pureUrl.replace(/www\.wikiwand\.com\/(\w+)\//,'$1.wikipedia.org/wiki/');
// 先頭の/を取り除く
hash = hash !== '' ? hash.slice(1) : hash;
}
code:convert.js
console.log(url = ${pureUrl}, hash = ${hash});
const params = hash !== '' ? url=${pureUrl}&hash=${hash} : url=${pureUrl};
console.log(start fetching https://url-info.vercel.app/api/page?${params}...);
const urlInfo = await window.getUrlInfo(https://url-info.vercel.app/api/page?${params})
.then(req => req.response);
if(!urlInfo.title) return undefined;
const result = {
href: urlInfo.url + (!urlInfo?.fragment?.hash ? '' : urlInfo?.fragment?.hash),
title: (!urlInfo?.fragment?.content ? '' : ${urlInfo.fragment.content.replace(/\n/g,'').trim()} | ) + urlInfo.title,
};
return [${result.href} ${result.title}];
}
没コード
scrapbox.PopupMenu.addButtonは非同期関数と相性が悪い
選択範囲内の最初のURLだけ変換してclipboardに貼り付けるか、clipboardから貼り付けるときに介入して変換させるかのどちらかの方法しか取れないな。
いや、scrapbox-insert-textを使えばいけるか?
2020-11-29 13:13:19 いけた
scrapbox-url-customizer#5fc31c0f1280f00000a53fd3
code:script_old1.js
scrapbox.PopupMenu.addButton({
title: 'URL',
onClick: async text => {
if (!window.getUrlInfo) {
alert('Please install "getUrlInfo from https://scrapbox.io/takker/url-info-proxy"');
return;
}
const urls = text.match(/https?:\/\/\S+/g) ?? [];
if (urls.length === 0) return;
const urlInfos = await Promise.all(urls.map(url =>
window.getUrlInfo(https://url-info.vercel.app/api/page?url=${url})
.then(req => req.response)));
let map = {};
for (const originalUrl of urls) {
const i = urls.indexOf(originalUrl);
const {url, title} = urlInfosi;
if (!title) break;
maporiginalUrl= urlInfosi;
}
console.log(map);
const result = text.replace(/https?:\/\/\S+/g, match => mapmatch ?
[${map[match].url} ${map[match].title}] : match);
console.log(result);
return result;
},
});
参考にしたcode
/ci7lus/tweet-card-upload-3
MIT License Copyright (c) 2020 ci7lus
#2021-02-26 00:29:48
#2021-01-05 10:15:40
#2020-12-08 10:43:11
#2020-12-03 19:30:18
#2020-11-30 22:20:04
#2020-11-29 11:30:18