diff --git a/src/app/course/[courseName]/calendar/day/getStatus.tsx b/src/app/course/[courseName]/calendar/day/getStatus.tsx
index 6caf87a..23f5482 100644
--- a/src/app/course/[courseName]/calendar/day/getStatus.tsx
+++ b/src/app/course/[courseName]/calendar/day/getStatus.tsx
@@ -108,6 +108,12 @@ export const getStatus = ({
markdownToHTMLSafe({
markdownString: assignment.description,
settings,
+ replaceText: [
+ {
+ source: "insert_github_classroom_url",
+ destination: assignment.githubClassroomAssignmentShareLink || "",
+ },
+ ],
}),
canvasAssignment.description
);
diff --git a/src/app/course/[courseName]/modules/[moduleName]/assignment/[assignmentName]/AssignmentPreview.tsx b/src/app/course/[courseName]/modules/[moduleName]/assignment/[assignmentName]/AssignmentPreview.tsx
index 03bbc88..7c25fa1 100644
--- a/src/app/course/[courseName]/modules/[moduleName]/assignment/[assignmentName]/AssignmentPreview.tsx
+++ b/src/app/course/[courseName]/modules/[moduleName]/assignment/[assignmentName]/AssignmentPreview.tsx
@@ -59,7 +59,15 @@ export default function AssignmentPreview({
diff --git a/src/components/MarkdownDisplay.tsx b/src/components/MarkdownDisplay.tsx
index c1c93cb..9670757 100644
--- a/src/components/MarkdownDisplay.tsx
+++ b/src/components/MarkdownDisplay.tsx
@@ -6,9 +6,14 @@ import { LocalCourseSettings } from "@/features/local/course/localCourseSettings
export default function MarkdownDisplay({
markdown,
className = "",
+ replaceText = [],
}: {
markdown: string;
className?: string;
+ replaceText?: {
+ source: string;
+ destination: string;
+ }[];
}) {
const { data: settings } = useLocalCourseSettingsQuery();
return (
@@ -17,6 +22,7 @@ export default function MarkdownDisplay({
markdown={markdown}
settings={settings}
className={className}
+ replaceText={replaceText}
/>
);
@@ -26,16 +32,25 @@ function DangerousInnerMarkdown({
markdown,
settings,
className,
+ replaceText,
}: {
markdown: string;
settings: LocalCourseSettings;
className: string;
+ replaceText: {
+ source: string;
+ destination: string;
+ }[];
}) {
return (
);
diff --git a/src/features/canvas/services/canvasAssignmentService.ts b/src/features/canvas/services/canvasAssignmentService.ts
index 43da076..d40ca1b 100644
--- a/src/features/canvas/services/canvasAssignmentService.ts
+++ b/src/features/canvas/services/canvasAssignmentService.ts
@@ -32,16 +32,14 @@ export const canvasAssignmentService = {
const content = markdownToHTMLSafe({
markdownString: localAssignment.description,
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 = {
assignment: {
name: localAssignment.name,
@@ -51,7 +49,7 @@ export const canvasAssignmentService = {
allowed_extensions: localAssignment.allowedFileUploadExtensions.map(
(e) => e.toString()
),
- description: contentWithClassroomLinks,
+ description: content,
due_at: getDateFromString(localAssignment.dueAt)?.toISOString(),
lock_at:
localAssignment.lockAt &&
@@ -90,6 +88,13 @@ export const canvasAssignmentService = {
description: markdownToHTMLSafe({
markdownString: localAssignment.description,
settings,
+ replaceText: [
+ {
+ source: "insert_github_classroom_url",
+ destination:
+ localAssignment.githubClassroomAssignmentShareLink || "",
+ },
+ ],
}),
due_at: getDateFromString(localAssignment.dueAt)?.toISOString(),
lock_at:
diff --git a/src/services/htmlMarkdownUtils.ts b/src/services/htmlMarkdownUtils.ts
index 5686571..ee9a337 100644
--- a/src/services/htmlMarkdownUtils.ts
+++ b/src/services/htmlMarkdownUtils.ts
@@ -90,14 +90,12 @@ export function markdownToHTMLSafe({
replaceText?: { source: string; destination: string }[];
}) {
const html = markdownToHtmlNoImages(markdownString);
- if (convertImages) return convertImagesToCanvasImages(html, settings);
-
-
const replacedHtml = replaceText.reduce(
(acc, { source, destination }) => acc.replaceAll(source, destination),
html
);
- // return html;
+
+ if (convertImages) return convertImagesToCanvasImages(replacedHtml, settings);
return replacedHtml;
}
diff --git a/src/services/utils/htmlIsCloseEnough.ts b/src/services/utils/htmlIsCloseEnough.ts
index b9655ad..5decd4b 100644
--- a/src/services/utils/htmlIsCloseEnough.ts
+++ b/src/services/utils/htmlIsCloseEnough.ts
@@ -1,6 +1,7 @@
const scriptRegex = //g;
const linkTagRegex = /]*>/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) {
return input.replace(/\\u[\dA-Fa-f]{4}/g, (match) => {
@@ -14,7 +15,7 @@ export const removeHtmlDetails = (html: string) => {
return withoutUnicode
.replaceAll(scriptRegex, "")
.replaceAll(linkTagRegex, "")
- .replaceAll(htmlAttribute, "")
+ .replaceAll(nonHrefAttribute, "")
.replaceAll(/\\"/g, '"')
.replaceAll(/\s/g, "")
.replaceAll(/
/g, "
")
@@ -32,5 +33,45 @@ export const removeHtmlDetails = (html: string) => {
export const htmlIsCloseEnough = (html1: string, html2: string) => {
const simple1 = removeHtmlDetails(html1);
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;
};