Skip to content
Open
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
6 changes: 5 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ use std::path::PathBuf;

use eyre::{eyre, Result};
use gumdrop::Options;
use obsidian_export::postprocessors::{filter_by_tags, softbreaks_to_hardbreaks};
use obsidian_export::postprocessors::{
filter_by_tags, parse_obsidian_comments, softbreaks_to_hardbreaks,
};
use obsidian_export::{ExportError, Exporter, FrontmatterStrategy, WalkOptions};

const VERSION: &str = env!("CARGO_PKG_VERSION");
Expand Down Expand Up @@ -107,6 +109,8 @@ fn main() {
exporter.preserve_mtime(args.preserve_mtime);
exporter.walk_options(walk_options);

exporter.add_postprocessor(&parse_obsidian_comments);

if args.hard_linebreaks {
exporter.add_postprocessor(&softbreaks_to_hardbreaks);
}
Expand Down
56 changes: 56 additions & 0 deletions src/postprocessors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,62 @@ pub fn softbreaks_to_hardbreaks(
PostprocessorResult::Continue
}

/// In addition to HTML comments "<!-- my comment -->", Obsidian syntax includes a second comment
/// syntax "%% my comment %%". This function converts Obsidian-style comments to the standard HTML
/// style.
///
/// Because this step is done when the document is already parsed from markdown, any embedded
/// markup inside comments will be elided from the output.
pub fn parse_obsidian_comments(
context: &mut Context,
events: &mut MarkdownEvents<'_>,
) -> PostprocessorResult {
let mut in_comment = false;
let mut comment_acc = String::new();
let input = std::mem::take(events);
let mut output = MarkdownEvents::new();

for event in input {
match event {
Event::Text(s) => {
for (idx, text) in s.split("%%").enumerate() {
if idx > 0 {
if in_comment && !comment_acc.is_empty() {
output.push(Event::InlineHtml(format!("<!--{comment_acc}-->").into()));
comment_acc.clear();
}

in_comment = !in_comment;
}

if !text.is_empty() {
if in_comment {
comment_acc.push_str(text);
} else {
output.push(Event::Text(text.to_owned().into()));
}
}
}
}
_ => {
if !in_comment {
output.push(event);
}
}
}
}

assert!(
!in_comment,
"Unmatched comment delimiter in {}",
context.destination.display()
);

std::mem::swap(events, &mut output);

PostprocessorResult::Continue
}

pub fn filter_by_tags(
skip_tags: Vec<String>,
only_tags: Vec<String>,
Expand Down
18 changes: 18 additions & 0 deletions tests/export_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use std::io::prelude::*;
use std::os::unix::fs::PermissionsExt;
use std::path::PathBuf;

use obsidian_export::postprocessors::parse_obsidian_comments;
use obsidian_export::{ExportError, Exporter, FrontmatterStrategy};
use pretty_assertions::assert_eq;
use tempfile::TempDir;
Expand Down Expand Up @@ -459,3 +460,20 @@ fn test_same_filename_different_directories() {
let actual = read_to_string(tmp_dir.path().join(PathBuf::from("Note.md"))).unwrap();
assert_eq!(expected, actual);
}

#[test]
fn test_parse_obsidian_comments() {
let tmp_dir = TempDir::new().expect("failed to make tempdir");

let mut exporter = Exporter::new(
PathBuf::from("tests/testdata/input/comments/"),
tmp_dir.path().to_path_buf(),
);
exporter.add_postprocessor(&parse_obsidian_comments);
exporter.run().expect("exporter returned error");

assert_eq!(
read_to_string("tests/testdata/expected/comments/note.md").unwrap(),
read_to_string(tmp_dir.path().join(PathBuf::from("note.md"))).unwrap(),
);
}
8 changes: 8 additions & 0 deletions tests/testdata/expected/comments/note.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Test

<!-- A comment -->

Test2
<!-- A comment containing embedded markup -->

This sentence is <!-- not --> true.
8 changes: 8 additions & 0 deletions tests/testdata/input/comments/note.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Test

%% A comment %%

Test2
%% A comment containing [[embedded]] **markup** %%

This sentence is %% not %% true.