diff --git a/tibok/tibok/Models/Document.swift b/tibok/tibok/Models/Document.swift index 68be239..a3932f1 100644 --- a/tibok/tibok/Models/Document.swift +++ b/tibok/tibok/Models/Document.swift @@ -73,4 +73,18 @@ struct Document: Identifiable, Equatable { var lineCount: Int { content.components(separatedBy: .newlines).count } + + /// Whether the document can be previewed as markdown + /// Only markdown files and untitled documents can be previewed + var isPreviewSupported: Bool { + // If no file URL, it's a new untitled document - support preview + guard let fileURL = fileURL else { + return true + } + + // Check file extension + let ext = fileURL.pathExtension.lowercased() + let supportedExtensions = ["md", "markdown", "mdown", "mkd"] + return supportedExtensions.contains(ext) + } } diff --git a/tibok/tibok/Views/PreviewView.swift b/tibok/tibok/Views/PreviewView.swift index a33006e..a383a20 100644 --- a/tibok/tibok/Views/PreviewView.swift +++ b/tibok/tibok/Views/PreviewView.swift @@ -100,6 +100,9 @@ struct PreviewView: View { if appState.currentDocument.isEmpty { // Empty state PreviewEmptyStateView() + } else if !appState.currentDocument.isPreviewSupported { + // Unsupported file type + PreviewUnsupportedView(fileExtension: appState.currentDocument.fileURL?.pathExtension ?? "") } else { // Preview content using WKWebView MarkdownWebView(html: renderedHTML, baseURL: resourceBaseURL) @@ -429,3 +432,43 @@ struct PreviewEmptyStateView: View { .frame(maxWidth: .infinity, maxHeight: .infinity) } } + +// MARK: - Preview Unsupported State + +struct PreviewUnsupportedView: View { + let fileExtension: String + + var body: some View { + VStack(spacing: 16) { + Spacer() + + Image(systemName: "doc.text") + .font(.system(size: 40)) + .foregroundColor(.secondary.opacity(0.4)) + + Text("Preview Not Available") + .font(.headline) + .foregroundColor(.secondary) + + Text("Preview is only available for Markdown files") + .font(.subheadline) + .foregroundColor(.secondary.opacity(0.7)) + .multilineTextAlignment(.center) + + if !fileExtension.isEmpty { + Text("Current file type: .\(fileExtension)") + .font(.system(size: 11)) + .foregroundColor(.secondary.opacity(0.5)) + .padding(.top, 4) + } + + Text("⌘\\ to toggle preview") + .font(.system(size: 11)) + .foregroundColor(.secondary.opacity(0.5)) + .padding(.top, 4) + + Spacer() + } + .frame(maxWidth: .infinity, maxHeight: .infinity) + } +} diff --git a/tibok/tibokTests/DocumentTests.swift b/tibok/tibokTests/DocumentTests.swift index 7971563..e23acd5 100644 --- a/tibok/tibokTests/DocumentTests.swift +++ b/tibok/tibokTests/DocumentTests.swift @@ -50,4 +50,68 @@ struct DocumentTests { let doc = Document(content: "Just one line") #expect(doc.lineCount == 1) } + + @Test("Preview is supported for markdown files") + func previewIsSupportedForMarkdownFiles() { + let mdURL = URL(fileURLWithPath: "/path/to/file.md") + let doc = Document(fileURL: mdURL) + #expect(doc.isPreviewSupported == true) + } + + @Test("Preview is supported for all markdown extensions") + func previewIsSupportedForAllMarkdownExtensions() { + let extensions = ["md", "markdown", "mdown", "mkd"] + for ext in extensions { + let url = URL(fileURLWithPath: "/path/to/file.\(ext)") + let doc = Document(fileURL: url) + #expect(doc.isPreviewSupported == true, ".\(ext) files should be previewable") + } + } + + @Test("Preview is not supported for non-markdown files") + func previewIsNotSupportedForNonMarkdownFiles() { + let tsxURL = URL(fileURLWithPath: "/path/to/file.tsx") + let doc = Document(fileURL: tsxURL) + #expect(doc.isPreviewSupported == false) + } + + @Test("Preview is not supported for common text files") + func previewIsNotSupportedForCommonTextFiles() { + let extensions = ["txt", "tsx", "jsx", "js", "ts", "py", "swift"] + for ext in extensions { + let url = URL(fileURLWithPath: "/path/to/file.\(ext)") + let doc = Document(fileURL: url) + #expect(doc.isPreviewSupported == false, ".\(ext) files should not be previewable") + } + } + + @Test("Preview is supported for untitled documents") + func previewIsSupportedForUntitledDocuments() { + let doc = Document.new() + #expect(doc.isPreviewSupported == true) + } + + @Test("Preview support is case insensitive") + func previewSupportIsCaseInsensitive() { + let upperURL = URL(fileURLWithPath: "/path/to/file.MD") + let mixedURL = URL(fileURLWithPath: "/path/to/file.Markdown") + + let upperDoc = Document(fileURL: upperURL) + let mixedDoc = Document(fileURL: mixedURL) + + #expect(upperDoc.isPreviewSupported == true) + #expect(mixedDoc.isPreviewSupported == true) + } + + @Test("Preview is not supported for files without extensions") + func previewIsNotSupportedForFilesWithoutExtensions() { + let readmeURL = URL(fileURLWithPath: "/path/to/README") + let licenseURL = URL(fileURLWithPath: "/path/to/LICENSE") + + let readmeDoc = Document(fileURL: readmeURL) + let licenseDoc = Document(fileURL: licenseURL) + + #expect(readmeDoc.isPreviewSupported == false) + #expect(licenseDoc.isPreviewSupported == false) + } } diff --git a/tibok/user_docs/FAQ.md b/tibok/user_docs/FAQ.md index 024ed93..e656e44 100644 --- a/tibok/user_docs/FAQ.md +++ b/tibok/user_docs/FAQ.md @@ -92,6 +92,9 @@ Use View > Toggle Preview or press Cmd+\. ### Does the preview update in real-time? Yes, the preview updates as you type. +### Why does the preview show "Preview Not Available"? +Preview is only available for Markdown files (`.md`, `.markdown`, `.mdown`, `.mkd`). When you open other file types (like `.tsx`, `.txt`, `.js`), the preview pane will display a message indicating that preview is not supported for that file type. You can hide the preview with Cmd+\ to maximize your editor space. + ### How do I create nested lists? Use 2-space indentation per nesting level: ```markdown diff --git a/tibok/user_docs/features/preview.md b/tibok/user_docs/features/preview.md index da7581f..2ddfc9b 100644 --- a/tibok/user_docs/features/preview.md +++ b/tibok/user_docs/features/preview.md @@ -2,6 +2,16 @@ tibok provides a live preview pane that renders your markdown as you type. +## File Type Support + +Preview is **only available for Markdown files** with the following extensions: +- `.md` +- `.markdown` +- `.mdown` +- `.mkd` + +When you open a non-markdown file (e.g., `.tsx`, `.txt`, `.js`), the preview pane will display a message indicating that preview is not available for that file type. You can toggle the preview pane off with `Cmd+\` to maximize your editor space. + ## Showing/Hiding Preview - **Menu**: View > Toggle Preview