特定のリンクにアイコンを自動生成して付けるUserCSS
スタイル設定用のファイル
不安なら使わないほうが良さげMijinko_SD.icon
externalLinksに設定を書き込むと反映される
code:script.ts
/// <reference no-default-lib="true" />
/// <reference lib="esnext" />
import { Style, toCSSText, writeText } from "./deps.ts";
import {
generateExternalLinkStyle,
generateLinkIconStyle,
LinkInit,
} from "./stylesheetGenerator.ts";
/**
* CSSの生成に使用するオブジェクト
*/
const externalLinks: LinkInit[] = [{
// PDF
url: {
url: ".pdf",
selectorSyntax: "$=",
},
style: {
"content": "'\\f1c1'",
"font-weight": 400, /* use Regular Style */
"margin-right": "1px",
},
}, {
// GitHub
url: [
],
style: {
"content": "'\\f09b'",
"font-weight": 400,
"margin-right": "1px",
},
}, {
// Wikipedia
url: [
],
style: {
"content": "'\\f266'",
"font-weight": 400,
"margin-right": "3px",
},
}, {
// Amazon
url: [
],
style: {
"content": "'\\f270'",
"font-weight": 400,
"margin-right": "1px",
},
}, {
// Twitter
url: [
],
style: {} // 標準でアイコンがあるので不要
}];
/**
* を実装するためのやつ
*/
const extraStyle: Style = {
[
".line .deco-\\. a.link:is(" +
") span.char-index"
]: {
"display": "inline-block",
"width": 0,
"text-indent": "-9999px",
"&:nth-of-type(30) ~ span.char-index": {
"display": "inherit",
"width": "inherit",
"text-indent": "inherit",
},
},
};
const elStyle: Style = generateExternalLinkStyle(externalLinks);
const liStyle: Style = generateLinkIconStyle(externalLinks);
await writeText(toCSSText({ ...elStyle, ...liStyle, ...extraStyle }));
.cssから変換した時のメモ
property: value;を"property": "value",に変換するやつ
正規表現:^(\s*)(.+):\s*(.*)\s*;.*$
置換文字:$1"$2": "$3",
この他に、contentプロパティの値の\をエスケープする必要がある
\ -> \\
CSS生成用のファイル
code:stylesheetGenerator.ts
/// <reference no-default-lib="true" />
/// <reference lib="esnext" />
import { Style } from "./deps.ts";
interface ChildStyle {
}
export type AttributeSelectorOperator = "^=" | "=" | "$=" | "*=" | "~=" | "|=";
export interface URLInit {
url: string;
/**
* 属性セレクタに使用する演算子
* 指定しない場合は^=が用いられる
*/
selectorSyntax: AttributeSelectorOperator;
}
export interface LinkInit {
url: string | URLInit | (string | URLInit)[];
style: ChildStyle;
}
/**
* 外部リンクを区別するUserCSSを生成する関数
*/
export function generateExternalLinkStyle(links: LinkInit[]): Style {
const urls = getURLFromLinkInit(links);
const selector =
".line span:not(.modal-image):not(.pointing-device-map) > a.link:not(.icon):not(:is(" +
urls.reduce(
(pre, crt) => ${pre}[href${crt.selectorSyntax}"${crt.url}"],,
"",
) +
"))::after";
const style: Style = {
"font-family": "'Font Awesome 5 Free', 'Font Awesome 5 Brands'",
"font-weight": "900",
"font-size": "0.8rem",
"content": "'\\f35d'",
"display": "inline-block",
"cursor": "text",
},
};
return style;
}
/**
* 特定のリンクにアイコンをつけるUserCSSを生成する関数
*/
export function generateLinkIconStyle(links: LinkInit[]): Style {
const allURLs = getURLFromLinkInit(links);
const baseSelector = ".line span:not(.deco-\\.) > span > a.link:is(" +
allURLs.reduce(
(pre, crt) => ${pre}[href${crt.selectorSyntax}"${crt.url}"],,
"",
) +
")::before";
/** 先頭にアイコンを付けるための共通のスタイル */
const baseStyle: Style = {
"display": "inline-block",
"width": "1em",
"height": "1em",
"vertical-align": "-1px",
"text-align": "center",
"background-size": "contain",
"background-repeat": "no-repeat",
"cursor": "text",
},
};
const individualStyle: Style = {};
for (const link of links) {
const urls = getURLFromLinkInit(link); const selector = ":is(.line, .line .deco) a.link:is(" +
urls.reduce(
(pre, crt) => ${pre}[href${crt.selectorSyntax}"${crt.url}"],,
"",
) +
")::before";
}
return { ...baseStyle, ...individualStyle };
}
/**
* LinkInitの配列からURLを取り出す
* @param {LinkInit[]} links 取り出し元のオブジェクト
* @return {URLInit[]}
*/
function getURLFromLinkInit(
links: LinkInit[],
defaultOperator: AttributeSelectorOperator = "^=",
): URLInit[] {
const resultURLs: URLInit[] = [];
for (const link of links) {
if (Array.isArray(link.url)) {
for (const url of link.url) {
if (typeof url === "string") {
resultURLs.push({ url: url, selectorSyntax: defaultOperator });
} else {
resultURLs.push(url);
}
}
} else {
const url = link.url;
if (typeof url === "string") {
resultURLs.push({ url: url, selectorSyntax: defaultOperator });
} else {
resultURLs.push(url);
}
}
}
return resultURLs;
}
依存関係をまとめたやつ
code:deps.ts
// CSSテキストを生成するのに使う
export {
toCSSText,
export type {
Style,
// クリップボードにコピーするやつ
生成後のCSS
code:style.css
.line span:not(.modal-image):not(.pointing-device-map) > a.link:not(.icon):not(:is(href$=".pdf",[href^="https://github.com"],[href^="https://raw.githubusercontent.com"],[href^="https://gist.github.com"],[href^="https://ja.wikipedia.org"],[href^="https://en.wikipedia.org"],[href^="https://www.amazon.co.jp"],[href^="https://amazon.co.jp"],[href^="https://twitter.com"],))::after{font-family:'Font Awesome 5 Free', 'Font Awesome 5 Brands';font-weight:900;font-size:0.8rem;content:'\f35d';display:inline-block;cursor:text;}.line span:not(.deco-\.) > span > a.link:is(href$=".pdf",[href^="https://github.com"],[href^="https://raw.githubusercontent.com"],[href^="https://gist.github.com"],[href^="https://ja.wikipedia.org"],[href^="https://en.wikipedia.org"],[href^="https://www.amazon.co.jp"],[href^="https://amazon.co.jp"],[href^="https://twitter.com"],)::before{display:inline-block;width:1em;height:1em;vertical-align:-1px;text-align:center;background-size:contain;background-repeat:no-repeat;cursor:text;}:is(.line, .line .deco) a.link:is(href$=".pdf",)::before{content:'\f1c1';font-weight:400;margin-right:1px;}:is(.line, .line .deco) a.link:is([href^="https://github.com"],[href^="https://raw.githubusercontent.com"],[href^="https://gist.github.com"],)::before{content:'\f09b';font-weight:400;margin-right:1px;}:is(.line, .line .deco) a.link:is([href^="https://ja.wikipedia.org"],[href^="https://en.wikipedia.org"],)::before{content:'\f266';font-weight:400;margin-right:3px;}:is(.line, .line .deco) a.link:is([href^="https://www.amazon.co.jp"],[href^="https://amazon.co.jp"],)::before{content:'\f270';font-weight:400;margin-right:1px;}.line .deco-\. a.link:is([href^="https://ja.wikipedia.org"],[href^="https://en.wikipedia.org"],) span.char-index{display:inline-block;width:0;text-indent:-9999px;}.line .deco-\. a.link:is([href^="https://ja.wikipedia.org"],[href^="https://en.wikipedia.org"],) span.char-index:nth-of-type(30) ~ span.char-index{display:inherit;width:inherit;text-indent:inherit;}