A permissively licensed markdown single-header library for Dear ImGui.

Overview

Support development of imgui_markdown through GitHub Sponsors or Patreon

Become a Patron

imgui_markdown

Markdown For Dear ImGui

A permissively licensed markdown single-header library for Dear ImGui.

Requires C++11 or above

imgui_markdown currently supports the following markdown functionality:

  • Wrapped text
  • Headers H1, H2, H3
  • Emphasis
  • Indented text, multi levels
  • Unordered list and sub-list
  • Link
  • Image
  • Horizontal rule

imgui_markdown demo live editing

Note - the gif above is heavily compressed due to GitHub limitations. There's a (slightly) better version of it on twitter.

Syntax

Wrapping

Text wraps automatically. To add a new line, use 'Return'.

Headers

# H1
## H2
### H3

Emphasis

*emphasis*
_emphasis_
**strong emphasis**
__strong emphasis__

Lists

Indent

On a new line, at the start of the line, add two spaces per indent.

Normal text
··Indent level 1
····Indent level 2
······Indent level 3
Normal text

Unordered list

On a new line, at the start of the line, add two spaces, an asterisks and a space. For nested lists, add two additional spaces in front of the asterisk per list level increment.

Normal text
··*·Unordered List level 1
····*·Unordered List level 2
······*·Unordered List level 3
······*·Unordered List level 3
··*·Unordered List level 1
Normal text

Link

[link description](https://...)

Image

![image alt text](image identifier e.g. filename)

Horizontal Rule

***
___

Example use of imgui_markdown with icon fonts

Unsupported Syntax Combinations

Non exhaustive

  • Header with link, image or emphasis included - header breaks link, image, emphasis
  • Emphasis with link or image - link, image break emphasis
  • Multiline emphasis - new line breaks emphasis

Example Use On Windows With Links Opening In Browser

#include "Shellapi.h" #include void LinkCallback( ImGui::MarkdownLinkCallbackData data_ ); inline ImGui::MarkdownImageData ImageCallback( ImGui::MarkdownLinkCallbackData data_ ); static ImFont* H1 = NULL; static ImFont* H2 = NULL; static ImFont* H3 = NULL; static ImGui::MarkdownConfig mdConfig; void LinkCallback( ImGui::MarkdownLinkCallbackData data_ ) { std::string url( data_.link, data_.linkLength ); if( !data_.isImage ) { ShellExecuteA( NULL, "open", url.c_str(), NULL, NULL, SW_SHOWNORMAL ); } } inline ImGui::MarkdownImageData ImageCallback( ImGui::MarkdownLinkCallbackData data_ ) { // In your application you would load an image based on data_ input. Here we just use the imgui font texture. ImTextureID image = ImGui::GetIO().Fonts->TexID; // > C++14 can use ImGui::MarkdownImageData imageData{ true, false, image, ImVec2( 40.0f, 20.0f ) }; ImGui::MarkdownImageData imageData; imageData.isValid = true; imageData.useLinkCallback = false; imageData.user_texture_id = image; imageData.size = ImVec2( 40.0f, 20.0f ); // For image resize when available size.x > image width, add ImVec2 const contentSize = ImGui::GetContentRegionAvail(); if( imageData.size.x > contentSize.x ) { float const ratio = imageData.size.y/imageData.size.x; imageData.size.x = contentSize.x; imageData.size.y = contentSize.x*ratio; } return imageData; } void LoadFonts( float fontSize_ = 12.0f ) { ImGuiIO& io = ImGui::GetIO(); io.Fonts->Clear(); // Base font io.Fonts->AddFontFromFileTTF( "myfont.ttf", fontSize_ ); // Bold headings H2 and H3 H2 = io.Fonts->AddFontFromFileTTF( "myfont-bold.ttf", fontSize_ ); H3 = mdConfig.headingFormats[ 1 ].font; // bold heading H1 float fontSizeH1 = fontSize_ * 1.1f; H1 = io.Fonts->AddFontFromFileTTF( "myfont-bold.ttf", fontSizeH1 ); } void ExampleMarkdownFormatCallback( const ImGui::MarkdownFormatInfo& markdownFormatInfo_, bool start_ ) { // Call the default first so any settings can be overwritten by our implementation. // Alternatively could be called or not called in a switch statement on a case by case basis. // See defaultMarkdownFormatCallback definition for furhter examples of how to use it. ImGui::defaultMarkdownFormatCallback( markdownFormatInfo_, start_ ); switch( markdownFormatInfo_.type ) { // example: change the colour of heading level 2 case ImGui::MarkdownFormatType::HEADING: { if( markdownFormatInfo_.level == 2 ) { if( start_ ) { ImGui::PushStyleColor( ImGuiCol_Text, ImGui::GetStyle().Colors[ImGuiCol_TextDisabled] ); } else { ImGui::PopStyleColor(); } } break; } default: { break; } } } void Markdown( const std::string& markdown_ ) { // You can make your own Markdown function with your prefered string container and markdown config. // > C++14 can use ImGui::MarkdownConfig mdConfig{ LinkCallback, NULL, ImageCallback, ICON_FA_LINK, { { H1, true }, { H2, true }, { H3, false } }, NULL }; mdConfig.linkCallback = LinkCallback; mdConfig.tooltipCallback = NULL; mdConfig.imageCallback = ImageCallback; mdConfig.linkIcon = ICON_FA_LINK; mdConfig.headingFormats[0] = { H1, true }; mdConfig.headingFormats[1] = { H2, true }; mdConfig.headingFormats[2] = { H3, false }; mdConfig.userData = NULL; mdConfig.formatCallback = ExampleMarkdownFormatCallback; ImGui::Markdown( markdown_.c_str(), markdown_.length(), mdConfig ); } void MarkdownExample() { const std::string markdownText = u8R"( # H1 Header: Text and Links You can add [links like this one to enkisoftware](https://www.enkisoftware.com/) and lines will wrap well. You can also insert images ![image alt text](image identifier e.g. filename) Horizontal rules: *** ___ *Emphasis* and **strong emphasis** change the appearance of the text. ## H2 Header: indented text. This text has an indent (two leading spaces). This one has two. ### H3 Header: Lists * Unordered lists * Lists can be indented with two extra spaces. * Lists can have [links like this one to Avoyd](https://www.avoyd.com/) and *emphasized text* )"; Markdown( markdownText ); }">
#include "ImGui.h"                // https://github.com/ocornut/imgui
#include "imgui_markdown.h"       // https://github.com/juliettef/imgui_markdown
#include "IconsFontAwesome5.h"    // https://github.com/juliettef/IconFontCppHeaders

// Following includes for Windows LinkCallback
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include "Shellapi.h"
#include <string>

void LinkCallback( ImGui::MarkdownLinkCallbackData data_ );
inline ImGui::MarkdownImageData ImageCallback( ImGui::MarkdownLinkCallbackData data_ );

static ImFont* H1 = NULL;
static ImFont* H2 = NULL;
static ImFont* H3 = NULL;

static ImGui::MarkdownConfig mdConfig; 


void LinkCallback( ImGui::MarkdownLinkCallbackData data_ )
{
    std::string url( data_.link, data_.linkLength );
    if( !data_.isImage )
    {
        ShellExecuteA( NULL, "open", url.c_str(), NULL, NULL, SW_SHOWNORMAL );
    }
}

inline ImGui::MarkdownImageData ImageCallback( ImGui::MarkdownLinkCallbackData data_ )
{
    // In your application you would load an image based on data_ input. Here we just use the imgui font texture.
    ImTextureID image = ImGui::GetIO().Fonts->TexID;
    // > C++14 can use ImGui::MarkdownImageData imageData{ true, false, image, ImVec2( 40.0f, 20.0f ) };
    ImGui::MarkdownImageData imageData;
    imageData.isValid =         true;
    imageData.useLinkCallback = false;
    imageData.user_texture_id = image;
    imageData.size =            ImVec2( 40.0f, 20.0f );

    // For image resize when available size.x > image width, add
    ImVec2 const contentSize = ImGui::GetContentRegionAvail();
    if( imageData.size.x > contentSize.x )
    {
        float const ratio = imageData.size.y/imageData.size.x;
        imageData.size.x = contentSize.x;
        imageData.size.y = contentSize.x*ratio;
    }

    return imageData;
}

void LoadFonts( float fontSize_ = 12.0f )
{
    ImGuiIO& io = ImGui::GetIO();
    io.Fonts->Clear();
    // Base font
    io.Fonts->AddFontFromFileTTF( "myfont.ttf", fontSize_ );
    // Bold headings H2 and H3
    H2 = io.Fonts->AddFontFromFileTTF( "myfont-bold.ttf", fontSize_ );
    H3 = mdConfig.headingFormats[ 1 ].font;
    // bold heading H1
    float fontSizeH1 = fontSize_ * 1.1f;
    H1 = io.Fonts->AddFontFromFileTTF( "myfont-bold.ttf", fontSizeH1 );
}

void ExampleMarkdownFormatCallback( const ImGui::MarkdownFormatInfo& markdownFormatInfo_, bool start_ )
{
    // Call the default first so any settings can be overwritten by our implementation.
    // Alternatively could be called or not called in a switch statement on a case by case basis.
    // See defaultMarkdownFormatCallback definition for furhter examples of how to use it.
    ImGui::defaultMarkdownFormatCallback( markdownFormatInfo_, start_ );        
       
    switch( markdownFormatInfo_.type )
    {
    // example: change the colour of heading level 2
    case ImGui::MarkdownFormatType::HEADING:
    {
        if( markdownFormatInfo_.level == 2 )
        {
            if( start_ )
            {
                ImGui::PushStyleColor( ImGuiCol_Text, ImGui::GetStyle().Colors[ImGuiCol_TextDisabled] );
            }
            else
            {
                ImGui::PopStyleColor();
            }
        }
        break;
    }
    default:
    {
        break;
    }
    }
}

void Markdown( const std::string& markdown_ )
{
    // You can make your own Markdown function with your prefered string container and markdown config.
    // > C++14 can use ImGui::MarkdownConfig mdConfig{ LinkCallback, NULL, ImageCallback, ICON_FA_LINK, { { H1, true }, { H2, true }, { H3, false } }, NULL };
    mdConfig.linkCallback =         LinkCallback;
    mdConfig.tooltipCallback =      NULL;
    mdConfig.imageCallback =        ImageCallback;
    mdConfig.linkIcon =             ICON_FA_LINK;
    mdConfig.headingFormats[0] =    { H1, true };
    mdConfig.headingFormats[1] =    { H2, true };
    mdConfig.headingFormats[2] =    { H3, false };
    mdConfig.userData =             NULL;
    mdConfig.formatCallback =       ExampleMarkdownFormatCallback;
    ImGui::Markdown( markdown_.c_str(), markdown_.length(), mdConfig );
}

void MarkdownExample()
{
    const std::string markdownText = u8R"(
# H1 Header: Text and Links
You can add [links like this one to enkisoftware](https://www.enkisoftware.com/) and lines will wrap well.
You can also insert images ![image alt text](image identifier e.g. filename)
Horizontal rules:
***
___
*Emphasis* and **strong emphasis** change the appearance of the text.
## H2 Header: indented text.
  This text has an indent (two leading spaces).
    This one has two.
### H3 Header: Lists
  * Unordered lists
    * Lists can be indented with two extra spaces.
  * Lists can have [links like this one to Avoyd](https://www.avoyd.com/) and *emphasized text*
)";
    Markdown( markdownText );
}

Projects Using imgui_markdown

Avoyd

Avoyd is an abstract 6 degrees of freedom voxel game.
www.avoyd.com

The game and the voxel editor's help and tutorials use imgui_markdown with Dear ImGui.

Avoyd screenshot

bgfx

Cross-platform rendering library.
bkaradzic.github.io/bgfx/overview

Imogen

GPU/CPU Texture Generator
skaven.fr/imogen

Imogen screenshot

Light Tracer

Experimental GPU ray tracer for web

Light Tracer screenshot

Visual 6502 Remix

Transistor level 6502 Hardware Simulation
hfloooh.github.io/visual6502remix

Using imgui_markdown as help viewer for Visual 6502 Remix with internal and external links:

Using imgui_markdown as help viewer for Visual 6502 Remix with internal and external links - animated gif Using imgui_markdown as help viewer for Visual 6502 Remix - screenshot

Using imgui_markdown in the About page for Visual 6502 Remix - screenshot

Credits

Design and implementation - Doug Binks - @dougbinks
Implementation and maintenance - Juliette Foucaut - @juliettef
Image resize example code - Soufiane Khiat
Emphasis and horizontal rule initial implementation - Dmitry Mekhontsev
Thanks to Omar Cornut for Dear ImGui

License (zlib)

Copyright (c) 2019 Juliette Foucaut and Doug Binks

This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software.

Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:

  1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
  2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
  3. This notice may not be removed or altered from any source distribution.
Comments
  • Code organization / structure

    Code organization / structure

    @bkaradzic mentions in issue 4 that he would prefer a separate header for the external interface.

    The way we use imgui_markdown.h in our project is we expose an external interface via our own string container, and the config isn't exposed. I'd thought people would likely use it that way, but I can see that for library projects they would like to expose a full external interface.

    I think there are several alternatives here:

    1. Keep the code as it is.
    2. Stick to one header file, but add #ifdef to separate the external interface and declarations from implementation, so that you could create a header and source file via these.
    3. Split into two as per https://github.com/bkaradzic/bgfx/blob/master/3rdparty/dear-imgui/widgets/markdown.h
    4. Split into header and .cpp file.

    Thoughts?

    question 
    opened by dougbinks 7
  • Image Resize when available size.x > image width

    Image Resize when available size.x > image width

    Resize when ImGui::GetContentRegionAvailWidth() < imageData.size.x with respect of image ratio. Xxqp7e86q0 Tested to support image position on the line (not convicing).

    float const imgPos = ImGui::GetCursorPosX();
    contentSize.x -= imgPos;
    

    TBD: support for:

    ![Alt](imgs/Image.png =250x50)
    // And
    ![Alt](imgs/Image.png =250x)
    
    enhancement 
    opened by soufianekhiat 5
  • Any hope of adding bold and italic?

    Any hope of adding bold and italic?

    Markdown always has bold and italic formatting - which are very useful for emphasis. While I know official Dear Imgui has stated no interest in text formatting I thought maybe you would find interest in adding them.

    enhancement 
    opened by frink 4
  • Adding

    Adding "inline" link support

    I noticed all Markdown renderers I've seen supported highlighting URLs in the text as links, without going through square brackets. Usually, this is constrained to a few well-known protocols, notably http, https, and ftp.

    I also found it was difficult to show a URL as its own text in imgui_markdown.

    So, I added "inline" link support. If some text starts with "http://" or "https://", the parser will recognize it as a link, and treat it similarly to http://foo.com.

    Here's the result in my project. The original text used no brackets or parens for the links. image

    opened by KABoissonneault 3
  • Line returns forced on '\n' rather than

    Line returns forced on '\n' rather than " \n"

    In most Markdown implementations a line return isn't added unless there are two empty spaces at the end of a line. This lets you wrap your markdown file nicely in your editor whilst also allowing your end viewer to wrap it accordingly.

    enhancement 
    opened by handsomematt 3
  • imgui_markdown does not display the last character

    imgui_markdown does not display the last character

    Hi

    As mentioned on twitter I started using imgui_markdown in glChAoS.P

    Using imgui_markdown with my help strings I realized that it does not display the last character.

    If the string is in form:

    std::string markdownText = u8R"(
    aaaaaP
    )";
    

    the problem does not seem to appear, because the last char is \n, but if I use: std::string markdownText = u8R"(aaaaaP)"; or a more simple: std::string markdownText = "aaaaP"; the P is not printed.

    Thanks

    bug 
    opened by BrutPitt 3
  • Icon

    Icon

    Here You show "This is an icon"

    I would like to see the code for that since I would like to use ICON_FA_STAR in the markdown but cannot get it to work

    Thank you in advance

    question 
    opened by ZoozleDev 2
  • Feedback request: new formatting customisation technique

    Feedback request: new formatting customisation technique

    Branch: dev_format_callback

    We'd like some feedback on our new MarkdownFormatCallback for customizable formatting. The way it works is you override DefaultMarkdownFormatCallback in your code to get features you require such as coloured text. See ExampleMarkdownFormatCallback for an example of how it works.

    Introducing this method is the first step towards adding features such as bold or italics, and permits much more customisable formatting.

    Thoughts?

    question 
    opened by juliettef 2
  • C++11 support

    C++11 support

    imgui_markdown currently requires C++14 due to the use of aggregate initializers along with default member initializers. Adding C++11 constructors would break users' code in a way that would be difficult to workaround, and adding initializer list constructors is somewhat of a pain.

    Question: do you need C++11 support and why?

    question 
    opened by juliettef 2
  • No or wrong text wrapping for links and headings.

    No or wrong text wrapping for links and headings.

    There are two problems with the current code concerning text wrapping:

    • Headings are wrapped at the wrong position because TextRegion always uses the normal text font to compute the wrap position but the font of a heading is usually larger than that.
    • Links are not wrapped at all. Shouldn't the code use the RenderLine() function like the other text elements do?
    bug 
    opened by rcane 2
  • Infinite loop when widget doesn't have enough horizontal space to fit a word.

    Infinite loop when widget doesn't have enough horizontal space to fit a word.

    There is bug here: https://github.com/juliettef/imgui_markdown/blob/d1726b1385f5790182892e41d4d8001a91fa0e04/imgui_markdown.h#L201

    When widthLeft is too small to fit whole word endPrevLine doesn't advance and it causes infinite loop.

    My workaround was:

    if (text == endPrevLine) {
        endPrevLine++;
    }
    

    Other minor issues:

    This: https://github.com/juliettef/imgui_markdown/blob/d1726b1385f5790182892e41d4d8001a91fa0e04/imgui_markdown.h#L155

    Should be (fixes clang error): HeadingFormat headingFormats[ NUMHEADINGS ] = { { NULL, true }, { NULL, true }, { NULL, true } };

    Also I would suggest to create .h file that contains only definitions users should use. I did this inside bgfx: https://github.com/bkaradzic/bgfx/blob/master/3rdparty/dear-imgui/widgets/markdown.h

    Sorry for not creating PR...

    bug 
    opened by bkaradzic 2
  • Support square brackets in link text

    Support square brackets in link text

    Add support for nested square brackets in link text.

    ex.

    [alice [at] example dot com](https://example.com) previously parsed as:

    TEXT: alice [at
    LINK: https://example.com
    

    This will now parse as:

    TEXT: alice [at] example dot com
    LINK: https://example.com
    
    opened by jasmaa 0
  • Minor Fixes

    Minor Fixes

    This patch fixes a few small things which annoyed me:

    • Remove trailing whitespace from all files
    • Change the indentation style to be four spaces everywhere (since it was the most prevalent one)
    • Remove a unneeded variable
    opened by mee4895 1
  • Will you consider add table?

    Will you consider add table?

    Add basic table, so we can make item alignment in one row, like this | 1 | 2 | 3 | | ------ | ------ | ------ | | column 1 | column2 long text | 3 | | 1 | column2 | long text |

    It's better if we can hide/show the title of the table, separator lines. thanx

    enhancement 
    opened by miscvariables 1
Owner
Juliette Foucaut
Game developer, C++, python, testing. Co-founder of enkisoftware with @dougbinks. Occasionally available for consultancy.
Juliette Foucaut
Addon widgets for GUI library Dear ImGui.

ImGui-Addons Addon widgets for GUI library Dear ImGui. File Dialog A simple cross-platform file dialog that uses dirent interface for reading director

null 286 Jan 7, 2023
Dear ImGui: Bloat-free Graphical User interface for C++ with minimal dependencies

Dear ImGui (This library is available under a free and permissive license, but needs financial support to sustain its continued improvements. In addit

omar 44.5k Jan 7, 2023
Advanced 2D Plotting for Dear ImGui

ImPlot ImPlot is an immediate mode, GPU accelerated plotting library for Dear ImGui. It aims to provide a first-class API that ImGui fans will love. I

Evan Pezent 2.9k Jan 9, 2023
Real-time GUI layout creator/editor for Dear ImGui

ImStudio Real-time GUI layout creator/editor for Dear ImGui Inspired by Code-Building/ImGuiBuilder Features Drag edit Property edit Covers most of the

null 303 Jan 9, 2023
Dear ImGui prototyping wrapper.

LabImGui Prototyping framework LabImGui wraps up creating a window, GL bindings, and a full screen docking set up with ImGui so that all of the boiler

Nick Porcino 1 Dec 5, 2022
An integrated information center created with dear ImGui using modern C++ design / coding style.

ImGui info-center Introduction An integrated notification and information center created with dear ImGui. Interfaces and variables are designed under

Feej 7 Oct 29, 2022
This is a software renderer for Dear ImGui. I built it not out of a specific need, but because it was fun

Dear ImGui software renderer This is a software renderer for Dear ImGui. I built it not out of a specific need, but because it was fun. The goal was t

Emil Ernerfeldt 214 Dec 22, 2022
Immediate mode 3D gizmo for scene editing and other controls based on Dear Imgui

ImGuizmo Latest stable tagged version is 1.83. Current master version is 1.84 WIP. What started with the gizmo is now a collection of dear imgui widge

Cedric Guillemet 2.3k Dec 27, 2022
This is a thin c-api wrapper programmatically generated for the excellent C++ immediate mode gui Dear ImGui.

cimgui This is a thin c-api wrapper programmatically generated for the excellent C++ immediate mode gui Dear ImGui. All imgui.h functions are programm

Victor Bombi 22 Jul 5, 2021
Nice things to use along dear imgui

Mini hexadecimal editor! Right-click for option menu. Features: Keyboard controls. Read-only mode. Optional Ascii display. Optional HexII display. Goto address. Highlight range/function. Read/Write handlers.

omar 664 Jan 1, 2023
Window and GUI system based on Dear ImGui from OCornut

ImWindow Window and GUI system based on ImGui from OCornut. Include docking/floating window, multi window and multi render support. Platform Actually

Thibault Hennequin 715 Dec 20, 2022
Sample Unreal Engine 5.0.1 C++ Project That Incorporates Dear ImGui

UE5 With Dear ImGui A sample Unreal Engine 5.0.1 C++ project that incorporates the Dear ImGui graphical user interface library. YouTube Tutorial This

Kyle Geske 36 Dec 25, 2022
Simple ImGui external base. Uses ImGui DX9.

ImGui External Base ??️ What is this? ⚡ Hello all! I used to use noteffex's loader base for all my external ImGui projects. I got bored of using this

Alfie 11 Jun 29, 2022
An addon of imgui for supporting docks in the imgui's window

An addon of imgui for support dock in the window

BB 207 Nov 29, 2022
This is a minimal state immediate mode graphical user interface toolkit written in ANSI C and licensed under public domain

This is a minimal state immediate mode graphical user interface toolkit written in ANSI C and licensed under public domain. It was designed as a simple embeddable user interface for application and does not have any dependencies, a default render backend or OS window and input handling but instead provides a very modular library approach by using simple input state for input and draw commands describing primitive shapes as output.

Micha Mettke 13.5k Jan 8, 2023
A single-header ANSI C immediate mode cross-platform GUI library

Nuklear This is a minimal-state, immediate-mode graphical user interface toolkit written in ANSI C and licensed under public domain. It was designed a

Immediate Mode UIs, Nuklear, etc. 6.7k Dec 24, 2022
A barebones single-header GUI library for Win32 and X11.

luigi A barebones single-header GUI library for Win32 and X11. Building example Windows Update luigi_example.c to #define UI_WINDOWS at the top of the

Nakst 235 Dec 30, 2022
CMakeLists wrapper around imgui

ImGui Wrappings This is a trifold wrapper for the Dear ImGui library. Ease integration with CMake, Provide an RAII mechanism for ImGui scopes, Provide

Oliver Smith 39 Dec 8, 2022
super duper simple gui for C, wrapping imgui and stb

super duper simle gui for C, wrapping imgui and stb You can use it as a static library with cmake. See the example directory for a complete example. E

Rasmus 11 May 19, 2022