Skip to content

Instantly share code, notes, and snippets.

@KEINOS
Last active December 10, 2019 14:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save KEINOS/4dd67a06c70134581358f4a486867939 to your computer and use it in GitHub Desktop.
Save KEINOS/4dd67a06c70134581358f4a486867939 to your computer and use it in GitHub Desktop.
A bookmarklet generator for Mastodon that helps toot a visiting web page's URL and the title. No OAuth login required.
javascript: (function () {
var LF = '\n';
var CR = '\r';
var BR = LF;
var ZWSP = unescape('%u200B');
var EMOJI_QIITA = ':qiita:';
var EMOJI_TWITTER = ':twitter:';
var CSS_SIZE_POPWINDOW = 'width=470,height=288';
function addCodeBlock(str)
{
var code_block = '```';
if (! str.trim()) {
return '';
}
return code_block + BR + str.trim() + BR + code_block;
}
function addHeaderQuote(str)
{
var lines = str.split(BR);
var result = '';
for (var i=0 ; i < lines.length ; i++ ) {
if (! (i == lines.length-1 && lines[i].length == 0)) {
result += '${msg_qutotation_header}' + lines[i].trim() + BR;
}
}
return result;
}
function addParenthesisTitle(str)
{
return '${title_quotation_begin}' + str.trim() + '${title_quotation_end}';
}
function breakLineWithFixWidth(s)
{
var str = s.trim().split('');
var reg_hankaku = new RegExp('^%uFF');
var reg_zenkaku = new RegExp('^%u');
var width_max = ${width_linebreak}-1;
var result = '';
var char_tmp = '';
var len = 0;
for (var i=0 ; i < str.length ; i++) {
char_tmp = str[i];
code_tmp = escape(char_tmp);
if (code_tmp.match(reg_hankaku)){
len++;
} else {
if (code_tmp.match(reg_zenkaku)){
len+=2;
} else {
len++;
}
}
if (char_tmp == BR) {
len = 0;
}
result = result + char_tmp;
if (len > width_max) {
result += BR;
len = 0;
}
}
return result;
}
function getSelectedStringAsQuote()
{
var s = '';
if (window.navigator.appName == 'Microsoft Internet Explorer') {
s = document.selection.createRange().text;
} else {
s = window.getSelection();
}
if (!s || s == '') {
s = '';
} else {
s = s + BR;
s = uniformBRtoLF(s);
if (${enable_linebreak}) {
s = breakLineWithFixWidth(s);
}
s = addHeaderQuote(s);
}
return s.trim();
}
function isUrlTwitter(url)
{
var reg_url_twitter = new RegExp('^https://twitter.com/');
return url.match(reg_url_twitter);
}
function isUrlQiita(url)
{
var reg_url_qiita = new RegExp('^https://qiita.com/');
return url.match(reg_url_qiita);
}
function isUrlQiitadon(url)
{
var reg_url_qiitadon = new RegExp('^https://qiitadon.com/');
return url.match(reg_url_qiitadon);
}
function makeComment()
{
var str = getSelectedStringAsQuote();
var tit = document.title;
var url = document.URL;
var ico = '';
var ret = '';
if (isUrlQiita(url)) {
ico = ZWSP + EMOJI_QIITA + ZWSP
ret += addCodeBlock(str) + BR;
ret += ico + addParenthesisTitle(trimQiitaFromTitle(tit));
ret += BR + url;
} else if (isUrlQiitadon(url)) {
ret += str.trim() + BR;
ret += '${msg_qutotation_header} ' + url;
} else if (isUrlTwitter(url)) {
ico = ZWSP + EMOJI_TWITTER + ZWSP;
ret += addCodeBlock(str) + BR;
ret += ico + url;
} else {
ret += addCodeBlock(str) + BR;
ret += addParenthesisTitle(tit) + BR;
ret += url;
}
return BR + ret.trim();
}
function trimQiitaFromTitle(title)
{
var reg_qiita = new RegExp('- Qiita');
return title.replace(reg_qiita,'').trim();
}
function uniformBRtoLF(str)
{
var reg_return = new RegExp(CR,'g');
return str.replace( reg_return ,'');
}
var str = encodeURIComponent( makeComment() );
var tit = "https://${your_instance}/intent/statuses/new?text=" + str;
window.open(tit, 'tooting', CSS_SIZE_POPWINDOW);
})();
void(0);
<?php
// constants
define('LF', "\n");
define('CR', "\r");
define('CRLF', "\r\n");
define('MINIFY_STRING', '"(?:[^"\\\]|\\\.)*"|\'(?:[^\'\\\]|\\\.)*\'');
define('MINIFY_COMMENT_CSS', '/\*[\s\S]*?\*/');
define('MINIFY_COMMENT_HTML', '<!\-{2}[\s\S]*?\-{2}>');
define('MINIFY_COMMENT_JS', '//[^\n]*');
define('MINIFY_PATTERN_JS', '/[^\n]+?/[gimuy]*');
define('MINIFY_HTML', '<[!/]?[a-zA-Z\d:.-]+[\s\S]*?>');
define('MINIFY_HTML_ENT', '&(?:[a-zA-Z\d]+|\#\d+|\#x[a-fA-F\d]+);');
define('MINIFY_HTML_KEEP', '<pre(?:\s[^<>]*?)?>[\s\S]*?</pre>|<code(?:\s[^<>]*?)?>[\s\S]*?</code>|<script(?:\s[^<>]*?)?>[\s\S]*?</script>|<style(?:\s[^<>]*?)?>[\s\S]*?</style>|<textarea(?:\s[^<>]*?)?>[\s\S]*?</textarea>');
function minify($pattern, $input)
{
return preg_split('#(' . implode('|', $pattern) . ')#', $input, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
}
function minifyJS($input, $comment = 2, $quote = 2)
{
if (!is_string($input) || !$input = normalizeLineBreak(trim($input))) {
return $input;
}
$output = $prev = "";
foreach (minify([MINIFY_COMMENT_CSS, MINIFY_STRING, MINIFY_COMMENT_JS, MINIFY_PATTERN_JS], $input) as $part) {
if (trim($part) === "") {
continue;
}
if ($comment !== 1 && (
strpos($part, '//') === 0 || // Remove inline comment(s)
strpos($part, '/*') === 0 && substr($part, -2) === '*/'
)) {
if (
$comment === 2 && (
// Detect special comment(s) from the third character. It should be a `!` or `*` → `/*! keep */` or `/** keep */`
strpos('*!', $part[2]) !== false ||
// Detect license comment(s) from the content. It should contains character(s) like `@license`
stripos($part, '@licence') !== false || // noun
stripos($part, '@license') !== false || // verb
stripos($part, '@preserve') !== false
)
) {
$output .= $part;
}
continue;
}
if ($part[0] === '/' && (substr($part, -1) === '/' || preg_match('#\/[gimuy]*$#', $part))) {
//
} elseif ($part[0] === '"' && substr($part, -1) === '"' || $part[0] === "'" && substr($part, -1) === "'") {
$output .= $part;
} else {
$output .= minifyJSUnion($part);
}
$prev = $part;
}
return trim($output);
}
function minifyJSUnion($input)
{
return preg_replace([
// Remove white–space(s) around punctuation(s) [^1]
'#\s*([!%&*\(\)\-=+\[\]\{\}|;:,.<>?\/])\s*#',
// Remove the last semi–colon and comma [^2]
'#[;,]([\]\}])#',
// Replace `true` with `!0` and `false` with `!1` [^3]
'#\btrue\b#', '#\bfalse\b#', '#\b(return\s?)\s*\b#',
// Replace `new Array(x)` with `[x]` … [^4]
'#\b(?:new\s+)?Array\((.*?)\)#', '#\b(?:new\s+)?Object\((.*?)\)#'
], [
// [^1]
'$1',
// [^2]
'$1',
// [^3]
'!0', '!1', '$1',
// [^4]
'[$1]', '{$1}'
], $input);
}
function normalizeLineBreak($s)
{
return str_replace([CRLF, CR], LF, $s);
}
<?php
//header("Content-type: text/text; charset=utf-8");
///////////////////////////////////////////////////////////////////////////////
// Qiitadon 用引用トゥートのブックマークレット・ジェネレーター
///////////////////////////////////////////////////////////////////////////////
$your_instance = 'qiitadon.com';
$your_language = 'ja'; // "ja" or "en"
$enable_linebreak = 'true'; // 固定長の設定。false = 引用時に固定長で改行しない。
$width_linebreak = 12*2; // 固定長幅。引用時の1行の文字幅。全角文字数*2
$export_as_link = 'true'; // 'true' => HTML 表示 'false' => Minified JS
///////////////////////////////////////////////////////////////////////////////
// ----------------------------------------------------------------------------
// Basic INFO bout the code
//
// Copyleft. Do whatever you want with it.
// ----------------------------------------------------------------------------
$version = "20191210_2325";
$url_original = "https://paiza.io/projects/h21KPTgHM3Xo5-pbQMIrRw";
$url_gist_last = "https://gist.github.com/KEINOS/4dd67a06c70134581358f4a486867939";
$ulr_gist_prev = "https://gist.github.com/KEINOS/4dd67a06c70134581358f4a486867939/d1175cc375a12d56cdc9ce22ef2824dea7f4d883";
$url_reference = "http://let.hatelabo.jp/pacochi/let/hJme9dvn644a";
$collaborators = [ "@KEINOS@qiitadon.com","@hidao@qiitadon.com","@htomine@qiitdon.com" ];
// ----------------------------------------------------------------------------
// Messages and settings according to the language.
// ----------------------------------------------------------------------------
// Quotation
$title_quotation_begin_ja = '『';
$title_quotation_begin_en = '“';
$title_quotation_end_ja = '』';
$title_quotation_end_en = '”';
$title_link_ja = 'このページを🐘';
$title_link_en = '🐘 This Page!';
$msg_qutotation_header = '> ';
$msg_drag_and_drop_ja = '上のリンクをブックマークバーにドラッグ&ドロップしてください。';
$msg_grag_and_drop_en = 'Drag and drop the link above to your bookmark bar.';
// Set messages according to the language.
$title_quotation_begin = ( $your_language == 'ja' ) ? $title_quotation_begin_ja : $title_quotation_begin_en;
$title_quotation_end = ( $your_language == 'ja' ) ? $title_quotation_end_ja : $title_quotation_end_en;
$title_link = ( $your_language == 'ja' ) ? $title_link_ja : $title_link_en;
$title_link_enc = urlencode($title_link);
$mst_drag_and_drop = ( $your_language == 'ja' ) ? $msg_drag_and_drop_ja : $msg_grag_and_drop_en;
// ----------------------------------------------------------------------------
// Main
// ----------------------------------------------------------------------------
// Include PHP script for minification of the javascript.
include_once('functions.php');
// Read javascript to minify.
$script = file_get_contents('bookmarklet.js');
$script = addcslashes($script,'\\');
$script = addcslashes($script,'"');
// Script hash to recognize changes
$hash_script = substr(hash('md5', $script),0,6);
// Replace PHP variables in javascript
eval("\$script = \"$script\";");
// Minifies javascript
$script = minifyJs($script);
// Export the javascript for bookmarklet
if($export_as_link=='true'){
// Exports as HTML link
$script = urlencode($script);
$script = str_replace('+','%20',$script);
$script = str_replace('javascript%3A%28','javascript:(', $script);
$script = str_replace('%29%28%29%3Bvoid%280%29%3B', ')(); void(0);', $script);
echo<<<EOL
<div>
<div style='padding:1em; margin:1em;'>
<a style='border:1px solid black;padding:1em' href='${script}' title='${title_link_enc}'>${title_link}</a>
</div>
<div>${mst_drag_and_drop}</div>
<div style='font-size:small;'>Ver: ${version} | <a href='${url_gist_last}' target='_blank'>View on Gist</a> | ${url_original} </div>
<div style='font-size:small;'>Script Hash: ${hash_script}</div>
</div>
EOL;
} else {
// Exports as raw minifyed javascript
echo $script;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment