Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions tibok/tibok/Models/Document.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
43 changes: 43 additions & 0 deletions tibok/tibok/Views/PreviewView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
}
}
64 changes: 64 additions & 0 deletions tibok/tibokTests/DocumentTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
3 changes: 3 additions & 0 deletions tibok/user_docs/FAQ.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
10 changes: 10 additions & 0 deletions tibok/user_docs/features/preview.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down