Copyright 2011-2016 Ali Rantakari -- http://hasseg.org
This is a syntax highlighter for the Markdown language, designed to be integrated into GUI text editor programs. It uses a recursive-descent parser for interpreting the input (instead of e.g. regular expressions), and this parser is based on the PEG grammar from John MacFarlane's peg-markdown project.
PEG Markdown Highlight…
This program uses the PEG grammar from John MacFarlane's peg-markdown
project,
and the greg
parser generator by Why The Lucky Stiff and Amos Wenger (greg
is heavily based on peg/leg
by Ian Piumarta). It also contains an
implementation of the merge sort algorithm for linked lists by Simon Tatham.
Thanks to these gentlemen (and everyone who contributed to their projects) for making this one possible.
See the LICENSE
file for licensing information.
Existing syntax highlighting solutions in (programming) editors are too simple to be able to handle the context sensitivity of the Markdown language, and the fact that it is not well defined. They usually work well for simple cases but fail for many nontrivial inputs that existing Markdown compilers handle correctly. This project is an attempt to bring Markdown syntax highlighting to the same level of “correctness” as the existing compilers.
Here are some quick, simple examples of what it might look like to use this highlighter in your project.
Using the Cocoa highlighter classes to highlight an NSTextView with default settings:
#import "HGMarkdownHighlighter.h"
@interface MyClass : NSObject {
HGMarkdownHighlighter *highlighter;
}
- (void) awakeFromNib {
highlighter = [[HGMarkdownHighlighter alloc]
initWithTextView:myTextView];
[highlighter activate];
}
Manually highlighting a TextWidget in some hypothetical GUI framework:
#include "pmh_parser.h"
void highlight(TextWidget *textWidget)
{
pmh_element **results;
pmh_markdown_to_elements(textWidget->containedText, pmh_EXT_NONE, &results);
for (int i = 0; i < pmh_NUM_LANG_TYPES; i++) {
TextStyle style;
switch (i) {
case pmh_EMPH: style = ItalicStyle; break;
case pmh_STRONG: style = BoldStyle; break;
case pmh_H1: style = LargeFontStyle; break;
default: style = FunkyStyle; break;
}
pmh_element *element_cursor = results[i];
while (element_cursor != NULL) {
textWidget->setStyleForSpan(element_cursor->pos,
element_cursor->end,
style);
element_cursor = element_cursor->next;
}
}
pmh_free_elements(results);
}
This project contains:
NSTextView
s in Cocoa applications.GtkTextView
in a GTK+ application.QTextEdit
in a Qt application.The public APIs are documented using Doxygen. If you have it installed,
just run make docs
and they should be available under the docs/
directory.
The parser has been written in ANSI/ISO C89 with GNU extensions, which means
that you need a GCC-compatible compiler (see section on MSVC below, though).
You also need Bourne Shell and some common Unix utilities due to a utility
shell script that is used to combine some files in a make
step.
You need to add the following files into your project:
pmh_definitions.h
pmh_parser.h
pmh_parser.c
pmh_parser.c
implements the parser and must be generated with make
.
pmh_parser.h
contains the parser's public interface and
pmh_definitions.h
some public definitions you might want to use in files
where you don't wish to import the parser interface itself.
First you need to generate pmh_parser.c
somehow. There are two main
ways to do this:
make
in the MinGW shell)Whichever way you go, the command you run is make pmh_parser.c
.
MSVC does not support some of the GNU extensions the code uses, but it should
compile it nicely as C++ (just change the extensions to .cpp
or set some
magic switch in the project settings to get the same effect). You may need to
insert the following to the beginning of pmh_parser.c
:
#include "stdafx.h"
The pmh_styleparser.h
file contains the style parser's public interface and
the pmh_styleparser.c
file implements the parser. The style parser depends
on the main parser.
The stylesheet syntax is documented in /styleparser/stylesheet_syntax.md
.
This file is compiled into an HTML format upon running make docs
.