From baf985635254d2d45b4ba3c1f2f33db6c85c133d Mon Sep 17 00:00:00 2001 From: Nityananda Zbil Date: Fri, 24 May 2024 23:57:18 +0200 Subject: [PATCH] `Communication`: Match mentions (#54) * Prototype render message * Replace: - attachments - attachment units - messages - slides * Test regex --- .../RegexReplacementVisitor.swift | 45 ++++++++++++++++++- .../ArtemisMarkdownTests.swift | 29 +++++++++++- 2 files changed, 71 insertions(+), 3 deletions(-) diff --git a/Sources/ArtemisMarkdown/RegexReplacementVisitor.swift b/Sources/ArtemisMarkdown/RegexReplacementVisitor.swift index fad74db..5c7dd1a 100644 --- a/Sources/ArtemisMarkdown/RegexReplacementVisitor.swift +++ b/Sources/ArtemisMarkdown/RegexReplacementVisitor.swift @@ -18,10 +18,33 @@ struct RegexReplacementVisitor { } enum RegexReplacementVisitors { - static let channels = RegexReplacementVisitor(regex: #/\[channel\](?.*?)\((?.*?)\)\[/channel\]/#) { match in + + // (?\[attachment].*?\[\/attachment]) + static let attachments = RegexReplacementVisitor( + regex: #/\[attachment\](?.*?)\((?lecture/\d+/.*?)\)\[/attachment\]/# + ) { match in + "[Attachment \(match.name)](mention://attachment/\(match.path))" + } + + // (?\[lecture-unit].*?\[\/lecture-unit]) + static let attachmentUnits = RegexReplacementVisitor( + regex: #/\[lecture-unit\](?.*?)\((?attachment-unit/\d+/.*?)\)\[/lecture-unit\]/# + ) { match in + "[Lecture unit \(match.name)](mention://lecture-unit/\(match.path))" + } + + // (?\[channel].*?\[\/channel]) + static let channels = RegexReplacementVisitor( + regex: #/\[channel\](?.*?)\((?.*?)\)\[/channel\]/# + ) { match in "[#\(match.name)](mention://channel/\(match.id))" } + // (?\[programming].*?\[\/programming])| + // (?\[modeling].*?\[\/modeling])| + // (?\[quiz].*?\[\/quiz])| + // (?\[text].*?\[\/text])| + // (?\[file-upload].*?\[\/file-upload]) static let exercises = RegexReplacementVisitor( regex: #/\[(?[\w-]*?)\](?.*?)\((?/courses/\d+/exercises/\d+)\)\[/(?[\w-]*?)\]/# ) { match in @@ -38,6 +61,7 @@ enum RegexReplacementVisitors { String(match.ins) } + // (?\[lecture].*?\[\/lecture]) static let lectures = RegexReplacementVisitor( regex: #/\[lecture\](?.*?)\((?/courses/\d+/lectures/\d+)\)\[/lecture\]/# ) { match in @@ -48,17 +72,34 @@ enum RegexReplacementVisitors { return "![Lecture](fa-chalkboard-user) [\(match.name)](mention://lecture/\(url.lastPathComponent))" } + // (?\[user].*?\[\/user]) static let members = RegexReplacementVisitor(regex: #/\[user\](?.*?)\((?.*?)\)\[/user\]/#) { match in "[@\(match.name)](mention://member/\(match.login))" } + // (?#\d+) + static let messages = RegexReplacementVisitor(regex: #/\#(?\d+)/#) { match in + return "[Message #\(match.id)](mention://message/\(match.id))" + } + + // (?\[slide].*?\[\/slide]) + static let slides = RegexReplacementVisitor( + regex: #/\[slide\](?.*?)\((?attachment-unit/\d+/slide/\d+)\)\[/slide\]/# + ) { match in + "[Slide \(match.name)](mention://slide/\(match.path))" + } + static func visitAll(input: inout String) { for visit in [ + attachments.visit(input:), + attachmentUnits.visit(input:), channels.visit(input:), exercises.visit(input:), ins.visit(input:), lectures.visit(input:), - members.visit(input:) + members.visit(input:), + messages.visit(input:), + slides.visit(input:) ] { visit(&input) } diff --git a/Tests/ArtemisMarkdownTests/ArtemisMarkdownTests.swift b/Tests/ArtemisMarkdownTests/ArtemisMarkdownTests.swift index b1c4843..e0bfe80 100644 --- a/Tests/ArtemisMarkdownTests/ArtemisMarkdownTests.swift +++ b/Tests/ArtemisMarkdownTests/ArtemisMarkdownTests.swift @@ -2,7 +2,21 @@ import XCTest @testable import ArtemisMarkdown final class ArtemisMarkdownTests: XCTestCase { - func testExerciseRegex() throws { + func testAttachmentsRegex() throws { + let inputString = "[attachment]uml-blue(lecture/3/LectureAttachment_2024-05-24T21-05-08-351_d37182b7.png)[/attachment]" + let match = try XCTUnwrap(RegexReplacementVisitors.attachments.regex.wholeMatch(in: inputString)) + XCTAssertEqual(match.name, "uml-blue") + XCTAssertEqual(match.path, "lecture/3/LectureAttachment_2024-05-24T21-05-08-351_d37182b7.png") + } + + func testAttachmentUnitsRegex() throws { + let inputString = "[lecture-unit]Inheritance (part 1)(attachment-unit/7/AttachmentUnit_2024-05-24T21-12-25-915_Inheritance__part_1_.pdf)[/lecture-unit]" + let match = try XCTUnwrap(RegexReplacementVisitors.attachmentUnits.regex.wholeMatch(in: inputString)) + XCTAssertEqual(match.name, "Inheritance (part 1)") + XCTAssertEqual(match.path, "attachment-unit/7/AttachmentUnit_2024-05-24T21-12-25-915_Inheritance__part_1_.pdf") + } + + func testExercisesRegex() throws { let inputString = "[file-upload]An Exercise(/courses/1/exercises/2)[/file-upload]" let match = try XCTUnwrap(RegexReplacementVisitors.exercises.regex.wholeMatch(in: inputString)) XCTAssertEqual(match.name, "An Exercise") @@ -28,4 +42,17 @@ final class ArtemisMarkdownTests: XCTestCase { XCTAssertEqual(match.name, "Full Name") XCTAssertEqual(match.login, "login") } + + func testMessagesRegex() throws { + let inputString = "#13" + let match = try XCTUnwrap(RegexReplacementVisitors.messages.regex.wholeMatch(in: inputString)) + XCTAssertEqual(match.id, "13") + } + + func testSlidesRegex() throws { + let inputString = "[slide]Polymorphism Slide 1(attachment-unit/10/slide/1)[/slide]" + let match = try XCTUnwrap(RegexReplacementVisitors.slides.regex.wholeMatch(in: inputString)) + XCTAssertEqual(match.name, "Polymorphism Slide 1") + XCTAssertEqual(match.path, "attachment-unit/10/slide/1") + } }