Skip to content

Commit

Permalink
modified: a.ts
Browse files Browse the repository at this point in the history
  • Loading branch information
phothinmg committed Aug 22, 2024
1 parent 2e95dd6 commit b457e2c
Show file tree
Hide file tree
Showing 10 changed files with 294 additions and 5 deletions.
2 changes: 1 addition & 1 deletion a.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
import { registerExtension, type ShowdownExtension } from "./dist/index.js";

4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,9 @@
"tsup": "^8.0.2",
"tsx": "^4.16.5",
"typescript": "^5.4.5"
},
"dependencies": {
"showdown-mathjax": "^1.0.7",
"showdown-prism": "^1.0.7"
}
}
27 changes: 27 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

59 changes: 59 additions & 0 deletions src/extensions/copy_code.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import {
registerExtension,
type MmExtension,
} from "../manage-extensions/index.js";

/**
*
*/
declare global {
interface Window {
copyCodeListener?: boolean;
}
}

/**
* Adds an event listener to the window that listens for clicks.
* @param {String} className The class name of the button.
*/
function addListener(className: string) {
if (typeof window !== "undefined" && window.copyCodeListener !== true) {
window.addEventListener("click", (e) => {
const target = e.target as HTMLElement;
if (
target?.classList?.contains(className) &&
target.nextElementSibling?.tagName === "PRE"
) {
navigator.clipboard.writeText(
(target.nextElementSibling as HTMLPreElement).innerText
);
}
});
window.copyCodeListener = true;
}
}
/**
* showdownCopyCode
*
* Showdown extension that adds a button above code blocks to quickly and easily copy code to the clipboard.
*
* @function
*/
function copyCode({ className = "copy-code" } = {}): MmExtension[] {
return [
{
type: "output",
filter: function (text: string) {
addListener(className);

return text.replace(
/<pre.*><code/g,
`<button class="${className}">Copy</button>$&`
);
},
},
];
}

registerExtension("copyCode", copyCode());
export default copyCode;
75 changes: 75 additions & 0 deletions src/extensions/custom_class.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import {
registerExtension,
type MmExtension,
} from "../manage-extensions/index.js";

/**
*
* This extension was inspired by
*
* https://www.npmjs.com/package/showdown-custom-class
*
* Showdown Custom Class Extension
*
*
* @example
*
* ```js
* var converter = new showdown.Converter({
* extensions: [customClassExt],
* })
* ```
*
* ---
*
* <br>
*
* ```md
* #[.header]Header
* [.pTag line]Just a line of text.
* ```
* <br>
*
* ---
*
* <br>
*
* ```html
* <h1 id="headercontenttitle" class="header">Header</h1>
* <p class="pTag line">Just a line of text.</p>
* ```
*
*
* @returns {MmExtension[]}
*/
function customClass(): MmExtension[] {
return [
{
type: "output",
filter: (text) => {
return (
text
// Add class for list (ol, ul)
.replace(
/<p>\[\.([a-z0-9A-Z\s]+)\]<\/p>[\n]?<(.+)>/g,
`<$2 class="$1">`
)

// Add class for other blocks
.replace(/<(.+)>\[\.([a-z0-9A-Z\s]+)\]/g, `<$1 class="$2">`)

// Prevent class name with 2 dashs being replace by `<em>` tag
.replace(/class="(.+)"/g, function (str) {
if (str.indexOf("<em>") !== -1) {
return str.replace(/<[/]?em>/g, "_");
}
return str;
})
);
},
},
];
}
registerExtension("customClass", customClass());

export default customClass;
46 changes: 46 additions & 0 deletions src/extensions/icons.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import {
registerExtension,
type MmExtension,
} from "../manage-extensions/index.js";

/**
* Font Awesome icons extension for Mmark and Showdown
*
* https://github.com/dbtek/showdown-icon/blob/master/showdown-icon.js
*
*
* @returns {MmExtension[]}
*
* ```js
* var converter = new Showdown.converter({ extensions: ['icons'] });
* alert(converter.makeHtml('@fa-home'));
* ```
*/
function icons(): MmExtension[] {
return [
{
type: "lang",
regex: "\\B(\\\\)?@fa-([\\S]+)\\b",
replace: function (a: any, b: string, c: string) {
return b === "\\" ? a : '<i class="fa fa-' + c + '">' + "</i>";
},
},
{
type: "output",
filter: (text: string) => {
const scriptTag = `
<script>
var script = document.createElement("script");
script.src = "https://kit.fontawesome.com/50c925d5df.js";
script.crossorigin = "anonymous";
document.head.appendChild(script);
</script>`;
return scriptTag + text;
},
},
];
}

registerExtension("icons", icons());

export default icons;
17 changes: 17 additions & 0 deletions src/extensions/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import showdownMathjax from "showdown-mathjax";
import showdownprism from "showdown-prism";
import copyCode from "./copy_code.js";
import customClass from "./custom_class.js";
import icons from "./icons.js";
import twitter from "./twitter.js";
import youtube from "./youtube.js";

export {
showdownMathjax,
showdownprism,
copyCode,
customClass,
icons,
twitter,
youtube,
};
62 changes: 62 additions & 0 deletions src/extensions/twitter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import {
registerExtension,
type MmExtension,
} from "../manage-extensions/index.js";
/**
* Twitter Extension
* Support for twitter @username and hashtag
* Usage:
* @username -> <a href="http://twitter.com/username">@username</a>
* #hashtag -> <a href="http://twitter.com/search/%23hashtag">#hashtag</a>
*/
function twitter(): MmExtension[] {
return [
// @username syntax
{
type: "lang",
regex: "\\B(\\\\)?@([\\S]+)\\b",
replace: function (match: any, leadingSlash: string, username: string) {
// Check if we matched the leading \ and return nothing changed if so
if (leadingSlash === "\\") {
return match;
} else {
return (
'<a href="http://twitter.com/' +
username +
'">@' +
username +
"</a>"
);
}
},
},
// #hashtag syntax
{
type: "lang",
regex: "\\B(\\\\)?#([\\S]+)\\b",
replace: function (match: any, leadingSlash: string, tag: string) {
// Check if we matched the leading \ and return nothing changed if so
if (leadingSlash === "\\") {
return match;
} else {
return (
'<a href="http://twitter.com/search/%23' +
tag +
'">#' +
tag +
"</a>"
);
}
},
},
// Escaped @'s
{
type: "lang",
regex: "\\\\@",
replace: "@",
},
];
}
registerExtension("twitter", twitter());

export default twitter;
6 changes: 3 additions & 3 deletions src/extensions/youtube.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
* ```
*
*/
function showdownYoutube(): MmExtension[] {
function youtube(): MmExtension[] {
return [
{
type: "lang",
Expand All @@ -32,6 +32,6 @@ function showdownYoutube(): MmExtension[] {
];
}

registerExtension("showdownYoutube", showdownYoutube());
registerExtension("youtube", youtube());

export default showdownYoutube;
export default youtube;
1 change: 0 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
export * from "./converter/index.js";
export * from "./frontmatter/index.js";
export * from "./helper/getalloptions.js";
export * from "./manage-extensions/index.js";
export * from "./subparser/index.js";

0 comments on commit b457e2c

Please sign in to comment.