Overview

obsidian-export is a tool that I use in my workflow to host my digital garden. You can learn more about it at obsidian-export. You can find the source code of my fork on my Github.

My Changes

Remove Obsidian Comments

I added a new command line flag —remove-obsidian-comments This is implemented as a post_processor removing anything between two % which Obsidian uses to denote comments. However if the comment is within a code block (as seen below) it won’t be removed.

This isn't a comment
%% This is a comment %%

I use regex in-order to find the comments in the text.

Source Code

pub fn remove_obsidian_comments(  _context: &mut Context, events: &mut MarkdownEvents,  ) -> PostprocessorResult {  
    let mut output = Vec::with_capacity(events.len());  
    let mut inside_comment = false;  
    let mut inside_codeblock = false;  
  
    for event in &mut *events {  
        output.push(event.to_owned());  
  
        match event {  
            Event::Text(ref text) => {  
                if !text.contains("%%") {  
                    if inside_comment {  
                        output.pop();  
                    }                    
                    continue;  
                } else if inside_codeblock {  
                    continue;  
                }  
                output.pop();  
 
                if inside_comment {  
                    inside_comment = false;  
                    continue;  
                }  
                if !text.eq(&CowStr::from("%%")) {  
                    let re = Regex::new(r"%%.*?%%").unwrap();  
                    let result = re.replace_all(text, "").to_string();  
                    output.push(Event::Text(CowStr::from(result)));  
                    continue;  
                }  
                inside_comment = true;  
            }            
            Event::Start(Tag::CodeBlock(_)) => {  
                inside_codeblock = true;  
            }            
            Event::End(Tag::CodeBlock(_)) => {  
                inside_codeblock = false;  
            }  
            _ => {  
                if inside_comment {  
                    output.pop();  
                }            
            }        
        }    
    }  
    *events = output;  
    PostprocessorResult::Continue  
}

Remove table of contents

In my obsidian vault I have a table of contents at the top of most of my notes. However, I currently host my notes through Quartz which offers a table of contents on the right side of the screen. Because of this I don’t also need a table of contents on the top so I just remove it from the markdown file before publishing. I originally was going to render the table of contents myself (seen here Automatic Table of Contents Bug) but I decided this wasn’t worth the effort and to just use the quartz table of contents.

This code is heavily borrowed from an example provided by Nick Groenen, creator of obsidian-export. This option is invoked through the flag —remove-table-of-contents

Source Code

pub fn remove_toc(_context: &mut Context, events: &mut MarkdownEvents) -> PostprocessorResult {  
    let mut output = Vec::with_capacity(events.len());  
  
    for event in &mut *events {  
        output.push(event.to_owned());  
        match event {  
            Event::Start(Tag::CodeBlock(CodeBlockKind::Fenced(ref language_tag))) => {  
                if language_tag != &CowStr::from("toc") && language_tag != &CowStr::from("table-of-contents")  {                    
	                continue;  
            }                
            
            output.pop(); // Remove codeblock start tag that was pushed onto output              
            }  
            
            Event::End(Tag::CodeBlock(CodeBlockKind::Fenced(ref language_tag))) => {  
                if language_tag == &CowStr::from("toc") && language_tag != &CowStr::from("table-of-contents")  {                    
	                // The corresponding codeblock start tag for this is replaced with regular  
                    // text (containing the Hugo shortcode), so we must also pop this end tag.                    
                    output.pop();  
                }            
            }            
            _ => {}  
        }    
    }    
    *events = output;  
    PostprocessorResult::Continue  
}