Skip to content

Commit

Permalink
Merge pull request #16 from moonlight-mod/markdown-library
Browse files Browse the repository at this point in the history
Markdown library
  • Loading branch information
Cynosphere authored Dec 9, 2023
2 parents e93cb3b + cba05a3 commit 36cba32
Show file tree
Hide file tree
Showing 7 changed files with 266 additions and 0 deletions.
55 changes: 55 additions & 0 deletions packages/core-extensions/src/markdown/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { ExtensionWebpackModule, Patch } from "@moonlight-mod/types";

export const patches: Patch[] = [
{
find: "/^(¯\\\\_\\(ツ\\)_\\/¯)/.exec",
replace: [
{
match: /={newline:(.+?)},(.{1,2})=\(0,/,
replacement: (_, rules, RULES) =>
`=require("markdown_markdown")._addRules({newline:${rules}}),${RULES}=(0,`
},
{
match: /(?<=var (.{1,2})={RULES:.+?})/,
replacement: (_, rulesets) =>
`;require("markdown_markdown")._applyRulesetBlacklist(${rulesets});`
}
]
},
{
find: "then you probably need to add it to this file so that the rich chat box understands it.",
replace: [
{
match: /(.)={link:{(.+?)},(.)=new Set/,
replacement: (_, rulesDef, rules, syntaxBefore) =>
`__slateRules,${rulesDef}=__slateRules=require("markdown_markdown")._addSlateRules({link:{${rules}}),${syntaxBefore}=new Set`
},
{
match:
/(originalMatch:.}=(.);)(.+?)case"emoticon":(return .+?;)(.+?)case"link":{(.+?)}default:/,
replacement: (
_,
start,
rule,
body,
plaintextReturn,
otherRules,
inlineStyleBody
) =>
`${start}if(${rule}.type.startsWith("__moonlight_")){if(__slateRules[${rule}.type].type=="inlineStyle"){${inlineStyleBody}}else{${plaintextReturn}}}${body}case"emoticon":${plaintextReturn}${otherRules}case"link":{${inlineStyleBody}}default:`
}
]
},
{
find: '"Slate: Unknown decoration attribute: "',
replace: {
match: /=({strong:.+?});/,
replacement: (_, rules) =>
`=require("markdown_markdown")._addSlateDecorators(${rules});`
}
}
];

export const webpackModules: Record<string, ExtensionWebpackModule> = {
markdown: {}
};
9 changes: 9 additions & 0 deletions packages/core-extensions/src/markdown/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"id": "markdown",
"meta": {
"name": "Markdown",
"tagline": "A library for adding new markdown rules",
"authors": ["Cynosphere"],
"tags": ["library"]
}
}
81 changes: 81 additions & 0 deletions packages/core-extensions/src/markdown/webpackModules/markdown.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/* eslint-disable no-console */
import {
MarkdownRule,
Ruleset,
SlateRule
} from "@moonlight-mod/types/coreExtensions/markdown";

export const rules: Record<
string,
(rules: Record<string, MarkdownRule>) => MarkdownRule
> = {};
export const slateRules: Record<
string,
(rules: Record<string, SlateRule>) => SlateRule
> = {};
export const slateDecorators: Record<string, string> = {};
export const ruleBlacklists: Record<Ruleset, Record<string, boolean>> = {
RULES: {},
CHANNEL_TOPIC_RULES: {},
VOICE_CHANNEL_STATUS_RULES: {},
EMBED_TITLE_RULES: {},
INLINE_REPLY_RULES: {},
GUILD_VERIFICATION_FORM_RULES: {},
GUILD_EVENT_RULES: {},
PROFILE_BIO_RULES: {},
AUTO_MODERATION_SYSTEM_MESSAGE_RULES: {},
NATIVE_SEARCH_RESULT_LINK_RULES: {}
};

export function addRule(
name: string,
markdown: (rules: Record<string, MarkdownRule>) => MarkdownRule,
slate: (rules: Record<string, SlateRule>) => SlateRule,
decorator?: string
) {
rules[name] = markdown;
slateRules[name] = slate;
if (decorator != null) slateDecorators[name] = decorator;
}

export function blacklistFromRuleset(ruleset: Ruleset, name: string) {
if (ruleBlacklists[ruleset] == null) ruleBlacklists[ruleset] = {};
ruleBlacklists[ruleset][name] = true;
}

export function _addRules(originalRules: Record<string, MarkdownRule>) {
for (const name in rules) {
originalRules["__moonlight_" + name] = rules[name](originalRules);
}

return originalRules;
}

export function _addSlateRules(originalRules: Record<string, SlateRule>) {
for (const name in slateRules) {
originalRules["__moonlight_" + name] = slateRules[name](originalRules);
}

return originalRules;
}

export function _addSlateDecorators(originalRules: Record<string, string>) {
for (const name in slateDecorators) {
originalRules["__moonlight_" + name] = slateDecorators[name];
}

return originalRules;
}

export function _applyRulesetBlacklist(
rulesets: Record<Ruleset, Record<string, MarkdownRule>>
) {
for (const ruleset of Object.keys(rulesets) as Ruleset[]) {
if (ruleset === "RULES") continue;

const rules = rulesets[ruleset];
for (const rule in ruleBlacklists[ruleset] || {}) {
delete rules["__moonlight_" + rule];
}
}
}
2 changes: 2 additions & 0 deletions packages/types/src/coreExtensions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,5 @@ export type CommonReact = typeof import("react");
export type CommonFlux = FluxDefault;
export type CommonComponents = CommonComponents_; // lol
export type CommonFluxDispatcher = Dispatcher<any>;

export * as Markdown from "./coreExtensions/markdown";
110 changes: 110 additions & 0 deletions packages/types/src/coreExtensions/markdown.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
// {{{ simple-markdown

export type SingleASTNode = {
type: string;
[key: string]: any;
};

export type UntypedASTNode = {
[key: string]: any;
};

export type ASTNode = SingleASTNode | Array<SingleASTNode>;

export type Parser = (
source: string,
state?: State | null | undefined
) => Array<SingleASTNode>;

export type ParseFunction = (
capture: Capture,
nestedParse: Parser,
state: State
) => UntypedASTNode | ASTNode;

export type Capture =
| (Array<string> & {
index: number;
})
| (Array<string> & {
index?: number;
});

export type State = {
key?: string | number | undefined;
inline?: boolean | null | undefined;
[key: string]: any;
};

export type MatchFunction = {
regex?: RegExp;
} & ((
source: string,
state: State,
prevCapture: string
) => Capture | null | undefined);

export type Output<Result> = (
node: ASTNode,
state?: State | null | undefined
) => Result;

export type SingleNodeOutput<Result> = (
node: SingleASTNode,
nestedOutput: Output<Result>,
state: State
) => Result;

// }}}

export type ValidFlags = "g" | "i" | "m" | "s" | "u" | "y" | undefined;

export type MarkdownRule = {
order: number;
match: MatchFunction;
parse: ParseFunction;
react: SingleNodeOutput<React.ReactNode>;
};

export type SlateRule =
| {
type: "skip";
}
| {
type: "verbatim";
}
| {
type: "inlineObject";
}
| {
type: "inlineStyle";
before: string;
after: string;
};

export type Ruleset =
| "RULES"
| "CHANNEL_TOPIC_RULES"
| "VOICE_CHANNEL_STATUS_RULES"
| "EMBED_TITLE_RULES"
| "INLINE_REPLY_RULES"
| "GUILD_VERIFICATION_FORM_RULES"
| "GUILD_EVENT_RULES"
| "PROFILE_BIO_RULES"
| "AUTO_MODERATION_SYSTEM_MESSAGE_RULES"
| "NATIVE_SEARCH_RESULT_LINK_RULES";

export type Markdown = {
rules: Record<string, MarkdownRule>;
slateRules: Record<string, SlateRule>;
slateDecorators: Record<string, string>;
ruleBlacklists: Record<Ruleset, Record<string, boolean>>;

addRule: (
name: string,
markdown: (rules: Record<string, MarkdownRule>) => MarkdownRule,
slate: (rules: Record<string, SlateRule>) => SlateRule,
decorator?: string | undefined
) => void;
blacklistFromRuleset: (ruleset: Ruleset, name: string) => void;
};
3 changes: 3 additions & 0 deletions packages/types/src/discord/require.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
CommonComponents,
CommonFluxDispatcher
} from "../coreExtensions";
import { Markdown } from "../coreExtensions/markdown";

declare function WebpackRequire(id: string): any;
declare function WebpackRequire(id: "spacepack_spacepack"): {
Expand All @@ -25,4 +26,6 @@ declare function WebpackRequire(id: "settings_settings"): {
default: Settings;
};

declare function WebpackRequire(id: "markdown_markdown"): Markdown;

export default WebpackRequire;
6 changes: 6 additions & 0 deletions packages/types/src/import.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,9 @@ declare module "@moonlight-mod/wp/settings_settings" {
export const Settings: CoreExtensions.Settings;
export default Settings;
}

declare module "@moonlight-mod/wp/markdown_markdown" {
import { CoreExtensions } from "@moonlight-mod/types";
const Markdown: CoreExtensions.Markdown.Markdown;
export = Markdown;
}

0 comments on commit 36cba32

Please sign in to comment.