From 54e071b053604a09b6df7a80448d8d8c06b3da5d Mon Sep 17 00:00:00 2001 From: Alex Mickelson Date: Fri, 31 Jan 2025 09:14:16 -0700 Subject: [PATCH] added catches around markdown to html, might throw exception if image error --- docker-compose.yml | 4 +- run.sh | 2 +- .../[courseName]/calendar/day/getStatus.tsx | 19 ++++++--- .../lecture/[lectureDay]/LecturePreview.tsx | 13 +++--- .../[assignmentName]/AssignmentPreview.tsx | 7 ++-- .../page/[pageName]/PagePreview.tsx | 9 +--- .../quiz/[quizName]/QuizPreview.tsx | 23 ++-------- src/components/MarkdownDisplay.tsx | 42 +++++++++++++++++++ src/services/htmlMarkdownUtils.ts | 6 ++- 9 files changed, 77 insertions(+), 48 deletions(-) create mode 100644 src/components/MarkdownDisplay.tsx 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) {