mirror of
https://github.com/alexmickelson/canvasManagement.git
synced 2026-03-25 23:28:33 -06:00
improving replace url features
This commit is contained in:
@@ -108,6 +108,12 @@ export const getStatus = ({
|
|||||||
markdownToHTMLSafe({
|
markdownToHTMLSafe({
|
||||||
markdownString: assignment.description,
|
markdownString: assignment.description,
|
||||||
settings,
|
settings,
|
||||||
|
replaceText: [
|
||||||
|
{
|
||||||
|
source: "insert_github_classroom_url",
|
||||||
|
destination: assignment.githubClassroomAssignmentShareLink || "",
|
||||||
|
},
|
||||||
|
],
|
||||||
}),
|
}),
|
||||||
canvasAssignment.description
|
canvasAssignment.description
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -59,7 +59,15 @@ export default function AssignmentPreview({
|
|||||||
<hr />
|
<hr />
|
||||||
<br />
|
<br />
|
||||||
<section>
|
<section>
|
||||||
<MarkdownDisplay markdown={assignment.description} />
|
<MarkdownDisplay
|
||||||
|
markdown={assignment.description}
|
||||||
|
replaceText={[
|
||||||
|
{
|
||||||
|
source: "insert_github_classroom_url",
|
||||||
|
destination: assignment.githubClassroomAssignmentShareLink || "",
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
</section>
|
</section>
|
||||||
<hr />
|
<hr />
|
||||||
<section>
|
<section>
|
||||||
|
|||||||
@@ -6,9 +6,14 @@ import { LocalCourseSettings } from "@/features/local/course/localCourseSettings
|
|||||||
export default function MarkdownDisplay({
|
export default function MarkdownDisplay({
|
||||||
markdown,
|
markdown,
|
||||||
className = "",
|
className = "",
|
||||||
|
replaceText = [],
|
||||||
}: {
|
}: {
|
||||||
markdown: string;
|
markdown: string;
|
||||||
className?: string;
|
className?: string;
|
||||||
|
replaceText?: {
|
||||||
|
source: string;
|
||||||
|
destination: string;
|
||||||
|
}[];
|
||||||
}) {
|
}) {
|
||||||
const { data: settings } = useLocalCourseSettingsQuery();
|
const { data: settings } = useLocalCourseSettingsQuery();
|
||||||
return (
|
return (
|
||||||
@@ -17,6 +22,7 @@ export default function MarkdownDisplay({
|
|||||||
markdown={markdown}
|
markdown={markdown}
|
||||||
settings={settings}
|
settings={settings}
|
||||||
className={className}
|
className={className}
|
||||||
|
replaceText={replaceText}
|
||||||
/>
|
/>
|
||||||
</SuspenseAndErrorHandling>
|
</SuspenseAndErrorHandling>
|
||||||
);
|
);
|
||||||
@@ -26,16 +32,25 @@ function DangerousInnerMarkdown({
|
|||||||
markdown,
|
markdown,
|
||||||
settings,
|
settings,
|
||||||
className,
|
className,
|
||||||
|
replaceText,
|
||||||
}: {
|
}: {
|
||||||
markdown: string;
|
markdown: string;
|
||||||
settings: LocalCourseSettings;
|
settings: LocalCourseSettings;
|
||||||
className: string;
|
className: string;
|
||||||
|
replaceText: {
|
||||||
|
source: string;
|
||||||
|
destination: string;
|
||||||
|
}[];
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={"markdownPreview " + className}
|
className={"markdownPreview " + className}
|
||||||
dangerouslySetInnerHTML={{
|
dangerouslySetInnerHTML={{
|
||||||
__html: markdownToHTMLSafe({ markdownString: markdown, settings }),
|
__html: markdownToHTMLSafe({
|
||||||
|
markdownString: markdown,
|
||||||
|
settings,
|
||||||
|
replaceText,
|
||||||
|
}),
|
||||||
}}
|
}}
|
||||||
></div>
|
></div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -32,16 +32,14 @@ export const canvasAssignmentService = {
|
|||||||
const content = markdownToHTMLSafe({
|
const content = markdownToHTMLSafe({
|
||||||
markdownString: localAssignment.description,
|
markdownString: localAssignment.description,
|
||||||
settings,
|
settings,
|
||||||
|
replaceText: [
|
||||||
|
{
|
||||||
|
source: "insert_github_classroom_url",
|
||||||
|
destination: localAssignment.githubClassroomAssignmentShareLink || "",
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
const contentWithClassroomLinks =
|
|
||||||
localAssignment.githubClassroomAssignmentShareLink
|
|
||||||
? content.replaceAll(
|
|
||||||
"insert_github_classroom_url",
|
|
||||||
localAssignment.githubClassroomAssignmentShareLink
|
|
||||||
)
|
|
||||||
: content;
|
|
||||||
|
|
||||||
const body = {
|
const body = {
|
||||||
assignment: {
|
assignment: {
|
||||||
name: localAssignment.name,
|
name: localAssignment.name,
|
||||||
@@ -51,7 +49,7 @@ export const canvasAssignmentService = {
|
|||||||
allowed_extensions: localAssignment.allowedFileUploadExtensions.map(
|
allowed_extensions: localAssignment.allowedFileUploadExtensions.map(
|
||||||
(e) => e.toString()
|
(e) => e.toString()
|
||||||
),
|
),
|
||||||
description: contentWithClassroomLinks,
|
description: content,
|
||||||
due_at: getDateFromString(localAssignment.dueAt)?.toISOString(),
|
due_at: getDateFromString(localAssignment.dueAt)?.toISOString(),
|
||||||
lock_at:
|
lock_at:
|
||||||
localAssignment.lockAt &&
|
localAssignment.lockAt &&
|
||||||
@@ -90,6 +88,13 @@ export const canvasAssignmentService = {
|
|||||||
description: markdownToHTMLSafe({
|
description: markdownToHTMLSafe({
|
||||||
markdownString: localAssignment.description,
|
markdownString: localAssignment.description,
|
||||||
settings,
|
settings,
|
||||||
|
replaceText: [
|
||||||
|
{
|
||||||
|
source: "insert_github_classroom_url",
|
||||||
|
destination:
|
||||||
|
localAssignment.githubClassroomAssignmentShareLink || "",
|
||||||
|
},
|
||||||
|
],
|
||||||
}),
|
}),
|
||||||
due_at: getDateFromString(localAssignment.dueAt)?.toISOString(),
|
due_at: getDateFromString(localAssignment.dueAt)?.toISOString(),
|
||||||
lock_at:
|
lock_at:
|
||||||
|
|||||||
@@ -90,14 +90,12 @@ export function markdownToHTMLSafe({
|
|||||||
replaceText?: { source: string; destination: string }[];
|
replaceText?: { source: string; destination: string }[];
|
||||||
}) {
|
}) {
|
||||||
const html = markdownToHtmlNoImages(markdownString);
|
const html = markdownToHtmlNoImages(markdownString);
|
||||||
if (convertImages) return convertImagesToCanvasImages(html, settings);
|
|
||||||
|
|
||||||
|
|
||||||
const replacedHtml = replaceText.reduce(
|
const replacedHtml = replaceText.reduce(
|
||||||
(acc, { source, destination }) => acc.replaceAll(source, destination),
|
(acc, { source, destination }) => acc.replaceAll(source, destination),
|
||||||
html
|
html
|
||||||
);
|
);
|
||||||
// return html;
|
|
||||||
|
if (convertImages) return convertImagesToCanvasImages(replacedHtml, settings);
|
||||||
return replacedHtml;
|
return replacedHtml;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
const scriptRegex = /<script.*?<\/script>/g;
|
const scriptRegex = /<script.*?<\/script>/g;
|
||||||
const linkTagRegex = /<link\s+rel="[^"]*"\s+href="[^"]*"[^>]*>/g;
|
const linkTagRegex = /<link\s+rel="[^"]*"\s+href="[^"]*"[^>]*>/g;
|
||||||
const htmlAttribute = /\s+\w+="[^"]*"|\s+\w+='[^']*'|\s+\w+=[^\s>]+/g;
|
const nonHrefAttribute =
|
||||||
|
/\s+(?!href\s*=)\w+="[^"]*"|\s+(?!href\s*=)\w+='[^']*'|\s+(?!href\s*=)\w+=[^\s>]+/g;
|
||||||
|
|
||||||
function replaceUnicodeEscapes(input: string) {
|
function replaceUnicodeEscapes(input: string) {
|
||||||
return input.replace(/\\u[\dA-Fa-f]{4}/g, (match) => {
|
return input.replace(/\\u[\dA-Fa-f]{4}/g, (match) => {
|
||||||
@@ -14,7 +15,7 @@ export const removeHtmlDetails = (html: string) => {
|
|||||||
return withoutUnicode
|
return withoutUnicode
|
||||||
.replaceAll(scriptRegex, "")
|
.replaceAll(scriptRegex, "")
|
||||||
.replaceAll(linkTagRegex, "")
|
.replaceAll(linkTagRegex, "")
|
||||||
.replaceAll(htmlAttribute, "")
|
.replaceAll(nonHrefAttribute, "")
|
||||||
.replaceAll(/\\"/g, '"')
|
.replaceAll(/\\"/g, '"')
|
||||||
.replaceAll(/\s/g, "")
|
.replaceAll(/\s/g, "")
|
||||||
.replaceAll(/<hr\s*\/?>/g, "<hr>")
|
.replaceAll(/<hr\s*\/?>/g, "<hr>")
|
||||||
@@ -32,5 +33,45 @@ export const removeHtmlDetails = (html: string) => {
|
|||||||
export const htmlIsCloseEnough = (html1: string, html2: string) => {
|
export const htmlIsCloseEnough = (html1: string, html2: string) => {
|
||||||
const simple1 = removeHtmlDetails(html1);
|
const simple1 = removeHtmlDetails(html1);
|
||||||
const simple2 = removeHtmlDetails(html2);
|
const simple2 = removeHtmlDetails(html2);
|
||||||
|
|
||||||
|
if (simple1 !== simple2) {
|
||||||
|
const len1 = simple1.length;
|
||||||
|
const len2 = simple2.length;
|
||||||
|
const maxLen = Math.max(len1, len2);
|
||||||
|
|
||||||
|
let firstDiff = -1;
|
||||||
|
const diffs: Array<{ index: number; a: string; b: string }> = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < maxLen && diffs.length < 10; i++) {
|
||||||
|
const a = simple1[i] ?? "∅";
|
||||||
|
const b = simple2[i] ?? "∅";
|
||||||
|
if (a !== b) {
|
||||||
|
if (firstDiff === -1) firstDiff = i;
|
||||||
|
diffs.push({ index: i, a, b });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const ctx = 30;
|
||||||
|
const start = Math.max(0, (firstDiff === -1 ? 0 : firstDiff) - ctx);
|
||||||
|
const end1 = Math.min(len1, (firstDiff === -1 ? 0 : firstDiff) + ctx);
|
||||||
|
const end2 = Math.min(len2, (firstDiff === -1 ? 0 : firstDiff) + ctx);
|
||||||
|
|
||||||
|
const mark = (s: string, sStart: number, idx: number, sEnd: number) => {
|
||||||
|
if (idx < 0) return s.slice(sStart, sEnd);
|
||||||
|
const before = s.slice(sStart, idx);
|
||||||
|
const ch = s[idx] ?? "∅";
|
||||||
|
const after = s.slice(idx + 1, sEnd);
|
||||||
|
return `${before}[${ch}]${after}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log("htmlIsCloseEnough: differences detected");
|
||||||
|
console.log(`len1=${len1}, len2=${len2}`);
|
||||||
|
if (firstDiff !== -1) {
|
||||||
|
console.log(`firstDiffAt=${firstDiff}`);
|
||||||
|
console.log("s1:", mark(simple1, start, firstDiff, end1));
|
||||||
|
console.log("s2:", mark(simple2, start, firstDiff, end2));
|
||||||
|
}
|
||||||
|
console.log("first 10 diffs:", diffs);
|
||||||
|
}
|
||||||
return simple1 === simple2;
|
return simple1 === simple2;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user