This example demonstrates the standard open-edit-save pipeline with Markdown (MD) documents, using different options on every step.
Introduction
Markdown is a lightweight markup language, which has become popular lately. Markdown files with an *.md extension are actually plain text files that contain special syntax, and support text formatting, tables, lists, images, and so on. There are several dialects of Markdown, including GFM, CommonMark, Multi-Markdown, and so on.
GroupDocs.Editor for Python via .NET fully supports the Markdown format on both import and export, as well as its auto-detection. GroupDocs.Editor supports the following Markdown features, which mostly follow the CommonMark specification: headings, blockquotes, code blocks, horizontal rules, bold emphasis, italic emphasis, strikethrough formatting, numbered and bulleted lists, tables, internal images (stored with base64 encoding), and external images.
Loading
Loading Markdown documents into the Editor class is usual and the same as for other formats. There are no dedicated load options for the Markdown format; it is enough to specify the file itself through a file path or a byte stream.
fromgroupdocs.editorimportEditor# Load from a file patheditor_from_path=Editor("article.md")# Load from a binary streamwithopen("article.md","rb")asstream:editor_from_stream=Editor(stream)
Editing
There is a special class MarkdownEditOptions for editing Markdown files. As always, it is not mandatory when editing a document, so the parameterless editor.edit() overload may be used — GroupDocs.Editor will automatically detect the format and apply the default options.
However, specifying the custom MarkdownEditOptions may be vital when an input Markdown file has external images. “External” means that images are stored somewhere else, and in the Markdown code there are links to these images. In order to point GroupDocs.Editor to all external images, the image_load_callback property of MarkdownEditOptions should be specified with an implementation of the image load callback interface, which provides the image data to GroupDocs.Editor when it encounters a link to an external image. This is an advanced scenario that requires a callback object; a schematic, non-runnable illustration is shown below.
fromgroupdocs.editor.optionsimportMarkdownEditOptions# Assume image_loader is an object that implements the Markdown image load callback,# returning binary data for each external image referenced from the Markdown fileedit_options=MarkdownEditOptions()edit_options.image_load_callback=image_loaderopened=editor.edit(edit_options)
Saving
GroupDocs.Editor also supports saving into the Markdown format. Like for any other format, for saving into Markdown the user must create an instance of the MarkdownSaveOptions class and specify it in the editor.save() method.
If the document destined for saving in the Markdown format has images, they can be resolved in one of three ways:
Ignore images — they will be absent.
Save images inside the Markdown code, where they will be stored in base64 encoding.
Save images as separate files in a specified folder, and in the Markdown code there will be references to these image files.
For this the MarkdownSaveOptions class has several properties. export_images_as_base64 is a boolean flag, by default set to False. If set to True, the content of the images will be injected inside the output Markdown as base64. This flag has the highest priority, and when it is True the images_folder property is ignored. The images_folder property, in turn, works when export_images_as_base64 is set to False; if specified, it should contain a valid path to an existing folder where GroupDocs.Editor should save the images.
Roundtrip
Because the Markdown format is supported on both import and export, it is possible to perform a roundtrip scenario — open a Markdown file for editing, edit it, and then save the edited version back to the Markdown format. The runnable example below demonstrates such a scenario with a Markdown file that has no external images, so no image load callback is needed.
importosfromgroupdocs.editorimportEditor,EditableDocument,Licensefromgroupdocs.editor.optionsimportMarkdownEditOptions,MarkdownSaveOptionsdefedit_markdown():# Optionally set a licenselicense_path=os.path.abspath("./GroupDocs.Editor.lic")ifos.path.exists(license_path):License().set_license(license_path)# Load an input Markdown file into the EditorwithEditor("./sample-article.markdown")aseditor:# Create the Markdown edit optionsedit_options=MarkdownEditOptions()# Edit the Markdown document and obtain an EditableDocumenteditable=editor.edit(edit_options)# Edit the content programmatically (in practice this is done in a WYSIWYG-editor)html=editable.get_embedded_html()edited=EditableDocument.from_markup(html.replace("</p>"," (edited)</p>",1))# Create Markdown save options with images embedded as base64save_options=MarkdownSaveOptions()save_options.export_images_as_base64=True# Save the edited document back to the Markdown formateditor.save(edited,"./edited-article.md",save_options)editable.dispose()edited.dispose()if__name__=="__main__":edit_markdown()
sample-article.markdown is the sample file used in this example. Click here to download it.
# Sample Article
This is a **sample Markdown document** used by the GroupDocs.Editor for Python via .NET examples.
## Introduction
GroupDocs.Editor converts Markdown to editable HTML and back, so you can edit content programmatically or in any WYSIWYG editor.
## Features
- Headings, paragraphs, and emphasis
- Ordered and unordered lists
- Links such as [GroupDocs](https://www.groupdocs.com)
- Inline code and fenced code blocks
## Example List
[TRUNCATED]
In this example the same Markdown file is opened for editing and then saved back into the Markdown format with all images embedded as base64. The export_images_as_base64 flag could be replaced with the images_folder property to store images as separate files instead.
Was this page helpful?
Any additional feedback you'd like to share with us?
Please tell us how we can improve this page.
Thank you for your feedback!
We value your opinion. Your feedback will help us improve our documentation.