Text Snippet Template Expansion

Markdown Monster includes support for text snippet expansions which which allow you to create a set of text snippets that can expand into larger blocks of repetive text in your documents. You can type a shortcut expression in your document, press hotkey or use the Snippet Form to then embed the expanded text into your document at the cursor position.

You can create text snippets that are plain static text, or you can use C# expressions or C# Razor templates to provide some dynamic logic into your snippets.

Creating Snippets with the Snippet Editor

You can create and manage your snippets using the Snippets Editor which you can access from the MM toolbar's Addin section.

This form allows you to add new snippets, create your snippet template text in the editor and assign shortcuts and hotkeys. You can also test your snippet right in the editor by pressing the test button which displays a message box with test result as a plain string.

Snippets contain plain text and you can use the ~ to specify the final cursor location after expansion. C# expressions can be embedded with {{expression}} syntax.

Embedding Snippets into your Document

To embed snippets into your document you can:

  • Type a ShortCut Expansion String
    This is a short mnemonic string you assign that you can type into the editor followed by a space and is then expanded into the document to replace the shortcut text.

  • Use a KeyBoard ShortCut
    You can define a keyboard shortcut for your snippet that causes the snippet to be injected. Note that this may not always work if there's a conflict with an existing shortcut in Markdown Monster. As MM contains many shortcuts it might be hard to find a combination that works.

  • Use the Snippets Form Navigation
    You can also interactively bring up the snippets form and navigate to a snippet you want to embed and either double click or press ENTER to embed expand the snippet into the current cursor position in the editor.

Snippet Examples

Snippets make a great use case for:

  • Signatures
  • Page or Support Templates
  • Prefilled Bug Reports
  • Timestamping documents

Here are a few examples.

Figure Caption

<small>**Figure ~** - </small>

This is useful for quickly creating figure captions where you can quickly type a figure number plus a description.

Current Formatted Date and Time

{{DateTime.Now.ToString("MMMM dd, yyyy at HH:mm tt")}}

Demonstrates using C# expression in a snippet.

Promotional Tag

<div style="margin-top: 30px;font-size: 0.8em;
            border-top: 1px solid #eee;padding-top: 8px;">
    <img src="https://markdownmonster.west-wind.com/favicon.png"
         style="height: 20px;float: left; margin-right: 10px;"/>
    this post created and published with 
    <a href="https://markdownmonster.west-wind.com" 
       target="top">Markdown Monster</a> 
</div>

This adds a largish block of HTML that can be embedded at the bottom of blog posts or other documents created.

Dynamic Code Embedding

Snippets support embedding of dynamic code using a couple of expression engines:

  • C# Expressions
  • C# @Razor Code

Embed C# Code Expressions

Snippets can contain embedded C# code expressions using {{ expression }} syntax which is evaluated when the snippet is rendered.

For example the following:

<div class="small">
   created by, Rick Strahl, on 
   {{DateTime.Now.ToString("MMM dd, yyyy")}}
</div>   

embeds a date into the snippet when it's created. Snippets can embed any text since Markdown supports both plain text as well as HTML markup as in the example above.

Access to the Addin Model

You also get access to the full Addin model that exposes a large chunk of Markdown Monsters active document, editor and UI using a Model property.

For example:

Full Filename: {{Model.ActiveDocument.Filename}}

Shows the currently open document's filename.

For more info on what's available check out the documentation or take a look at the Markdown Monster source code:

Using this option, you only get to apply expressions and no code blocks, but that still gives you a fair bit of functionality you can work with.

Embed C# Razor Code

If you need more control, you can also use ASP.NET Style Razor syntax for snippets. As with expressions the Model is also available in @Razor snippets.

The following template example accesses the Markdown Monster Model data to get data out of the documents.

Main Window Title:  @Model.Window.Title. 

Timestamp: @DateTime.Now.ToString("MMM dd, yyy")

Filename: @Model.ActiveDocument.Filename

Open Documents:
@foreach(var doc in Model.OpenDocuments) {
    <text>* @doc.Filename</text>
}

Here's another example that creates a Front Matter blog header which deduces the title from the filename

@{
    var file = Path.GetFileNameWithoutExtension(
                                 Model.ActiveDocument.Filename);
    file = StringUtils.FromCamelCase(file);
    file = file.Replace("-"," ");
}---
Title: @file
Timestamp: @DateTime.Now.ToString("MMM dd, yyyy HH:mm")
Tags:
-
---

Note that this example, relies on pre-loaded namespaces and assembly references. System.IO (namespace) and Westwind.Utilities (assembly and namespace) which are pre-loaded as part of the Razor Host startup.

Loading Assemblies and Namespaces

Any non-standard assemblies you might want to reference from the GAC or from disk, you have to explicitly add to your templates.

If you want to explicitly load an assembly and namespace you can do so by using the @reference and @namespace directives.

@reference must load out of the Install Folder

Any references must be loaded out of the Markdown Monster install folder. This limitation is deliberate to prevent script highjacking and requiring custom assemblies to be copied into only into a privileged folder on the local machine.

Here's a silly example that demonstrates showing a message as part of a template.

@reference System.Windows.Forms.dll
@using System.Windows.Forms
@{
    MessageBox.Show("hello world");
}
<div class="small">created on @DateTime.Now.ToString("d")</div>

Note assemblies have to be referenced with the .dll extension and have to be loaded out of the Markdown Monster install folder. They cannot have a path associated with it to limit security exposure as you need elevated rights to put a DLL into the installation folder (Program Files\MarkdownMonster).

Note: Razor Expressions are Html Encoded by Default

Because the engine is the ASP.NET Razor engine strings returned from @expressions are by default formatted to Html encoded text. For example:

@{
    var htmlString = "<div class='Header1'>Huuge</div>";
}
@htmlString

produces: &lt;div class='Header1'&gt;>Huuge&lt;/div&gt;.

If content you are creating shouldn't be HTML encoded you can use @Html.Raw(expression):

@{
    var htmlString = "<div class='Header1'>Huuge</div>";
}
@Html.Raw(htmlString)

Since Markdown is HTML aware however, in most cases HTML encoded strings will actually render correctly as Markdown so the use case for @Html.Raw() should be fairly minimal

Razor @helpers

You can also use Razor helpers in a snippet:

Message is: @HelloWorld("Rick")

@helper HelloWorld(string name) {
    <div>Hello world, @name! Time is: @DateTime.Now.ToString("d")</div>  
}

Cursor Position: ~ marks the Spot

By default the cursor position for an expanded snippet is immediately after the expanded snippet. If you want to place the cursor inside of the snippets text somewhere you can place a ~ character in the place where you want to cursor to end up.

---
Title: 
Timestamp: @DateTime.Now.ToString("MMM dd, yyyy HH:mm")
Tags:
- ~
---

Here the cursor will end up at the first tag item to be entered (at the -).

Expansion Keys

You can also create a shortcut extension key combination. When you type the key sequence and wait for the type timeout (around 800ms) the snippet is expanded in place to allow for keyboard based extension.

For example, in the screen shot the fmatter combination is set up for the script. So if I type fmatter in the editor and wait for a second the associated snippet is expanded. Note that the shortcut text to be expanded has to be at the end of the current line - text in the middle of a line is not expanded for performance considerations at this time.


© West Wind Technologies, 1996-2021 • Updated: 04/21/19
Comment or report problem with topic