您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Replace Pastebin code blocks in markdown mode with Shiki syntax highlighting and copy button
// ==UserScript== // @name Pastebin Shiki Highlighter Codeblocks for Markdown // @namespace https://pastebin.com/ // @version 1.3.6 // @description Replace Pastebin code blocks in markdown mode with Shiki syntax highlighting and copy button // @match https://pastebin.com/* // @author BourbonCrow // @icon https://raw.githubusercontent.com/shikijs/shiki/main/docs/public/logo.svg // @grant GM_addStyle // @run-at document-start // @license MIT // ==/UserScript== (function () { "use strict"; // Hide raw markdown code instantly if (typeof GM_addStyle === "function") { GM_addStyle(` .source.markdown code[class^="language-"], .source.markdown pre > code[class^="language-"] { display: none !important; } `); } function getHeaderHeight() { const header = document.querySelector(".header"); return header ? header.offsetHeight || 0 : 0; } function init() { if (document.readyState === "loading") { document.addEventListener("DOMContentLoaded", init); return; } // Inject ESM script const script = document.createElement("script"); script.type = "module"; script.innerHTML = ` import { codeToHtml } from 'https://cdn.jsdelivr.net/npm/shiki/+esm'; // Canonical language definitions const languages = { abap:{display:"ABAP",aliases:[]}, actionscript:{display:"ActionScript",aliases:["actionscript-3"]}, ada:{display:"Ada",aliases:[]}, "angular-html":{display:"Angular HTML",aliases:[]}, "angular-ts":{display:"Angular TypeScript",aliases:[]}, apache:{display:"Apache Conf",aliases:[]}, ansi:{display:"ANSI",aliases:[]}, apex:{display:"Apex",aliases:[]}, apl:{display:"APL",aliases:[]}, applescript:{display:"AppleScript",aliases:[]}, ara:{display:"Ara",aliases:[]}, asciidoc:{display:"AsciiDoc",aliases:["adoc"]}, asm:{display:"Assembly",aliases:[]}, astro:{display:"Astro",aliases:[]}, awk:{display:"AWK",aliases:[]}, ballerina:{display:"Ballerina",aliases:[]}, bat:{display:"Batch File",aliases:["batch"]}, beancount:{display:"Beancount",aliases:[]}, berry:{display:"Berry",aliases:["be"]}, bibtex:{display:"BibTeX",aliases:[]}, bicep:{display:"Bicep",aliases:[]}, blade:{display:"Blade",aliases:[]}, bsl:{display:"1C (Enterprise)",aliases:["1c"]}, c:{display:"C",aliases:[]}, cadence:{display:"Cadence",aliases:["cdc"]}, cairo:{display:"Cairo",aliases:[]}, clarity:{display:"Clarity",aliases:[]}, clojure:{display:"Clojure",aliases:["clj"]}, cmake:{display:"CMake",aliases:[]}, cobol:{display:"COBOL",aliases:[]}, codeowners:{display:"CODEOWNERS",aliases:[]}, codeql:{display:"CodeQL",aliases:["ql"]}, coffee:{display:"CoffeeScript",aliases:["coffeescript"]}, "common-lisp":{display:"Common Lisp",aliases:["lisp"]}, coq:{display:"Coq",aliases:[]}, cpp:{display:"C++",aliases:["c++"]}, crystal:{display:"Crystal",aliases:[]}, csharp:{display:"C#",aliases:["cs","c#"]}, css:{display:"CSS",aliases:[]}, csv:{display:"CSV",aliases:[]}, cue:{display:"CUE",aliases:[]}, cypher:{display:"Cypher",aliases:["cql"]}, d:{display:"D",aliases:[]}, dart:{display:"Dart",aliases:[]}, dax:{display:"DAX",aliases:[]}, desktop:{display:"Desktop",aliases:[]}, diff:{display:"Diff",aliases:[]}, docker:{display:"Dockerfile",aliases:["dockerfile"]}, dotenv:{display:"dotEnv",aliases:[]}, "dream-maker":{display:"Dream Maker",aliases:[]}, edge:{display:"Edge",aliases:[]}, elixir:{display:"Elixir",aliases:[]}, elm:{display:"Elm",aliases:[]}, "emacs-lisp":{display:"Emacs Lisp",aliases:["elisp"]}, erb:{display:"ERB",aliases:[]}, erlang:{display:"Erlang",aliases:["erl"]}, fennel:{display:"Fennel",aliases:[]}, fish:{display:"Fish",aliases:[]}, fluent:{display:"Fluent",aliases:["ftl"]}, "fortran-fixed-form":{display:"Fortran (Fixed Form)",aliases:["f77"]}, "fortran-free-form":{display:"Fortran (Free Form)",aliases:["f90","f95","f03","f08","f18"]}, fsharp:{display:"F#",aliases:["fs","f#"]}, gdresource:{display:"GDResource",aliases:[]}, gdscript:{display:"GDScript",aliases:[]}, gdshader:{display:"GDShader",aliases:[]}, genie:{display:"Genie",aliases:[]}, gherkin:{display:"Gherkin",aliases:[]}, "git-commit":{display:"Git Commit Message",aliases:[]}, "git-rebase":{display:"Git Rebase Message",aliases:[]}, gleam:{display:"Gleam",aliases:[]}, "glimmer-js":{display:"Glimmer JS",aliases:["gjs"]}, "glimmer-ts":{display:"Glimmer TS",aliases:["gts"]}, glsl:{display:"GLSL",aliases:[]}, gnuplot:{display:"Gnuplot",aliases:[]}, go:{display:"Go",aliases:[]}, graphql:{display:"GraphQL",aliases:["gql"]}, groovy:{display:"Groovy",aliases:[]}, hack:{display:"Hack",aliases:[]}, haml:{display:"Ruby Haml",aliases:[]}, handlebars:{display:"Handlebars",aliases:["hbs"]}, haskell:{display:"Haskell",aliases:["hs"]}, haxe:{display:"Haxe",aliases:[]}, hcl:{display:"HashiCorp HCL",aliases:[]}, hjson:{display:"Hjson",aliases:[]}, hlsl:{display:"HLSL",aliases:[]}, html:{display:"HTML",aliases:[]}, "html-derivative":{display:"HTML (Derivative)",aliases:[]}, http:{display:"HTTP",aliases:[]}, hxml:{display:"HXML",aliases:[]}, hy:{display:"Hy",aliases:[]}, imba:{display:"Imba",aliases:[]}, ini:{display:"INI",aliases:["properties"]}, java:{display:"Java",aliases:[]}, javascript:{display:"JavaScript",aliases:["js"]}, jinja:{display:"Jinja",aliases:[]}, jison:{display:"Jison",aliases:[]}, json:{display:"JSON",aliases:[]}, json5:{display:"JSON5",aliases:[]}, jsonc:{display:"JSON with Comments",aliases:[]}, jsonl:{display:"JSON Lines",aliases:[]}, jsonnet:{display:"Jsonnet",aliases:[]}, jssm:{display:"JSSM",aliases:["fsl"]}, jsx:{display:"JSX",aliases:[]}, julia:{display:"Julia",aliases:["jl"]}, kotlin:{display:"Kotlin",aliases:["kt","kts"]}, kusto:{display:"Kusto",aliases:["kql"]}, latex:{display:"LaTeX",aliases:[]}, lean:{display:"Lean 4",aliases:["lean4"]}, less:{display:"Less",aliases:[]}, liquid:{display:"Liquid",aliases:[]}, llvm:{display:"LLVM IR",aliases:[]}, log:{display:"Log file",aliases:[]}, logo:{display:"Logo",aliases:[]}, lua:{display:"Lua",aliases:[]}, luau:{display:"Luau",aliases:[]}, make:{display:"Makefile",aliases:["makefile"]}, markdown:{display:"Markdown",aliases:["md"]}, marko:{display:"Marko",aliases:[]}, matlab:{display:"MATLAB",aliases:[]}, mdc:{display:"MDC",aliases:[]}, mdx:{display:"MDX",aliases:[]}, mermaid:{display:"Mermaid",aliases:["mmd"]}, mipsasm:{display:"MIPS Assembly",aliases:["mips"]}, mojo:{display:"Mojo",aliases:[]}, move:{display:"Move",aliases:[]}, narrat:{display:"Narrat Language",aliases:["nar"]}, nextflow:{display:"Nextflow",aliases:["nf"]}, nginx:{display:"Nginx",aliases:[]}, nim:{display:"Nim",aliases:[]}, nix:{display:"Nix",aliases:[]}, nushell:{display:"nushell",aliases:["nu"]}, "objective-c":{display:"Objective-C",aliases:["objc"]}, "objective-cpp":{display:"Objective-C++",aliases:[]}, ocaml:{display:"OCaml",aliases:[]}, pascal:{display:"Pascal",aliases:[]}, perl:{display:"Perl",aliases:[]}, php:{display:"PHP",aliases:[]}, plsql:{display:"PL/SQL",aliases:[]}, po:{display:"Gettext PO",aliases:["pot","potx"]}, polar:{display:"Polar",aliases:[]}, postcss:{display:"PostCSS",aliases:[]}, powerquery:{display:"PowerQuery",aliases:[]}, powershell:{display:"PowerShell",aliases:["ps","ps1"]}, prisma:{display:"Prisma",aliases:[]}, prolog:{display:"Prolog",aliases:[]}, proto:{display:"Protocol Buffer 3",aliases:["protobuf"]}, pug:{display:"Pug",aliases:["jade"]}, puppet:{display:"Puppet",aliases:[]}, purescript:{display:"PureScript",aliases:[]}, python:{display:"Python",aliases:["py"]}, qml:{display:"QML",aliases:[]}, qmldir:{display:"QML Directory",aliases:[]}, qss:{display:"Qt Style Sheets",aliases:[]}, r:{display:"R",aliases:[]}, racket:{display:"Racket",aliases:[]}, raku:{display:"Raku",aliases:["perl6"]}, razor:{display:"ASP.NET Razor",aliases:[]}, reg:{display:"Windows Registry Script",aliases:[]}, regexp:{display:"RegExp",aliases:["regex"]}, rel:{display:"Rel",aliases:[]}, riscv:{display:"RISC-V",aliases:[]}, rst:{display:"reStructuredText",aliases:[]}, ruby:{display:"Ruby",aliases:["rb"]}, rust:{display:"Rust",aliases:["rs"]}, sas:{display:"SAS",aliases:[]}, sass:{display:"Sass",aliases:[]}, scala:{display:"Scala",aliases:[]}, scheme:{display:"Scheme",aliases:[]}, scss:{display:"SCSS",aliases:[]}, sdbl:{display:"1C (Query)",aliases:["1c-query"]}, shaderlab:{display:"ShaderLab",aliases:["shader"]}, shellscript:{display:"Shell",aliases:["bash","sh","zsh"]}, shellsession:{display:"Shell Session",aliases:["console"]}, smalltalk:{display:"Smalltalk",aliases:[]}, solidity:{display:"Solidity",aliases:[]}, soy:{display:"Closure Templates",aliases:["closure-templates"]}, sparql:{display:"SPARQL",aliases:[]}, splunk:{display:"Splunk Query Language",aliases:["spl"]}, sql:{display:"SQL",aliases:[]}, "ssh-config":{display:"SSH Config",aliases:[]}, stata:{display:"Stata",aliases:[]}, stylus:{display:"Stylus",aliases:["styl"]}, svelte:{display:"Svelte",aliases:[]}, swift:{display:"Swift",aliases:[]}, "system-verilog":{display:"SystemVerilog",aliases:[]}, systemd:{display:"Systemd Units",aliases:[]}, talonscript:{display:"TalonScript",aliases:["talon"]}, tasl:{display:"Tasl",aliases:[]}, tcl:{display:"Tcl",aliases:[]}, templ:{display:"Templ",aliases:[]}, terraform:{display:"Terraform",aliases:["tf","tfvars"]}, tex:{display:"TeX",aliases:[]}, toml:{display:"TOML",aliases:[]}, "ts-tags":{display:"TypeScript with Tags",aliases:["lit"]}, tsv:{display:"TSV",aliases:[]}, tsx:{display:"TSX",aliases:[]}, turtle:{display:"Turtle",aliases:[]}, twig:{display:"Twig",aliases:[]}, typescript:{display:"TypeScript",aliases:["ts"]}, typespec:{display:"TypeSpec",aliases:["tsp"]}, typst:{display:"Typst",aliases:["typ"]}, v:{display:"V",aliases:[]}, vala:{display:"Vala",aliases:[]}, vb:{display:"Visual Basic",aliases:["cmd"]}, verilog:{display:"Verilog",aliases:[]}, vhdl:{display:"VHDL",aliases:[]}, viml:{display:"Vim Script",aliases:["vim","vimscript"]}, vue:{display:"Vue",aliases:[]}, "vue-html":{display:"Vue HTML",aliases:[]}, "vue-vine":{display:"Vue Vine",aliases:[]}, vyper:{display:"Vyper",aliases:["vy"]}, wasm:{display:"WebAssembly",aliases:[]}, wenyan:{display:"Wenyan",aliases:["文言"]}, wgsl:{display:"WGSL",aliases:[]}, wikitext:{display:"Wikitext",aliases:["mediawiki","wiki"]}, wit:{display:"WebAssembly Interface Types",aliases:[]}, wolfram:{display:"Wolfram",aliases:["wl"]}, xml:{display:"XML",aliases:[]}, xsl:{display:"XSL",aliases:[]}, yaml:{display:"YAML",aliases:["yml"]}, zenscript:{display:"ZenScript",aliases:[]}, zig:{display:"Zig",aliases:[]}, plaintext:{display:"Plain Text",aliases:["text","txt"]} }; // Build alias map const aliasMap = {}; for (const [key, { aliases }] of Object.entries(languages)) { aliasMap[key] = key; for (const alias of aliases) { aliasMap[alias.toLowerCase()] = key; } } function resolveLanguage(lang) { if (!lang) return "Plain Text"; const key = lang.toLowerCase(); const canonical = aliasMap[key] || "plaintext"; return languages[canonical].display; } async function highlight() { const markdownSource = document.querySelector('.source.markdown'); if (!markdownSource) return; const codeBlocks = markdownSource.querySelectorAll("code[class^='language-']"); for (const block of codeBlocks) { try { const rawCode = block.textContent; let lang = "plaintext"; const match = block.className.match(/language-(\\w+)/); if (match) lang = match[1]; const displayLang = resolveLanguage(lang); const html = await codeToHtml(rawCode, { lang, theme: 'github-dark' }); const wrapper = document.createElement("div"); wrapper.className = "shiki-wrapper"; wrapper.innerHTML = \` <div class="shiki-header"> <span class="shiki-lang">\${displayLang}</span> <button class="shiki-copy">Copy code</button> </div> \${html} \`; const pre = block.closest('pre') || block.parentElement; pre.replaceWith(wrapper); const copyBtn = wrapper.querySelector(".shiki-copy"); const header = wrapper.querySelector(".shiki-header"); function getButtonRelativePosition() { const btnRect = copyBtn.getBoundingClientRect(); const wrapperRect = wrapper.getBoundingClientRect(); return { top: btnRect.top - wrapperRect.top, right: wrapperRect.right - btnRect.right }; } function updatePosition() { const headerHeight = (${getHeaderHeight.toString()})(); const wrapperRect = wrapper.getBoundingClientRect(); const btnHeight = copyBtn.offsetHeight; const margin = 7; const shouldFloat = wrapperRect.top < headerHeight + margin && wrapperRect.bottom > headerHeight + btnHeight + margin; if (shouldFloat) { if (!copyBtn.classList.contains('floating')) { copyBtn.classList.add('floating'); copyBtn.style.position = 'fixed'; copyBtn.style.zIndex = '999'; } const targetTop = Math.min( Math.max(headerHeight + margin, wrapperRect.top + margin), wrapperRect.bottom - btnHeight - margin ); const targetRight = window.innerWidth - wrapperRect.right + 8; copyBtn.style.top = targetTop + 'px'; copyBtn.style.right = targetRight + 'px'; copyBtn.style.left = 'auto'; } else { if (copyBtn.classList.contains('floating')) { copyBtn.classList.remove('floating'); copyBtn.style.position = 'absolute'; copyBtn.style.zIndex = '1'; } copyBtn.style.top = margin + 'px'; copyBtn.style.right = '8px'; copyBtn.style.left = 'auto'; } } let ticking = false; const requestTick = () => { if (!ticking) { requestAnimationFrame(() => { updatePosition(); ticking = false; }); ticking = true; } }; window.addEventListener("scroll", requestTick, { passive: true }); window.addEventListener("resize", requestTick, { passive: true }); setTimeout(updatePosition, 100); } catch (error) { console.warn('Highlight failed:', error); } } } highlight(); document.addEventListener("click", (e) => { if (e.target.classList.contains("shiki-copy")) { const code = e.target.closest(".shiki-wrapper").querySelector("code").innerText; navigator.clipboard.writeText(code); e.target.textContent = "Copied!"; setTimeout(() => (e.target.textContent = "Copy code"), 1500); } }); `; document.head.appendChild(script); // Styles GM_addStyle(` .shiki-wrapper { margin: 1em 0; border: 1px solid #171717; border-radius: 8px; overflow: hidden; background: #171717; position: relative; } .shiki-header { display: flex; justify-content: space-between; align-items: center; background: #171717; color: #ccc; font-size: 12px; font-family: sans-serif; padding: 0.3em 0.6em; position: relative; } .shiki-header .shiki-lang { user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; font-weight: bold; color: #bbb; flex: 1; } .shiki-header .shiki-copy { background: #171717; border-radius: 3px; border: none; color: #bbb; cursor: pointer; font-size: 12px; padding: 2px 6px; position: absolute; top: 7px; right: 8px; z-index: 1; margin-left: auto; } .shiki-header .shiki-copy:hover { color: white; } pre.shiki { margin: 0; padding: 1em; overflow-x: auto; font-size: 14px; line-height: 1.5; border: 1px solid #171717; background: none !important; } pre.shiki code { background: none !important; } .source.markdown .highlighted-code .source code { background: none !important; color: inherit !important; } `); } init(); })();