diff --git a/docker-compose.yml b/docker-compose.yml
index 825f59d..767bc75 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -38,11 +38,9 @@ services:
environment:
- TUNNEL_TOKEN=${CLOUDFLARE_TUNNEL_TOKEN}
healthcheck:
- test: ["CMD", "cloudflared", "--version"]
+ test: [ "CMD", "cloudflared", "--version" ]
interval: 30s
timeout: 10s
retries: 3
start_period: 10s
-
-
# https://ngrok.com/docs/using-ngrok-with/docker/
diff --git a/run.sh b/run.sh
index ec59290..c4a79b2 100755
--- a/run.sh
+++ b/run.sh
@@ -9,9 +9,9 @@ docker run -it --rm \
-p 3000:3000 \
-w /app \
-v .:/app \
- -v ~/projects/faculty/1810/2024-fall-alex/modules:/app/storage/intro_to_web \
-v ~/projects/faculty/4850_AdvancedFE/2024-fall-alex/modules:/app/storage/advanced_frontend \
-v ~/projects/faculty/1810/2025-spring-alex/online:/app/storage/intro_to_web_online \
+ -v ~/projects/faculty/1810/2025-spring-alex/in-person:/app/storage/intro_to_web \
-v ~/projects/faculty/1400/2025_spring_alex/modules:/app/storage/1400 \
-v ~/projects/faculty/1405/2025_spring_alex:/app/storage/1405 \
-v ~/projects/faculty/3840_Telemetry/2025_spring_alex/modules:/app/storage/telemetry \
diff --git a/src/app/course/[courseName]/calendar/day/getStatus.tsx b/src/app/course/[courseName]/calendar/day/getStatus.tsx
index 01bbe3d..2b984e6 100644
--- a/src/app/course/[courseName]/calendar/day/getStatus.tsx
+++ b/src/app/course/[courseName]/calendar/day/getStatus.tsx
@@ -104,15 +104,22 @@ export const getStatus = ({
),
};
- const htmlIsSame = htmlIsCloseEnough(
- markdownToHTMLSafe(assignment.description, settings),
- canvasAssignment.description
- );
- if (!htmlIsSame)
+ try {
+ const htmlIsSame = htmlIsCloseEnough(
+ markdownToHTMLSafe(assignment.description, settings),
+ canvasAssignment.description
+ );
+ if (!htmlIsSame)
+ return {
+ status: "incomplete",
+ message: "Canvas description is different",
+ };
+ } catch (exception) {
return {
status: "incomplete",
- message: "Canvas description is different",
+ message: "Error parsing markdown " + exception,
};
+ }
}
return { status: "published", message: "" };
diff --git a/src/app/course/[courseName]/lecture/[lectureDay]/LecturePreview.tsx b/src/app/course/[courseName]/lecture/[lectureDay]/LecturePreview.tsx
index c4d3dc0..7874662 100644
--- a/src/app/course/[courseName]/lecture/[lectureDay]/LecturePreview.tsx
+++ b/src/app/course/[courseName]/lecture/[lectureDay]/LecturePreview.tsx
@@ -1,3 +1,5 @@
+import MarkdownDisplay from "@/components/MarkdownDisplay";
+import { SuspenseAndErrorHandling } from "@/components/SuspenseAndErrorHandling";
import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks";
import { Lecture } from "@/models/local/lecture";
import { markdownToHTMLSafe } from "@/services/htmlMarkdownUtils";
@@ -8,15 +10,12 @@ export default function LecturePreview({ lecture }: { lecture: Lecture }) {
<>
{lecture.name}
- {lecture.date}
+
+ {lecture.date}
+
>
);
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 1158bb6..a0338fe 100644
--- a/src/app/course/[courseName]/modules/[moduleName]/assignment/[assignmentName]/AssignmentPreview.tsx
+++ b/src/app/course/[courseName]/modules/[moduleName]/assignment/[assignmentName]/AssignmentPreview.tsx
@@ -1,4 +1,5 @@
import ClientOnly from "@/components/ClientOnly";
+import MarkdownDisplay from "@/components/MarkdownDisplay";
import { SuspenseAndErrorHandling } from "@/components/SuspenseAndErrorHandling";
import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks";
import { LocalAssignment } from "@/models/local/assignment/localAssignment";
@@ -18,7 +19,6 @@ export default function AssignmentPreview({
(sum, cur) => (rubricItemIsExtraCredit(cur) ? sum + cur.points : sum),
0
);
- const htmlPreview = markdownToHTMLSafe(assignment.description, settings);
return (
@@ -59,12 +59,13 @@ export default function AssignmentPreview({
*/}
diff --git a/src/app/course/[courseName]/modules/[moduleName]/page/[pageName]/PagePreview.tsx b/src/app/course/[courseName]/modules/[moduleName]/page/[pageName]/PagePreview.tsx
index 1f25a01..f06b679 100644
--- a/src/app/course/[courseName]/modules/[moduleName]/page/[pageName]/PagePreview.tsx
+++ b/src/app/course/[courseName]/modules/[moduleName]/page/[pageName]/PagePreview.tsx
@@ -1,16 +1,11 @@
+import MarkdownDisplay from "@/components/MarkdownDisplay";
import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks";
import { LocalCoursePage } from "@/models/local/page/localCoursePage";
import { markdownToHTMLSafe } from "@/services/htmlMarkdownUtils";
import React from "react";
export default function PagePreview({ page }: { page: LocalCoursePage }) {
- const [settings] = useLocalCourseSettingsQuery();
return (
-
+
);
}
diff --git a/src/app/course/[courseName]/modules/[moduleName]/quiz/[quizName]/QuizPreview.tsx b/src/app/course/[courseName]/modules/[moduleName]/quiz/[quizName]/QuizPreview.tsx
index 2fe5718..352fa0a 100644
--- a/src/app/course/[courseName]/modules/[moduleName]/quiz/[quizName]/QuizPreview.tsx
+++ b/src/app/course/[courseName]/modules/[moduleName]/quiz/[quizName]/QuizPreview.tsx
@@ -1,4 +1,5 @@
import CheckIcon from "@/components/icons/CheckIcon";
+import MarkdownDisplay from "@/components/MarkdownDisplay";
import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks";
import { useQuizQuery } from "@/hooks/localCourse/quizHooks";
import {
@@ -53,12 +54,7 @@ export default function QuizPreview({
Assignment Group Name
{quiz.localAssignmentGroupName}
-
+
{quiz.questions.map((question, i) => (
@@ -88,13 +84,7 @@ function QuizQuestionPreview({ question }: { question: LocalQuizQuestion }) {
{question.points} {question.points === 1 ? " Point" : " Points"}
-
-
+
{question.questionType === QuestionType.MATCHING && (
{question.answers.map((answer) => (
@@ -134,12 +124,7 @@ function QuizQuestionPreview({ question }: { question: LocalQuizQuestion }) {
)}
-
+
))}
diff --git a/src/components/MarkdownDisplay.tsx b/src/components/MarkdownDisplay.tsx
new file mode 100644
index 0000000..1363696
--- /dev/null
+++ b/src/components/MarkdownDisplay.tsx
@@ -0,0 +1,42 @@
+import { useLocalCourseSettingsQuery } from "@/hooks/localCourse/localCoursesHooks";
+import { SuspenseAndErrorHandling } from "./SuspenseAndErrorHandling";
+import { markdownToHTMLSafe } from "@/services/htmlMarkdownUtils";
+import { LocalCourseSettings } from "@/models/local/localCourseSettings";
+
+export default function MarkdownDisplay({
+ markdown,
+ className = "",
+}: {
+ markdown: string;
+ className?: string;
+}) {
+ const [settings] = useLocalCourseSettingsQuery();
+ return (
+
+
+
+ );
+}
+
+function DangerousInnerMarkdown({
+ markdown,
+ settings,
+ className,
+}: {
+ markdown: string;
+ settings: LocalCourseSettings;
+ className: string;
+}) {
+ return (
+
+ );
+}
diff --git a/src/services/htmlMarkdownUtils.ts b/src/services/htmlMarkdownUtils.ts
index bbb6bc9..9965b9a 100644
--- a/src/services/htmlMarkdownUtils.ts
+++ b/src/services/htmlMarkdownUtils.ts
@@ -46,10 +46,12 @@ export function convertImagesToCanvasImages(
export function markdownToHTMLSafe(
markdownString: string,
- settings: LocalCourseSettings
+ settings: LocalCourseSettings,
+ convertImages: boolean = true
) {
const html = markdownToHtmlNoImages(markdownString);
- return convertImagesToCanvasImages(html, settings);
+ if (convertImages) return convertImagesToCanvasImages(html, settings);
+ else return html;
}
export function markdownToHtmlNoImages(markdownString: string) {