mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-04-23 00:19:15 -04:00
adding pegmarkdown support library.
git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5953 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
parent
4413536926
commit
3be22536df
libretroshare/src/services
supportlibs/pegmarkdown
GLibFacade.cGLibFacade.hLICENSEMakefile.orig
MarkdownTest_1.0.3
MarkdownTest.pl
README.markdownglib.hmarkdown.cmarkdown_lib.cmarkdown_lib.hmarkdown_output.cmarkdown_parser.cmarkdown_parser.legmarkdown_peg.hodf.codf.hparsing_functions.cparsing_functions.hTests
Amps and angle encoding.htmlAmps and angle encoding.textAuto links.htmlAuto links.textBackslash escapes.htmlBackslash escapes.textBlockquotes with code blocks.htmlBlockquotes with code blocks.textCode Blocks.htmlCode Blocks.textCode Spans.htmlCode Spans.textHard-wrapped paragraphs with list-like lines.htmlHard-wrapped paragraphs with list-like lines.textHorizontal rules.htmlHorizontal rules.textInline HTML (Advanced).htmlInline HTML (Advanced).textInline HTML (Simple).htmlInline HTML (Simple).textInline HTML comments.htmlInline HTML comments.textLinks, inline style.htmlLinks, inline style.textLinks, reference style.htmlLinks, reference style.textLinks, shortcut references.htmlLinks, shortcut references.textLiteral quotes in titles.htmlLiteral quotes in titles.textMarkdown Documentation - Basics.htmlMarkdown Documentation - Basics.textMarkdown Documentation - Syntax.htmlMarkdown Documentation - Syntax.textNested blockquotes.htmlNested blockquotes.textOrdered and unordered lists.htmlOrdered and unordered lists.textStrong and em together.htmlStrong and em together.textTabs.htmlTabs.textTidyness.htmlTidyness.text
peg-0.1.9
@ -2,6 +2,7 @@
|
||||
#include <algorithm>
|
||||
#include <math.h>
|
||||
#include <sstream>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "p3posted.h"
|
||||
#include "gxs/rsgxsflags.h"
|
||||
|
208
supportlibs/pegmarkdown/GLibFacade.c
Normal file
208
supportlibs/pegmarkdown/GLibFacade.c
Normal file
@ -0,0 +1,208 @@
|
||||
/*
|
||||
* GLibFacade.c
|
||||
* MultiMarkdown
|
||||
*
|
||||
* Created by Daniel Jalkut on 7/26/11.
|
||||
* Modified by Fletcher T. Penney on 9/15/11.
|
||||
* Modified by Dan Lowe on 1/3/12.
|
||||
* Copyright 2011 __MyCompanyName__. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "GLibFacade.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
/*
|
||||
* The following section came from:
|
||||
*
|
||||
* http://lists-archives.org/mingw-users/12649-asprintf-missing-vsnprintf-
|
||||
* behaving-differently-and-_vsncprintf-undefined.html
|
||||
*
|
||||
* and
|
||||
*
|
||||
* http://groups.google.com/group/jansson-users/browse_thread/thread/
|
||||
* 76a88d63d9519978/041a7d0570de2d48?lnk=raot
|
||||
*/
|
||||
|
||||
/* Solaris and Windows do not provide vasprintf() or asprintf(). */
|
||||
#if defined(__WIN32) || (defined(__SVR4) && defined(__sun))
|
||||
int vasprintf( char **sptr, char *fmt, va_list argv )
|
||||
{
|
||||
int wanted = vsnprintf( *sptr = NULL, 0, fmt, argv );
|
||||
if( (wanted > 0) && ((*sptr = malloc( 1 + wanted )) != NULL) )
|
||||
return vsprintf( *sptr, fmt, argv );
|
||||
|
||||
return wanted;
|
||||
}
|
||||
|
||||
int asprintf( char **sptr, char *fmt, ... )
|
||||
{
|
||||
int retval;
|
||||
va_list argv;
|
||||
va_start( argv, fmt );
|
||||
retval = vasprintf( sptr, fmt, argv );
|
||||
va_end( argv );
|
||||
return retval;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* GString */
|
||||
|
||||
#define kStringBufferStartingSize 1024
|
||||
#define kStringBufferGrowthMultiplier 2
|
||||
|
||||
GString* g_string_new(char *startingString)
|
||||
{
|
||||
GString* newString = malloc(sizeof(GString));
|
||||
|
||||
if (startingString == NULL) startingString = "";
|
||||
|
||||
size_t startingBufferSize = kStringBufferStartingSize;
|
||||
size_t startingStringSize = strlen(startingString);
|
||||
while (startingBufferSize < (startingStringSize + 1))
|
||||
{
|
||||
startingBufferSize *= kStringBufferGrowthMultiplier;
|
||||
}
|
||||
|
||||
newString->str = malloc(startingBufferSize);
|
||||
newString->currentStringBufferSize = startingBufferSize;
|
||||
strncpy(newString->str, startingString, startingStringSize);
|
||||
newString->str[startingStringSize] = '\0';
|
||||
newString->currentStringLength = startingStringSize;
|
||||
|
||||
return newString;
|
||||
}
|
||||
|
||||
char* g_string_free(GString* ripString, bool freeCharacterData)
|
||||
{
|
||||
char* returnedString = ripString->str;
|
||||
if (freeCharacterData)
|
||||
{
|
||||
if (ripString->str != NULL)
|
||||
{
|
||||
free(ripString->str);
|
||||
}
|
||||
returnedString = NULL;
|
||||
}
|
||||
|
||||
free(ripString);
|
||||
|
||||
return returnedString;
|
||||
}
|
||||
|
||||
static void ensureStringBufferCanHold(GString* baseString, size_t newStringSize)
|
||||
{
|
||||
size_t newBufferSizeNeeded = newStringSize + 1;
|
||||
if (newBufferSizeNeeded > baseString->currentStringBufferSize)
|
||||
{
|
||||
size_t newBufferSize = baseString->currentStringBufferSize;
|
||||
|
||||
while (newBufferSizeNeeded > newBufferSize)
|
||||
{
|
||||
newBufferSize *= kStringBufferGrowthMultiplier;
|
||||
}
|
||||
|
||||
baseString->str = realloc(baseString->str, newBufferSize);
|
||||
baseString->currentStringBufferSize = newBufferSize;
|
||||
}
|
||||
}
|
||||
|
||||
void g_string_append(GString* baseString, char* appendedString)
|
||||
{
|
||||
if ((appendedString != NULL) && (strlen(appendedString) > 0))
|
||||
{
|
||||
size_t appendedStringLength = strlen(appendedString);
|
||||
size_t newStringLength = baseString->currentStringLength + appendedStringLength;
|
||||
ensureStringBufferCanHold(baseString, newStringLength);
|
||||
|
||||
/* We already know where the current string ends, so pass that as the starting address for strncat */
|
||||
strncat(baseString->str + baseString->currentStringLength, appendedString, appendedStringLength);
|
||||
baseString->currentStringLength = newStringLength;
|
||||
}
|
||||
}
|
||||
|
||||
void g_string_append_c(GString* baseString, char appendedCharacter)
|
||||
{
|
||||
size_t newSizeNeeded = baseString->currentStringLength + 1;
|
||||
ensureStringBufferCanHold(baseString, newSizeNeeded);
|
||||
|
||||
baseString->str[baseString->currentStringLength] = appendedCharacter;
|
||||
baseString->currentStringLength++;
|
||||
baseString->str[baseString->currentStringLength] = '\0';
|
||||
}
|
||||
|
||||
void g_string_append_printf(GString* baseString, char* format, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
|
||||
char* formattedString = NULL;
|
||||
vasprintf(&formattedString, format, args);
|
||||
if (formattedString != NULL)
|
||||
{
|
||||
g_string_append(baseString, formattedString);
|
||||
free(formattedString);
|
||||
}
|
||||
}
|
||||
|
||||
void g_string_prepend(GString* baseString, char* prependedString)
|
||||
{
|
||||
if ((prependedString != NULL) && (strlen(prependedString) > 0))
|
||||
{
|
||||
size_t prependedStringLength = strlen(prependedString);
|
||||
size_t newStringLength = baseString->currentStringLength + prependedStringLength;
|
||||
ensureStringBufferCanHold(baseString, newStringLength);
|
||||
|
||||
memmove(baseString->str + prependedStringLength, baseString->str, baseString->currentStringLength);
|
||||
strncpy(baseString->str, prependedString, prependedStringLength);
|
||||
baseString->currentStringLength = newStringLength;
|
||||
baseString->str[baseString->currentStringLength] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
/* GSList */
|
||||
|
||||
void g_slist_free(GSList* ripList)
|
||||
{
|
||||
GSList* thisListItem = ripList;
|
||||
while (thisListItem != NULL)
|
||||
{
|
||||
GSList* nextItem = thisListItem->next;
|
||||
|
||||
/* I guess we don't release the data? Non-retained memory management is hard... let's figure it out later. */
|
||||
free(thisListItem);
|
||||
|
||||
thisListItem = nextItem;
|
||||
}
|
||||
}
|
||||
|
||||
/* Currently only used for markdown_output.c endnotes printing */
|
||||
GSList* g_slist_reverse(GSList* theList)
|
||||
{
|
||||
GSList* lastNodeSeen = NULL;
|
||||
|
||||
/* Iterate the list items, tacking them on to our new reversed List as we find them */
|
||||
GSList* listWalker = theList;
|
||||
while (listWalker != NULL)
|
||||
{
|
||||
GSList* nextNode = listWalker->next;
|
||||
listWalker->next = lastNodeSeen;
|
||||
lastNodeSeen = listWalker;
|
||||
listWalker = nextNode;
|
||||
}
|
||||
|
||||
return lastNodeSeen;
|
||||
}
|
||||
|
||||
GSList* g_slist_prepend(GSList* targetElement, void* newElementData)
|
||||
{
|
||||
GSList* newElement = malloc(sizeof(GSList));
|
||||
newElement->data = newElementData;
|
||||
newElement->next = targetElement;
|
||||
return newElement;
|
||||
}
|
||||
|
67
supportlibs/pegmarkdown/GLibFacade.h
Normal file
67
supportlibs/pegmarkdown/GLibFacade.h
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* GLibFacade.h
|
||||
* MultiMarkdown
|
||||
*
|
||||
* Created by Daniel Jalkut on 7/26/11.
|
||||
* Copyright 2011 __MyCompanyName__. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __MARKDOWN_GLIB_FACADE__
|
||||
#define __MARKDOWN_GLIB_FACADE__
|
||||
|
||||
/* peg_markdown uses the link symbol for its own purposes */
|
||||
#define link MARKDOWN_LINK_IGNORED
|
||||
#include <unistd.h>
|
||||
#undef link
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <ctype.h>
|
||||
|
||||
typedef int gboolean;
|
||||
typedef char gchar;
|
||||
|
||||
/* This style of bool is used in shared source code */
|
||||
#define FALSE false
|
||||
#define TRUE true
|
||||
|
||||
/* WE implement minimal mirror implementations of GLib's GString and GSList
|
||||
* sufficient to cover the functionality required by MultiMarkdown.
|
||||
*
|
||||
* NOTE: THese are 100% clean, from-scratch implementations using only the
|
||||
* GLib function prototype as guide for behavior.
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
/* Current UTF8 byte stream this string represents */
|
||||
char* str;
|
||||
|
||||
/* Where in the str buffer will we add new characters */
|
||||
/* or append new strings? */
|
||||
int currentStringBufferSize;
|
||||
int currentStringLength;
|
||||
} GString;
|
||||
|
||||
GString* g_string_new(char *startingString);
|
||||
char* g_string_free(GString* ripString, bool freeCharacterData);
|
||||
|
||||
void g_string_append_c(GString* baseString, char appendedCharacter);
|
||||
void g_string_append(GString* baseString, char *appendedString);
|
||||
|
||||
void g_string_prepend(GString* baseString, char* prependedString);
|
||||
|
||||
void g_string_append_printf(GString* baseString, char* format, ...);
|
||||
|
||||
/* Just implement a very simple singly linked list. */
|
||||
|
||||
typedef struct _GSList
|
||||
{
|
||||
void* data;
|
||||
struct _GSList* next;
|
||||
} GSList;
|
||||
|
||||
void g_slist_free(GSList* ripList);
|
||||
GSList* g_slist_prepend(GSList* targetElement, void* newElementData);
|
||||
GSList* g_slist_reverse(GSList* theList);
|
||||
|
||||
#endif
|
88
supportlibs/pegmarkdown/LICENSE
Normal file
88
supportlibs/pegmarkdown/LICENSE
Normal file
@ -0,0 +1,88 @@
|
||||
markdown in c, implemented using PEG grammar
|
||||
Copyright (c) 2008-2011 John MacFarlane
|
||||
ODF output code (c) 2011 Fletcher T. Penney
|
||||
|
||||
peg-markdown is released under both the GPL and MIT licenses.
|
||||
You may pick the license that best fits your needs.
|
||||
|
||||
The GPL
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
The MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
|
||||
peg-0.1.4 (included for convenience - http://piumarta.com/software/peg/)
|
||||
|
||||
Copyright (c) 2007 by Ian Piumarta
|
||||
All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the 'Software'),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, provided that the above copyright notice(s) and this
|
||||
permission notice appear in all copies of the Software. Acknowledgement
|
||||
of the use of this Software in supporting documentation would be
|
||||
appreciated but is not required.
|
||||
|
||||
THE SOFTWARE IS PROVIDED 'AS IS'. USE ENTIRELY AT YOUR OWN RISK.
|
||||
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
|
||||
my_getopt (included for convenience - http://www.geocities.com/bsittler/)
|
||||
|
||||
Copyright 1997, 2000, 2001, 2002, 2006, Benjamin Sittler
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use, copy,
|
||||
modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
42
supportlibs/pegmarkdown/Makefile.orig
Normal file
42
supportlibs/pegmarkdown/Makefile.orig
Normal file
@ -0,0 +1,42 @@
|
||||
uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not')
|
||||
ifneq (,$(findstring MINGW,$(uname_S)))
|
||||
X = .exe
|
||||
endif
|
||||
|
||||
export X
|
||||
|
||||
PROGRAM=markdown$(X)
|
||||
CFLAGS ?= -Wall -O3 -ansi -D_GNU_SOURCE # -flto for newer GCC versions
|
||||
OBJS=markdown_parser.o markdown_output.o markdown_lib.o utility_functions.o parsing_functions.o odf.o
|
||||
PEGDIR=peg-0.1.9
|
||||
LEG=$(PEGDIR)/leg$(X)
|
||||
PKG_CONFIG = pkg-config
|
||||
|
||||
ALL : $(PROGRAM)
|
||||
|
||||
$(LEG): $(PEGDIR)
|
||||
CC=gcc make -C $(PEGDIR)
|
||||
|
||||
%.o : %.c markdown_peg.h
|
||||
$(CC) -c `$(PKG_CONFIG) --cflags glib-2.0` $(CFLAGS) -o $@ $<
|
||||
|
||||
$(PROGRAM) : markdown.c $(OBJS)
|
||||
$(CC) `$(PKG_CONFIG) --cflags glib-2.0` $(CFLAGS) -o $@ $< $(OBJS) `$(PKG_CONFIG) --libs glib-2.0`
|
||||
|
||||
markdown_parser.c : markdown_parser.leg $(LEG) markdown_peg.h parsing_functions.c utility_functions.c
|
||||
$(LEG) -o $@ $<
|
||||
|
||||
.PHONY: clean test
|
||||
|
||||
clean:
|
||||
rm -f markdown_parser.c $(PROGRAM) $(OBJS)
|
||||
|
||||
distclean: clean
|
||||
make -C $(PEGDIR) clean
|
||||
\
|
||||
test: $(PROGRAM)
|
||||
cd MarkdownTest_1.0.3; \
|
||||
./MarkdownTest.pl --script=../$(PROGRAM) --tidy
|
||||
|
||||
leak-check: $(PROGRAM)
|
||||
valgrind --leak-check=full ./markdown README
|
176
supportlibs/pegmarkdown/MarkdownTest_1.0.3/MarkdownTest.pl
Executable file
176
supportlibs/pegmarkdown/MarkdownTest_1.0.3/MarkdownTest.pl
Executable file
@ -0,0 +1,176 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
#
|
||||
# MarkdownTester -- Run tests for Markdown implementations
|
||||
#
|
||||
# Copyright (c) 2004-2005 John Gruber
|
||||
# <http://daringfireball.net/projects/markdown/>
|
||||
#
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Getopt::Long;
|
||||
use Benchmark;
|
||||
|
||||
our $VERSION = '1.0.2';
|
||||
# Sat 24 Dec 2005
|
||||
|
||||
my $time_start = new Benchmark;
|
||||
my $test_dir = "Tests";
|
||||
my $script = "./Markdown.pl";
|
||||
my $use_tidy = 0;
|
||||
my ($flag_version);
|
||||
|
||||
GetOptions (
|
||||
"script=s" => \$script,
|
||||
"testdir=s" => \$test_dir,
|
||||
"tidy" => \$use_tidy,
|
||||
"version" => \$flag_version,
|
||||
);
|
||||
|
||||
if($flag_version) {
|
||||
my $progname = $0;
|
||||
$progname =~ s{.*/}{};
|
||||
die "$progname version $VERSION\n";
|
||||
}
|
||||
|
||||
unless (-d $test_dir) { die "'$test_dir' is not a directory.\n"; }
|
||||
unless (-f $script) { die "$script does not exist.\n"; }
|
||||
unless (-x $script) { die "$script is not executable.\n"; }
|
||||
|
||||
my $tests_passed = 0;
|
||||
my $tests_failed = 0;
|
||||
|
||||
TEST:
|
||||
foreach my $testfile (glob "$test_dir/*.text") {
|
||||
my $testname = $testfile;
|
||||
$testname =~ s{.*/(.+)\.text$}{$1}i;
|
||||
print "$testname ... ";
|
||||
|
||||
# Look for a corresponding .html file for each .text file:
|
||||
my $resultfile = $testfile;
|
||||
$resultfile =~ s{\.text$}{\.html}i;
|
||||
unless (-f $resultfile) {
|
||||
print "'$resultfile' does not exist.\n\n";
|
||||
next TEST;
|
||||
}
|
||||
|
||||
# open(TEST, $testfile) || die("Can't open testfile: $!");
|
||||
open(RESULT, $resultfile) || die("Can't open resultfile: $!");
|
||||
undef $/;
|
||||
# my $t_input = <TEST>;
|
||||
my $t_result = <RESULT>;
|
||||
|
||||
my $t_output = `'$script' '$testfile'`;
|
||||
|
||||
# Normalize the output and expected result strings:
|
||||
$t_result =~ s/\s+\z//; # trim trailing whitespace
|
||||
$t_output =~ s/\s+\z//; # trim trailing whitespace
|
||||
if ($use_tidy) {
|
||||
# Escape the strings, pass them through to CLI tidy tool for tag-level equivalency
|
||||
$t_result =~ s{'}{'\\''}g; # escape ' chars for shell
|
||||
$t_output =~ s{'}{'\\''}g;
|
||||
$t_result = `echo '$t_result' | tidy --show-body-only 1 --quiet 1 --show-warnings 0`;
|
||||
$t_output = `echo '$t_output' | tidy --show-body-only 1 --quiet 1 --show-warnings 0`;
|
||||
}
|
||||
|
||||
if ($t_output eq $t_result) {
|
||||
print "OK\n";
|
||||
$tests_passed++;
|
||||
}
|
||||
else {
|
||||
print "FAILED\n\n";
|
||||
# This part added by JM to print diffs
|
||||
open(OUT, '>tmp1') or die $!;
|
||||
print OUT $t_output or die $!;
|
||||
open(RES, '>tmp2') or die $!;
|
||||
print RES $t_result or die $!;
|
||||
print `diff tmp1 tmp2`;
|
||||
close RES;
|
||||
close OUT;
|
||||
print "\n";
|
||||
`rm tmp?`;
|
||||
# End of added part
|
||||
$tests_failed++;
|
||||
}
|
||||
}
|
||||
|
||||
print "\n\n";
|
||||
print "$tests_passed passed; $tests_failed failed.\n";
|
||||
|
||||
my $time_end = new Benchmark;
|
||||
my $time_diff = timediff($time_end, $time_start);
|
||||
print "Benchmark: ", timestr($time_diff), "\n";
|
||||
|
||||
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
B<MarkdownTest>
|
||||
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
B<MarkdownTest.pl> [ B<--options> ] [ I<file> ... ]
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
|
||||
=head1 OPTIONS
|
||||
|
||||
Use "--" to end switch parsing. For example, to open a file named "-z", use:
|
||||
|
||||
MarkdownTest.pl -- -z
|
||||
|
||||
=over 4
|
||||
|
||||
=item B<--script>
|
||||
|
||||
Specify the path to the Markdown script to test. Defaults to
|
||||
"./Markdown.pl". Example:
|
||||
|
||||
./MarkdownTest.pl --script ./PHP-Markdown/php-markdown
|
||||
|
||||
=item B<--testdir>
|
||||
|
||||
Specify the path to a directory containing test data. Defaults to "Tests".
|
||||
|
||||
=item B<--tidy>
|
||||
|
||||
Flag to turn on using the command line 'tidy' tool to normalize HTML
|
||||
output before comparing script output to the expected test result.
|
||||
Assumes that the 'tidy' command is available in your PATH. Defaults to
|
||||
off.
|
||||
|
||||
=back
|
||||
|
||||
|
||||
|
||||
=head1 BUGS
|
||||
|
||||
|
||||
|
||||
=head1 VERSION HISTORY
|
||||
|
||||
1.0 Mon 13 Dec 2004-2005
|
||||
|
||||
1.0.1 Mon 19 Sep 2005
|
||||
|
||||
+ Better handling of case when foo.text exists, but foo.html doesn't.
|
||||
It now prints a message and moves on, rather than dying.
|
||||
|
||||
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
Copyright (c) 2004-2005 John Gruber
|
||||
<http://daringfireball.net/>
|
||||
All rights reserved.
|
||||
|
||||
This is free software; you may redistribute it and/or modify it under
|
||||
the same terms as Perl itself.
|
||||
|
||||
=cut
|
@ -0,0 +1,17 @@
|
||||
<p>AT&T has an ampersand in their name.</p>
|
||||
|
||||
<p>AT&T is another way to write it.</p>
|
||||
|
||||
<p>This & that.</p>
|
||||
|
||||
<p>4 < 5.</p>
|
||||
|
||||
<p>6 > 5.</p>
|
||||
|
||||
<p>Here's a <a href="http://example.com/?foo=1&bar=2">link</a> with an ampersand in the URL.</p>
|
||||
|
||||
<p>Here's a link with an amersand in the link text: <a href="http://att.com/" title="AT&T">AT&T</a>.</p>
|
||||
|
||||
<p>Here's an inline <a href="/script?foo=1&bar=2">link</a>.</p>
|
||||
|
||||
<p>Here's an inline <a href="/script?foo=1&bar=2">link</a>.</p>
|
@ -0,0 +1,21 @@
|
||||
AT&T has an ampersand in their name.
|
||||
|
||||
AT&T is another way to write it.
|
||||
|
||||
This & that.
|
||||
|
||||
4 < 5.
|
||||
|
||||
6 > 5.
|
||||
|
||||
Here's a [link] [1] with an ampersand in the URL.
|
||||
|
||||
Here's a link with an amersand in the link text: [AT&T] [2].
|
||||
|
||||
Here's an inline [link](/script?foo=1&bar=2).
|
||||
|
||||
Here's an inline [link](</script?foo=1&bar=2>).
|
||||
|
||||
|
||||
[1]: http://example.com/?foo=1&bar=2
|
||||
[2]: http://att.com/ "AT&T"
|
@ -0,0 +1,18 @@
|
||||
<p>Link: <a href="http://example.com/">http://example.com/</a>.</p>
|
||||
|
||||
<p>With an ampersand: <a href="http://example.com/?foo=1&bar=2">http://example.com/?foo=1&bar=2</a></p>
|
||||
|
||||
<ul>
|
||||
<li>In a list?</li>
|
||||
<li><a href="http://example.com/">http://example.com/</a></li>
|
||||
<li>It should.</li>
|
||||
</ul>
|
||||
|
||||
<blockquote>
|
||||
<p>Blockquoted: <a href="http://example.com/">http://example.com/</a></p>
|
||||
</blockquote>
|
||||
|
||||
<p>Auto-links should not occur here: <code><http://example.com/></code></p>
|
||||
|
||||
<pre><code>or here: <http://example.com/>
|
||||
</code></pre>
|
@ -0,0 +1,13 @@
|
||||
Link: <http://example.com/>.
|
||||
|
||||
With an ampersand: <http://example.com/?foo=1&bar=2>
|
||||
|
||||
* In a list?
|
||||
* <http://example.com/>
|
||||
* It should.
|
||||
|
||||
> Blockquoted: <http://example.com/>
|
||||
|
||||
Auto-links should not occur here: `<http://example.com/>`
|
||||
|
||||
or here: <http://example.com/>
|
@ -0,0 +1,118 @@
|
||||
<p>These should all get escaped:</p>
|
||||
|
||||
<p>Backslash: \</p>
|
||||
|
||||
<p>Backtick: `</p>
|
||||
|
||||
<p>Asterisk: *</p>
|
||||
|
||||
<p>Underscore: _</p>
|
||||
|
||||
<p>Left brace: {</p>
|
||||
|
||||
<p>Right brace: }</p>
|
||||
|
||||
<p>Left bracket: [</p>
|
||||
|
||||
<p>Right bracket: ]</p>
|
||||
|
||||
<p>Left paren: (</p>
|
||||
|
||||
<p>Right paren: )</p>
|
||||
|
||||
<p>Greater-than: ></p>
|
||||
|
||||
<p>Hash: #</p>
|
||||
|
||||
<p>Period: .</p>
|
||||
|
||||
<p>Bang: !</p>
|
||||
|
||||
<p>Plus: +</p>
|
||||
|
||||
<p>Minus: -</p>
|
||||
|
||||
<p>These should not, because they occur within a code block:</p>
|
||||
|
||||
<pre><code>Backslash: \\
|
||||
|
||||
Backtick: \`
|
||||
|
||||
Asterisk: \*
|
||||
|
||||
Underscore: \_
|
||||
|
||||
Left brace: \{
|
||||
|
||||
Right brace: \}
|
||||
|
||||
Left bracket: \[
|
||||
|
||||
Right bracket: \]
|
||||
|
||||
Left paren: \(
|
||||
|
||||
Right paren: \)
|
||||
|
||||
Greater-than: \>
|
||||
|
||||
Hash: \#
|
||||
|
||||
Period: \.
|
||||
|
||||
Bang: \!
|
||||
|
||||
Plus: \+
|
||||
|
||||
Minus: \-
|
||||
</code></pre>
|
||||
|
||||
<p>Nor should these, which occur in code spans:</p>
|
||||
|
||||
<p>Backslash: <code>\\</code></p>
|
||||
|
||||
<p>Backtick: <code>\`</code></p>
|
||||
|
||||
<p>Asterisk: <code>\*</code></p>
|
||||
|
||||
<p>Underscore: <code>\_</code></p>
|
||||
|
||||
<p>Left brace: <code>\{</code></p>
|
||||
|
||||
<p>Right brace: <code>\}</code></p>
|
||||
|
||||
<p>Left bracket: <code>\[</code></p>
|
||||
|
||||
<p>Right bracket: <code>\]</code></p>
|
||||
|
||||
<p>Left paren: <code>\(</code></p>
|
||||
|
||||
<p>Right paren: <code>\)</code></p>
|
||||
|
||||
<p>Greater-than: <code>\></code></p>
|
||||
|
||||
<p>Hash: <code>\#</code></p>
|
||||
|
||||
<p>Period: <code>\.</code></p>
|
||||
|
||||
<p>Bang: <code>\!</code></p>
|
||||
|
||||
<p>Plus: <code>\+</code></p>
|
||||
|
||||
<p>Minus: <code>\-</code></p>
|
||||
|
||||
|
||||
<p>These should get escaped, even though they're matching pairs for
|
||||
other Markdown constructs:</p>
|
||||
|
||||
<p>*asterisks*</p>
|
||||
|
||||
<p>_underscores_</p>
|
||||
|
||||
<p>`backticks`</p>
|
||||
|
||||
<p>This is a code span with a literal backslash-backtick sequence: <code>\`</code></p>
|
||||
|
||||
<p>This is a tag with unescaped backticks <span attr='`ticks`'>bar</span>.</p>
|
||||
|
||||
<p>This is a tag with backslashes <span attr='\\backslashes\\'>bar</span>.</p>
|
@ -0,0 +1,120 @@
|
||||
These should all get escaped:
|
||||
|
||||
Backslash: \\
|
||||
|
||||
Backtick: \`
|
||||
|
||||
Asterisk: \*
|
||||
|
||||
Underscore: \_
|
||||
|
||||
Left brace: \{
|
||||
|
||||
Right brace: \}
|
||||
|
||||
Left bracket: \[
|
||||
|
||||
Right bracket: \]
|
||||
|
||||
Left paren: \(
|
||||
|
||||
Right paren: \)
|
||||
|
||||
Greater-than: \>
|
||||
|
||||
Hash: \#
|
||||
|
||||
Period: \.
|
||||
|
||||
Bang: \!
|
||||
|
||||
Plus: \+
|
||||
|
||||
Minus: \-
|
||||
|
||||
|
||||
|
||||
These should not, because they occur within a code block:
|
||||
|
||||
Backslash: \\
|
||||
|
||||
Backtick: \`
|
||||
|
||||
Asterisk: \*
|
||||
|
||||
Underscore: \_
|
||||
|
||||
Left brace: \{
|
||||
|
||||
Right brace: \}
|
||||
|
||||
Left bracket: \[
|
||||
|
||||
Right bracket: \]
|
||||
|
||||
Left paren: \(
|
||||
|
||||
Right paren: \)
|
||||
|
||||
Greater-than: \>
|
||||
|
||||
Hash: \#
|
||||
|
||||
Period: \.
|
||||
|
||||
Bang: \!
|
||||
|
||||
Plus: \+
|
||||
|
||||
Minus: \-
|
||||
|
||||
|
||||
Nor should these, which occur in code spans:
|
||||
|
||||
Backslash: `\\`
|
||||
|
||||
Backtick: `` \` ``
|
||||
|
||||
Asterisk: `\*`
|
||||
|
||||
Underscore: `\_`
|
||||
|
||||
Left brace: `\{`
|
||||
|
||||
Right brace: `\}`
|
||||
|
||||
Left bracket: `\[`
|
||||
|
||||
Right bracket: `\]`
|
||||
|
||||
Left paren: `\(`
|
||||
|
||||
Right paren: `\)`
|
||||
|
||||
Greater-than: `\>`
|
||||
|
||||
Hash: `\#`
|
||||
|
||||
Period: `\.`
|
||||
|
||||
Bang: `\!`
|
||||
|
||||
Plus: `\+`
|
||||
|
||||
Minus: `\-`
|
||||
|
||||
|
||||
These should get escaped, even though they're matching pairs for
|
||||
other Markdown constructs:
|
||||
|
||||
\*asterisks\*
|
||||
|
||||
\_underscores\_
|
||||
|
||||
\`backticks\`
|
||||
|
||||
This is a code span with a literal backslash-backtick sequence: `` \` ``
|
||||
|
||||
This is a tag with unescaped backticks <span attr='`ticks`'>bar</span>.
|
||||
|
||||
This is a tag with backslashes <span attr='\\backslashes\\'>bar</span>.
|
@ -0,0 +1,15 @@
|
||||
<blockquote>
|
||||
<p>Example:</p>
|
||||
|
||||
<pre><code>sub status {
|
||||
print "working";
|
||||
}
|
||||
</code></pre>
|
||||
|
||||
<p>Or:</p>
|
||||
|
||||
<pre><code>sub status {
|
||||
return "working";
|
||||
}
|
||||
</code></pre>
|
||||
</blockquote>
|
@ -0,0 +1,11 @@
|
||||
> Example:
|
||||
>
|
||||
> sub status {
|
||||
> print "working";
|
||||
> }
|
||||
>
|
||||
> Or:
|
||||
>
|
||||
> sub status {
|
||||
> return "working";
|
||||
> }
|
@ -0,0 +1,18 @@
|
||||
<pre><code>code block on the first line
|
||||
</code></pre>
|
||||
|
||||
<p>Regular text.</p>
|
||||
|
||||
<pre><code>code block indented by spaces
|
||||
</code></pre>
|
||||
|
||||
<p>Regular text.</p>
|
||||
|
||||
<pre><code>the lines in this block
|
||||
all contain trailing spaces
|
||||
</code></pre>
|
||||
|
||||
<p>Regular Text.</p>
|
||||
|
||||
<pre><code>code block on the last line
|
||||
</code></pre>
|
@ -0,0 +1,14 @@
|
||||
code block on the first line
|
||||
|
||||
Regular text.
|
||||
|
||||
code block indented by spaces
|
||||
|
||||
Regular text.
|
||||
|
||||
the lines in this block
|
||||
all contain trailing spaces
|
||||
|
||||
Regular Text.
|
||||
|
||||
code block on the last line
|
@ -0,0 +1,6 @@
|
||||
<p><code><test a="</code> content of attribute <code>"></code></p>
|
||||
|
||||
<p>Fix for backticks within HTML tag: <span attr='`ticks`'>like this</span></p>
|
||||
|
||||
<p>Here's how you put <code>`backticks`</code> in a code span.</p>
|
||||
|
@ -0,0 +1,6 @@
|
||||
`<test a="` content of attribute `">`
|
||||
|
||||
Fix for backticks within HTML tag: <span attr='`ticks`'>like this</span>
|
||||
|
||||
Here's how you put `` `backticks` `` in a code span.
|
||||
|
8
supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Hard-wrapped paragraphs with list-like lines.html
Normal file
8
supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Hard-wrapped paragraphs with list-like lines.html
Normal file
@ -0,0 +1,8 @@
|
||||
<p>In Markdown 1.0.0 and earlier. Version
|
||||
8. This line turns into a list item.
|
||||
Because a hard-wrapped line in the
|
||||
middle of a paragraph looked like a
|
||||
list item.</p>
|
||||
|
||||
<p>Here's one with a bullet.
|
||||
* criminey.</p>
|
8
supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Hard-wrapped paragraphs with list-like lines.text
Normal file
8
supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Hard-wrapped paragraphs with list-like lines.text
Normal file
@ -0,0 +1,8 @@
|
||||
In Markdown 1.0.0 and earlier. Version
|
||||
8. This line turns into a list item.
|
||||
Because a hard-wrapped line in the
|
||||
middle of a paragraph looked like a
|
||||
list item.
|
||||
|
||||
Here's one with a bullet.
|
||||
* criminey.
|
@ -0,0 +1,71 @@
|
||||
<p>Dashes:</p>
|
||||
|
||||
<hr />
|
||||
|
||||
<hr />
|
||||
|
||||
<hr />
|
||||
|
||||
<hr />
|
||||
|
||||
<pre><code>---
|
||||
</code></pre>
|
||||
|
||||
<hr />
|
||||
|
||||
<hr />
|
||||
|
||||
<hr />
|
||||
|
||||
<hr />
|
||||
|
||||
<pre><code>- - -
|
||||
</code></pre>
|
||||
|
||||
<p>Asterisks:</p>
|
||||
|
||||
<hr />
|
||||
|
||||
<hr />
|
||||
|
||||
<hr />
|
||||
|
||||
<hr />
|
||||
|
||||
<pre><code>***
|
||||
</code></pre>
|
||||
|
||||
<hr />
|
||||
|
||||
<hr />
|
||||
|
||||
<hr />
|
||||
|
||||
<hr />
|
||||
|
||||
<pre><code>* * *
|
||||
</code></pre>
|
||||
|
||||
<p>Underscores:</p>
|
||||
|
||||
<hr />
|
||||
|
||||
<hr />
|
||||
|
||||
<hr />
|
||||
|
||||
<hr />
|
||||
|
||||
<pre><code>___
|
||||
</code></pre>
|
||||
|
||||
<hr />
|
||||
|
||||
<hr />
|
||||
|
||||
<hr />
|
||||
|
||||
<hr />
|
||||
|
||||
<pre><code>_ _ _
|
||||
</code></pre>
|
@ -0,0 +1,67 @@
|
||||
Dashes:
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
- - -
|
||||
|
||||
- - -
|
||||
|
||||
- - -
|
||||
|
||||
- - -
|
||||
|
||||
- - -
|
||||
|
||||
|
||||
Asterisks:
|
||||
|
||||
***
|
||||
|
||||
***
|
||||
|
||||
***
|
||||
|
||||
***
|
||||
|
||||
***
|
||||
|
||||
* * *
|
||||
|
||||
* * *
|
||||
|
||||
* * *
|
||||
|
||||
* * *
|
||||
|
||||
* * *
|
||||
|
||||
|
||||
Underscores:
|
||||
|
||||
___
|
||||
|
||||
___
|
||||
|
||||
___
|
||||
|
||||
___
|
||||
|
||||
___
|
||||
|
||||
_ _ _
|
||||
|
||||
_ _ _
|
||||
|
||||
_ _ _
|
||||
|
||||
_ _ _
|
||||
|
||||
_ _ _
|
@ -0,0 +1,15 @@
|
||||
<p>Simple block on one line:</p>
|
||||
|
||||
<div>foo</div>
|
||||
|
||||
<p>And nested without indentation:</p>
|
||||
|
||||
<div>
|
||||
<div>
|
||||
<div>
|
||||
foo
|
||||
</div>
|
||||
<div style=">"/>
|
||||
</div>
|
||||
<div>bar</div>
|
||||
</div>
|
@ -0,0 +1,15 @@
|
||||
Simple block on one line:
|
||||
|
||||
<div>foo</div>
|
||||
|
||||
And nested without indentation:
|
||||
|
||||
<div>
|
||||
<div>
|
||||
<div>
|
||||
foo
|
||||
</div>
|
||||
<div style=">"/>
|
||||
</div>
|
||||
<div>bar</div>
|
||||
</div>
|
@ -0,0 +1,72 @@
|
||||
<p>Here's a simple block:</p>
|
||||
|
||||
<div>
|
||||
foo
|
||||
</div>
|
||||
|
||||
<p>This should be a code block, though:</p>
|
||||
|
||||
<pre><code><div>
|
||||
foo
|
||||
</div>
|
||||
</code></pre>
|
||||
|
||||
<p>As should this:</p>
|
||||
|
||||
<pre><code><div>foo</div>
|
||||
</code></pre>
|
||||
|
||||
<p>Now, nested:</p>
|
||||
|
||||
<div>
|
||||
<div>
|
||||
<div>
|
||||
foo
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p>This should just be an HTML comment:</p>
|
||||
|
||||
<!-- Comment -->
|
||||
|
||||
<p>Multiline:</p>
|
||||
|
||||
<!--
|
||||
Blah
|
||||
Blah
|
||||
-->
|
||||
|
||||
<p>Code block:</p>
|
||||
|
||||
<pre><code><!-- Comment -->
|
||||
</code></pre>
|
||||
|
||||
<p>Just plain comment, with trailing spaces on the line:</p>
|
||||
|
||||
<!-- foo -->
|
||||
|
||||
<p>Code:</p>
|
||||
|
||||
<pre><code><hr />
|
||||
</code></pre>
|
||||
|
||||
<p>Hr's:</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<hr/>
|
||||
|
||||
<hr />
|
||||
|
||||
<hr>
|
||||
|
||||
<hr/>
|
||||
|
||||
<hr />
|
||||
|
||||
<hr class="foo" id="bar" />
|
||||
|
||||
<hr class="foo" id="bar"/>
|
||||
|
||||
<hr class="foo" id="bar" >
|
@ -0,0 +1,69 @@
|
||||
Here's a simple block:
|
||||
|
||||
<div>
|
||||
foo
|
||||
</div>
|
||||
|
||||
This should be a code block, though:
|
||||
|
||||
<div>
|
||||
foo
|
||||
</div>
|
||||
|
||||
As should this:
|
||||
|
||||
<div>foo</div>
|
||||
|
||||
Now, nested:
|
||||
|
||||
<div>
|
||||
<div>
|
||||
<div>
|
||||
foo
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
This should just be an HTML comment:
|
||||
|
||||
<!-- Comment -->
|
||||
|
||||
Multiline:
|
||||
|
||||
<!--
|
||||
Blah
|
||||
Blah
|
||||
-->
|
||||
|
||||
Code block:
|
||||
|
||||
<!-- Comment -->
|
||||
|
||||
Just plain comment, with trailing spaces on the line:
|
||||
|
||||
<!-- foo -->
|
||||
|
||||
Code:
|
||||
|
||||
<hr />
|
||||
|
||||
Hr's:
|
||||
|
||||
<hr>
|
||||
|
||||
<hr/>
|
||||
|
||||
<hr />
|
||||
|
||||
<hr>
|
||||
|
||||
<hr/>
|
||||
|
||||
<hr />
|
||||
|
||||
<hr class="foo" id="bar" />
|
||||
|
||||
<hr class="foo" id="bar"/>
|
||||
|
||||
<hr class="foo" id="bar" >
|
||||
|
@ -0,0 +1,13 @@
|
||||
<p>Paragraph one.</p>
|
||||
|
||||
<!-- This is a simple comment -->
|
||||
|
||||
<!--
|
||||
This is another comment.
|
||||
-->
|
||||
|
||||
<p>Paragraph two.</p>
|
||||
|
||||
<!-- one comment block -- -- with two comments -->
|
||||
|
||||
<p>The end.</p>
|
@ -0,0 +1,13 @@
|
||||
Paragraph one.
|
||||
|
||||
<!-- This is a simple comment -->
|
||||
|
||||
<!--
|
||||
This is another comment.
|
||||
-->
|
||||
|
||||
Paragraph two.
|
||||
|
||||
<!-- one comment block -- -- with two comments -->
|
||||
|
||||
The end.
|
@ -0,0 +1,11 @@
|
||||
<p>Just a <a href="/url/">URL</a>.</p>
|
||||
|
||||
<p><a href="/url/" title="title">URL and title</a>.</p>
|
||||
|
||||
<p><a href="/url/" title="title preceded by two spaces">URL and title</a>.</p>
|
||||
|
||||
<p><a href="/url/" title="title preceded by a tab">URL and title</a>.</p>
|
||||
|
||||
<p><a href="/url/" title="title has spaces afterward">URL and title</a>.</p>
|
||||
|
||||
<p><a href="">Empty</a>.</p>
|
@ -0,0 +1,12 @@
|
||||
Just a [URL](/url/).
|
||||
|
||||
[URL and title](/url/ "title").
|
||||
|
||||
[URL and title](/url/ "title preceded by two spaces").
|
||||
|
||||
[URL and title](/url/ "title preceded by a tab").
|
||||
|
||||
[URL and title](/url/ "title has spaces afterward" ).
|
||||
|
||||
|
||||
[Empty]().
|
@ -0,0 +1,52 @@
|
||||
<p>Foo <a href="/url/" title="Title">bar</a>.</p>
|
||||
|
||||
<p>Foo <a href="/url/" title="Title">bar</a>.</p>
|
||||
|
||||
<p>Foo <a href="/url/" title="Title">bar</a>.</p>
|
||||
|
||||
<p>With <a href="/url/">embedded [brackets]</a>.</p>
|
||||
|
||||
<p>Indented <a href="/url">once</a>.</p>
|
||||
|
||||
<p>Indented <a href="/url">twice</a>.</p>
|
||||
|
||||
<p>Indented <a href="/url">thrice</a>.</p>
|
||||
|
||||
<p>Indented [four][] times.</p>
|
||||
|
||||
<pre><code>[four]: /url
|
||||
</code></pre>
|
||||
|
||||
<hr />
|
||||
|
||||
<p><a href="foo">this</a> should work</p>
|
||||
|
||||
<p>So should <a href="foo">this</a>.</p>
|
||||
|
||||
<p>And <a href="foo">this</a>.</p>
|
||||
|
||||
<p>And <a href="foo">this</a>.</p>
|
||||
|
||||
<p>And <a href="foo">this</a>.</p>
|
||||
|
||||
<p>But not [that] [].</p>
|
||||
|
||||
<p>Nor [that][].</p>
|
||||
|
||||
<p>Nor [that].</p>
|
||||
|
||||
<p>[Something in brackets like <a href="foo">this</a> should work]</p>
|
||||
|
||||
<p>[Same with <a href="foo">this</a>.]</p>
|
||||
|
||||
<p>In this case, <a href="/somethingelse/">this</a> points to something else.</p>
|
||||
|
||||
<p>Backslashing should suppress [this] and [this].</p>
|
||||
|
||||
<hr />
|
||||
|
||||
<p>Here's one where the <a href="/url/">link
|
||||
breaks</a> across lines.</p>
|
||||
|
||||
<p>Here's another where the <a href="/url/">link
|
||||
breaks</a> across lines, but with a line-ending space.</p>
|
@ -0,0 +1,71 @@
|
||||
Foo [bar] [1].
|
||||
|
||||
Foo [bar][1].
|
||||
|
||||
Foo [bar]
|
||||
[1].
|
||||
|
||||
[1]: /url/ "Title"
|
||||
|
||||
|
||||
With [embedded [brackets]] [b].
|
||||
|
||||
|
||||
Indented [once][].
|
||||
|
||||
Indented [twice][].
|
||||
|
||||
Indented [thrice][].
|
||||
|
||||
Indented [four][] times.
|
||||
|
||||
[once]: /url
|
||||
|
||||
[twice]: /url
|
||||
|
||||
[thrice]: /url
|
||||
|
||||
[four]: /url
|
||||
|
||||
|
||||
[b]: /url/
|
||||
|
||||
* * *
|
||||
|
||||
[this] [this] should work
|
||||
|
||||
So should [this][this].
|
||||
|
||||
And [this] [].
|
||||
|
||||
And [this][].
|
||||
|
||||
And [this].
|
||||
|
||||
But not [that] [].
|
||||
|
||||
Nor [that][].
|
||||
|
||||
Nor [that].
|
||||
|
||||
[Something in brackets like [this][] should work]
|
||||
|
||||
[Same with [this].]
|
||||
|
||||
In this case, [this](/somethingelse/) points to something else.
|
||||
|
||||
Backslashing should suppress \[this] and [this\].
|
||||
|
||||
[this]: foo
|
||||
|
||||
|
||||
* * *
|
||||
|
||||
Here's one where the [link
|
||||
breaks] across lines.
|
||||
|
||||
Here's another where the [link
|
||||
breaks] across lines, but with a line-ending space.
|
||||
|
||||
|
||||
[link breaks]: /url/
|
@ -0,0 +1,9 @@
|
||||
<p>This is the <a href="/simple">simple case</a>.</p>
|
||||
|
||||
<p>This one has a <a href="/foo">line
|
||||
break</a>.</p>
|
||||
|
||||
<p>This one has a <a href="/foo">line
|
||||
break</a> with a line-ending space.</p>
|
||||
|
||||
<p><a href="/that">this</a> and the <a href="/other">other</a></p>
|
@ -0,0 +1,20 @@
|
||||
This is the [simple case].
|
||||
|
||||
[simple case]: /simple
|
||||
|
||||
|
||||
|
||||
This one has a [line
|
||||
break].
|
||||
|
||||
This one has a [line
|
||||
break] with a line-ending space.
|
||||
|
||||
[line break]: /foo
|
||||
|
||||
|
||||
[this] [that] and the [other]
|
||||
|
||||
[this]: /this
|
||||
[that]: /that
|
||||
[other]: /other
|
@ -0,0 +1,3 @@
|
||||
<p>Foo <a href="/url/" title="Title with "quotes" inside">bar</a>.</p>
|
||||
|
||||
<p>Foo <a href="/url/" title="Title with "quotes" inside">bar</a>.</p>
|
@ -0,0 +1,7 @@
|
||||
Foo [bar][].
|
||||
|
||||
Foo [bar](/url/ "Title with "quotes" inside").
|
||||
|
||||
|
||||
[bar]: /url/ "Title with "quotes" inside"
|
||||
|
314
supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Markdown Documentation - Basics.html
Normal file
314
supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Markdown Documentation - Basics.html
Normal file
@ -0,0 +1,314 @@
|
||||
<h1>Markdown: Basics</h1>
|
||||
|
||||
<ul id="ProjectSubmenu">
|
||||
<li><a href="/projects/markdown/" title="Markdown Project Page">Main</a></li>
|
||||
<li><a class="selected" title="Markdown Basics">Basics</a></li>
|
||||
<li><a href="/projects/markdown/syntax" title="Markdown Syntax Documentation">Syntax</a></li>
|
||||
<li><a href="/projects/markdown/license" title="Pricing and License Information">License</a></li>
|
||||
<li><a href="/projects/markdown/dingus" title="Online Markdown Web Form">Dingus</a></li>
|
||||
</ul>
|
||||
|
||||
<h2>Getting the Gist of Markdown's Formatting Syntax</h2>
|
||||
|
||||
<p>This page offers a brief overview of what it's like to use Markdown.
|
||||
The <a href="/projects/markdown/syntax" title="Markdown Syntax">syntax page</a> provides complete, detailed documentation for
|
||||
every feature, but Markdown should be very easy to pick up simply by
|
||||
looking at a few examples of it in action. The examples on this page
|
||||
are written in a before/after style, showing example syntax and the
|
||||
HTML output produced by Markdown.</p>
|
||||
|
||||
<p>It's also helpful to simply try Markdown out; the <a href="/projects/markdown/dingus" title="Markdown Dingus">Dingus</a> is a
|
||||
web application that allows you type your own Markdown-formatted text
|
||||
and translate it to XHTML.</p>
|
||||
|
||||
<p><strong>Note:</strong> This document is itself written using Markdown; you
|
||||
can <a href="/projects/markdown/basics.text">see the source for it by adding '.text' to the URL</a>.</p>
|
||||
|
||||
<h2>Paragraphs, Headers, Blockquotes</h2>
|
||||
|
||||
<p>A paragraph is simply one or more consecutive lines of text, separated
|
||||
by one or more blank lines. (A blank line is any line that looks like a
|
||||
blank line -- a line containing nothing spaces or tabs is considered
|
||||
blank.) Normal paragraphs should not be intended with spaces or tabs.</p>
|
||||
|
||||
<p>Markdown offers two styles of headers: <em>Setext</em> and <em>atx</em>.
|
||||
Setext-style headers for <code><h1></code> and <code><h2></code> are created by
|
||||
"underlining" with equal signs (<code>=</code>) and hyphens (<code>-</code>), respectively.
|
||||
To create an atx-style header, you put 1-6 hash marks (<code>#</code>) at the
|
||||
beginning of the line -- the number of hashes equals the resulting
|
||||
HTML header level.</p>
|
||||
|
||||
<p>Blockquotes are indicated using email-style '<code>></code>' angle brackets.</p>
|
||||
|
||||
<p>Markdown:</p>
|
||||
|
||||
<pre><code>A First Level Header
|
||||
====================
|
||||
|
||||
A Second Level Header
|
||||
---------------------
|
||||
|
||||
Now is the time for all good men to come to
|
||||
the aid of their country. This is just a
|
||||
regular paragraph.
|
||||
|
||||
The quick brown fox jumped over the lazy
|
||||
dog's back.
|
||||
|
||||
### Header 3
|
||||
|
||||
> This is a blockquote.
|
||||
>
|
||||
> This is the second paragraph in the blockquote.
|
||||
>
|
||||
> ## This is an H2 in a blockquote
|
||||
</code></pre>
|
||||
|
||||
<p>Output:</p>
|
||||
|
||||
<pre><code><h1>A First Level Header</h1>
|
||||
|
||||
<h2>A Second Level Header</h2>
|
||||
|
||||
<p>Now is the time for all good men to come to
|
||||
the aid of their country. This is just a
|
||||
regular paragraph.</p>
|
||||
|
||||
<p>The quick brown fox jumped over the lazy
|
||||
dog's back.</p>
|
||||
|
||||
<h3>Header 3</h3>
|
||||
|
||||
<blockquote>
|
||||
<p>This is a blockquote.</p>
|
||||
|
||||
<p>This is the second paragraph in the blockquote.</p>
|
||||
|
||||
<h2>This is an H2 in a blockquote</h2>
|
||||
</blockquote>
|
||||
</code></pre>
|
||||
|
||||
<h3>Phrase Emphasis</h3>
|
||||
|
||||
<p>Markdown uses asterisks and underscores to indicate spans of emphasis.</p>
|
||||
|
||||
<p>Markdown:</p>
|
||||
|
||||
<pre><code>Some of these words *are emphasized*.
|
||||
Some of these words _are emphasized also_.
|
||||
|
||||
Use two asterisks for **strong emphasis**.
|
||||
Or, if you prefer, __use two underscores instead__.
|
||||
</code></pre>
|
||||
|
||||
<p>Output:</p>
|
||||
|
||||
<pre><code><p>Some of these words <em>are emphasized</em>.
|
||||
Some of these words <em>are emphasized also</em>.</p>
|
||||
|
||||
<p>Use two asterisks for <strong>strong emphasis</strong>.
|
||||
Or, if you prefer, <strong>use two underscores instead</strong>.</p>
|
||||
</code></pre>
|
||||
|
||||
<h2>Lists</h2>
|
||||
|
||||
<p>Unordered (bulleted) lists use asterisks, pluses, and hyphens (<code>*</code>,
|
||||
<code>+</code>, and <code>-</code>) as list markers. These three markers are
|
||||
interchangable; this:</p>
|
||||
|
||||
<pre><code>* Candy.
|
||||
* Gum.
|
||||
* Booze.
|
||||
</code></pre>
|
||||
|
||||
<p>this:</p>
|
||||
|
||||
<pre><code>+ Candy.
|
||||
+ Gum.
|
||||
+ Booze.
|
||||
</code></pre>
|
||||
|
||||
<p>and this:</p>
|
||||
|
||||
<pre><code>- Candy.
|
||||
- Gum.
|
||||
- Booze.
|
||||
</code></pre>
|
||||
|
||||
<p>all produce the same output:</p>
|
||||
|
||||
<pre><code><ul>
|
||||
<li>Candy.</li>
|
||||
<li>Gum.</li>
|
||||
<li>Booze.</li>
|
||||
</ul>
|
||||
</code></pre>
|
||||
|
||||
<p>Ordered (numbered) lists use regular numbers, followed by periods, as
|
||||
list markers:</p>
|
||||
|
||||
<pre><code>1. Red
|
||||
2. Green
|
||||
3. Blue
|
||||
</code></pre>
|
||||
|
||||
<p>Output:</p>
|
||||
|
||||
<pre><code><ol>
|
||||
<li>Red</li>
|
||||
<li>Green</li>
|
||||
<li>Blue</li>
|
||||
</ol>
|
||||
</code></pre>
|
||||
|
||||
<p>If you put blank lines between items, you'll get <code><p></code> tags for the
|
||||
list item text. You can create multi-paragraph list items by indenting
|
||||
the paragraphs by 4 spaces or 1 tab:</p>
|
||||
|
||||
<pre><code>* A list item.
|
||||
|
||||
With multiple paragraphs.
|
||||
|
||||
* Another item in the list.
|
||||
</code></pre>
|
||||
|
||||
<p>Output:</p>
|
||||
|
||||
<pre><code><ul>
|
||||
<li><p>A list item.</p>
|
||||
<p>With multiple paragraphs.</p></li>
|
||||
<li><p>Another item in the list.</p></li>
|
||||
</ul>
|
||||
</code></pre>
|
||||
|
||||
<h3>Links</h3>
|
||||
|
||||
<p>Markdown supports two styles for creating links: <em>inline</em> and
|
||||
<em>reference</em>. With both styles, you use square brackets to delimit the
|
||||
text you want to turn into a link.</p>
|
||||
|
||||
<p>Inline-style links use parentheses immediately after the link text.
|
||||
For example:</p>
|
||||
|
||||
<pre><code>This is an [example link](http://example.com/).
|
||||
</code></pre>
|
||||
|
||||
<p>Output:</p>
|
||||
|
||||
<pre><code><p>This is an <a href="http://example.com/">
|
||||
example link</a>.</p>
|
||||
</code></pre>
|
||||
|
||||
<p>Optionally, you may include a title attribute in the parentheses:</p>
|
||||
|
||||
<pre><code>This is an [example link](http://example.com/ "With a Title").
|
||||
</code></pre>
|
||||
|
||||
<p>Output:</p>
|
||||
|
||||
<pre><code><p>This is an <a href="http://example.com/" title="With a Title">
|
||||
example link</a>.</p>
|
||||
</code></pre>
|
||||
|
||||
<p>Reference-style links allow you to refer to your links by names, which
|
||||
you define elsewhere in your document:</p>
|
||||
|
||||
<pre><code>I get 10 times more traffic from [Google][1] than from
|
||||
[Yahoo][2] or [MSN][3].
|
||||
|
||||
[1]: http://google.com/ "Google"
|
||||
[2]: http://search.yahoo.com/ "Yahoo Search"
|
||||
[3]: http://search.msn.com/ "MSN Search"
|
||||
</code></pre>
|
||||
|
||||
<p>Output:</p>
|
||||
|
||||
<pre><code><p>I get 10 times more traffic from <a href="http://google.com/"
|
||||
title="Google">Google</a> than from <a href="http://search.yahoo.com/"
|
||||
title="Yahoo Search">Yahoo</a> or <a href="http://search.msn.com/"
|
||||
title="MSN Search">MSN</a>.</p>
|
||||
</code></pre>
|
||||
|
||||
<p>The title attribute is optional. Link names may contain letters,
|
||||
numbers and spaces, but are <em>not</em> case sensitive:</p>
|
||||
|
||||
<pre><code>I start my morning with a cup of coffee and
|
||||
[The New York Times][NY Times].
|
||||
|
||||
[ny times]: http://www.nytimes.com/
|
||||
</code></pre>
|
||||
|
||||
<p>Output:</p>
|
||||
|
||||
<pre><code><p>I start my morning with a cup of coffee and
|
||||
<a href="http://www.nytimes.com/">The New York Times</a>.</p>
|
||||
</code></pre>
|
||||
|
||||
<h3>Images</h3>
|
||||
|
||||
<p>Image syntax is very much like link syntax.</p>
|
||||
|
||||
<p>Inline (titles are optional):</p>
|
||||
|
||||
<pre><code>
|
||||
</code></pre>
|
||||
|
||||
<p>Reference-style:</p>
|
||||
|
||||
<pre><code>![alt text][id]
|
||||
|
||||
[id]: /path/to/img.jpg "Title"
|
||||
</code></pre>
|
||||
|
||||
<p>Both of the above examples produce the same output:</p>
|
||||
|
||||
<pre><code><img src="/path/to/img.jpg" alt="alt text" title="Title" />
|
||||
</code></pre>
|
||||
|
||||
<h3>Code</h3>
|
||||
|
||||
<p>In a regular paragraph, you can create code span by wrapping text in
|
||||
backtick quotes. Any ampersands (<code>&</code>) and angle brackets (<code><</code> or
|
||||
<code>></code>) will automatically be translated into HTML entities. This makes
|
||||
it easy to use Markdown to write about HTML example code:</p>
|
||||
|
||||
<pre><code>I strongly recommend against using any `<blink>` tags.
|
||||
|
||||
I wish SmartyPants used named entities like `&mdash;`
|
||||
instead of decimal-encoded entites like `&#8212;`.
|
||||
</code></pre>
|
||||
|
||||
<p>Output:</p>
|
||||
|
||||
<pre><code><p>I strongly recommend against using any
|
||||
<code>&lt;blink&gt;</code> tags.</p>
|
||||
|
||||
<p>I wish SmartyPants used named entities like
|
||||
<code>&amp;mdash;</code> instead of decimal-encoded
|
||||
entites like <code>&amp;#8212;</code>.</p>
|
||||
</code></pre>
|
||||
|
||||
<p>To specify an entire block of pre-formatted code, indent every line of
|
||||
the block by 4 spaces or 1 tab. Just like with code spans, <code>&</code>, <code><</code>,
|
||||
and <code>></code> characters will be escaped automatically.</p>
|
||||
|
||||
<p>Markdown:</p>
|
||||
|
||||
<pre><code>If you want your page to validate under XHTML 1.0 Strict,
|
||||
you've got to put paragraph tags in your blockquotes:
|
||||
|
||||
<blockquote>
|
||||
<p>For example.</p>
|
||||
</blockquote>
|
||||
</code></pre>
|
||||
|
||||
<p>Output:</p>
|
||||
|
||||
<pre><code><p>If you want your page to validate under XHTML 1.0 Strict,
|
||||
you've got to put paragraph tags in your blockquotes:</p>
|
||||
|
||||
<pre><code>&lt;blockquote&gt;
|
||||
&lt;p&gt;For example.&lt;/p&gt;
|
||||
&lt;/blockquote&gt;
|
||||
</code></pre>
|
||||
</code></pre>
|
306
supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Markdown Documentation - Basics.text
Normal file
306
supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Markdown Documentation - Basics.text
Normal file
@ -0,0 +1,306 @@
|
||||
Markdown: Basics
|
||||
================
|
||||
|
||||
<ul id="ProjectSubmenu">
|
||||
<li><a href="/projects/markdown/" title="Markdown Project Page">Main</a></li>
|
||||
<li><a class="selected" title="Markdown Basics">Basics</a></li>
|
||||
<li><a href="/projects/markdown/syntax" title="Markdown Syntax Documentation">Syntax</a></li>
|
||||
<li><a href="/projects/markdown/license" title="Pricing and License Information">License</a></li>
|
||||
<li><a href="/projects/markdown/dingus" title="Online Markdown Web Form">Dingus</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
Getting the Gist of Markdown's Formatting Syntax
|
||||
------------------------------------------------
|
||||
|
||||
This page offers a brief overview of what it's like to use Markdown.
|
||||
The [syntax page] [s] provides complete, detailed documentation for
|
||||
every feature, but Markdown should be very easy to pick up simply by
|
||||
looking at a few examples of it in action. The examples on this page
|
||||
are written in a before/after style, showing example syntax and the
|
||||
HTML output produced by Markdown.
|
||||
|
||||
It's also helpful to simply try Markdown out; the [Dingus] [d] is a
|
||||
web application that allows you type your own Markdown-formatted text
|
||||
and translate it to XHTML.
|
||||
|
||||
**Note:** This document is itself written using Markdown; you
|
||||
can [see the source for it by adding '.text' to the URL] [src].
|
||||
|
||||
[s]: /projects/markdown/syntax "Markdown Syntax"
|
||||
[d]: /projects/markdown/dingus "Markdown Dingus"
|
||||
[src]: /projects/markdown/basics.text
|
||||
|
||||
|
||||
## Paragraphs, Headers, Blockquotes ##
|
||||
|
||||
A paragraph is simply one or more consecutive lines of text, separated
|
||||
by one or more blank lines. (A blank line is any line that looks like a
|
||||
blank line -- a line containing nothing spaces or tabs is considered
|
||||
blank.) Normal paragraphs should not be intended with spaces or tabs.
|
||||
|
||||
Markdown offers two styles of headers: *Setext* and *atx*.
|
||||
Setext-style headers for `<h1>` and `<h2>` are created by
|
||||
"underlining" with equal signs (`=`) and hyphens (`-`), respectively.
|
||||
To create an atx-style header, you put 1-6 hash marks (`#`) at the
|
||||
beginning of the line -- the number of hashes equals the resulting
|
||||
HTML header level.
|
||||
|
||||
Blockquotes are indicated using email-style '`>`' angle brackets.
|
||||
|
||||
Markdown:
|
||||
|
||||
A First Level Header
|
||||
====================
|
||||
|
||||
A Second Level Header
|
||||
---------------------
|
||||
|
||||
Now is the time for all good men to come to
|
||||
the aid of their country. This is just a
|
||||
regular paragraph.
|
||||
|
||||
The quick brown fox jumped over the lazy
|
||||
dog's back.
|
||||
|
||||
### Header 3
|
||||
|
||||
> This is a blockquote.
|
||||
>
|
||||
> This is the second paragraph in the blockquote.
|
||||
>
|
||||
> ## This is an H2 in a blockquote
|
||||
|
||||
|
||||
Output:
|
||||
|
||||
<h1>A First Level Header</h1>
|
||||
|
||||
<h2>A Second Level Header</h2>
|
||||
|
||||
<p>Now is the time for all good men to come to
|
||||
the aid of their country. This is just a
|
||||
regular paragraph.</p>
|
||||
|
||||
<p>The quick brown fox jumped over the lazy
|
||||
dog's back.</p>
|
||||
|
||||
<h3>Header 3</h3>
|
||||
|
||||
<blockquote>
|
||||
<p>This is a blockquote.</p>
|
||||
|
||||
<p>This is the second paragraph in the blockquote.</p>
|
||||
|
||||
<h2>This is an H2 in a blockquote</h2>
|
||||
</blockquote>
|
||||
|
||||
|
||||
|
||||
### Phrase Emphasis ###
|
||||
|
||||
Markdown uses asterisks and underscores to indicate spans of emphasis.
|
||||
|
||||
Markdown:
|
||||
|
||||
Some of these words *are emphasized*.
|
||||
Some of these words _are emphasized also_.
|
||||
|
||||
Use two asterisks for **strong emphasis**.
|
||||
Or, if you prefer, __use two underscores instead__.
|
||||
|
||||
Output:
|
||||
|
||||
<p>Some of these words <em>are emphasized</em>.
|
||||
Some of these words <em>are emphasized also</em>.</p>
|
||||
|
||||
<p>Use two asterisks for <strong>strong emphasis</strong>.
|
||||
Or, if you prefer, <strong>use two underscores instead</strong>.</p>
|
||||
|
||||
|
||||
|
||||
## Lists ##
|
||||
|
||||
Unordered (bulleted) lists use asterisks, pluses, and hyphens (`*`,
|
||||
`+`, and `-`) as list markers. These three markers are
|
||||
interchangable; this:
|
||||
|
||||
* Candy.
|
||||
* Gum.
|
||||
* Booze.
|
||||
|
||||
this:
|
||||
|
||||
+ Candy.
|
||||
+ Gum.
|
||||
+ Booze.
|
||||
|
||||
and this:
|
||||
|
||||
- Candy.
|
||||
- Gum.
|
||||
- Booze.
|
||||
|
||||
all produce the same output:
|
||||
|
||||
<ul>
|
||||
<li>Candy.</li>
|
||||
<li>Gum.</li>
|
||||
<li>Booze.</li>
|
||||
</ul>
|
||||
|
||||
Ordered (numbered) lists use regular numbers, followed by periods, as
|
||||
list markers:
|
||||
|
||||
1. Red
|
||||
2. Green
|
||||
3. Blue
|
||||
|
||||
Output:
|
||||
|
||||
<ol>
|
||||
<li>Red</li>
|
||||
<li>Green</li>
|
||||
<li>Blue</li>
|
||||
</ol>
|
||||
|
||||
If you put blank lines between items, you'll get `<p>` tags for the
|
||||
list item text. You can create multi-paragraph list items by indenting
|
||||
the paragraphs by 4 spaces or 1 tab:
|
||||
|
||||
* A list item.
|
||||
|
||||
With multiple paragraphs.
|
||||
|
||||
* Another item in the list.
|
||||
|
||||
Output:
|
||||
|
||||
<ul>
|
||||
<li><p>A list item.</p>
|
||||
<p>With multiple paragraphs.</p></li>
|
||||
<li><p>Another item in the list.</p></li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
### Links ###
|
||||
|
||||
Markdown supports two styles for creating links: *inline* and
|
||||
*reference*. With both styles, you use square brackets to delimit the
|
||||
text you want to turn into a link.
|
||||
|
||||
Inline-style links use parentheses immediately after the link text.
|
||||
For example:
|
||||
|
||||
This is an [example link](http://example.com/).
|
||||
|
||||
Output:
|
||||
|
||||
<p>This is an <a href="http://example.com/">
|
||||
example link</a>.</p>
|
||||
|
||||
Optionally, you may include a title attribute in the parentheses:
|
||||
|
||||
This is an [example link](http://example.com/ "With a Title").
|
||||
|
||||
Output:
|
||||
|
||||
<p>This is an <a href="http://example.com/" title="With a Title">
|
||||
example link</a>.</p>
|
||||
|
||||
Reference-style links allow you to refer to your links by names, which
|
||||
you define elsewhere in your document:
|
||||
|
||||
I get 10 times more traffic from [Google][1] than from
|
||||
[Yahoo][2] or [MSN][3].
|
||||
|
||||
[1]: http://google.com/ "Google"
|
||||
[2]: http://search.yahoo.com/ "Yahoo Search"
|
||||
[3]: http://search.msn.com/ "MSN Search"
|
||||
|
||||
Output:
|
||||
|
||||
<p>I get 10 times more traffic from <a href="http://google.com/"
|
||||
title="Google">Google</a> than from <a href="http://search.yahoo.com/"
|
||||
title="Yahoo Search">Yahoo</a> or <a href="http://search.msn.com/"
|
||||
title="MSN Search">MSN</a>.</p>
|
||||
|
||||
The title attribute is optional. Link names may contain letters,
|
||||
numbers and spaces, but are *not* case sensitive:
|
||||
|
||||
I start my morning with a cup of coffee and
|
||||
[The New York Times][NY Times].
|
||||
|
||||
[ny times]: http://www.nytimes.com/
|
||||
|
||||
Output:
|
||||
|
||||
<p>I start my morning with a cup of coffee and
|
||||
<a href="http://www.nytimes.com/">The New York Times</a>.</p>
|
||||
|
||||
|
||||
### Images ###
|
||||
|
||||
Image syntax is very much like link syntax.
|
||||
|
||||
Inline (titles are optional):
|
||||
|
||||

|
||||
|
||||
Reference-style:
|
||||
|
||||
![alt text][id]
|
||||
|
||||
[id]: /path/to/img.jpg "Title"
|
||||
|
||||
Both of the above examples produce the same output:
|
||||
|
||||
<img src="/path/to/img.jpg" alt="alt text" title="Title" />
|
||||
|
||||
|
||||
|
||||
### Code ###
|
||||
|
||||
In a regular paragraph, you can create code span by wrapping text in
|
||||
backtick quotes. Any ampersands (`&`) and angle brackets (`<` or
|
||||
`>`) will automatically be translated into HTML entities. This makes
|
||||
it easy to use Markdown to write about HTML example code:
|
||||
|
||||
I strongly recommend against using any `<blink>` tags.
|
||||
|
||||
I wish SmartyPants used named entities like `—`
|
||||
instead of decimal-encoded entites like `—`.
|
||||
|
||||
Output:
|
||||
|
||||
<p>I strongly recommend against using any
|
||||
<code><blink></code> tags.</p>
|
||||
|
||||
<p>I wish SmartyPants used named entities like
|
||||
<code>&mdash;</code> instead of decimal-encoded
|
||||
entites like <code>&#8212;</code>.</p>
|
||||
|
||||
|
||||
To specify an entire block of pre-formatted code, indent every line of
|
||||
the block by 4 spaces or 1 tab. Just like with code spans, `&`, `<`,
|
||||
and `>` characters will be escaped automatically.
|
||||
|
||||
Markdown:
|
||||
|
||||
If you want your page to validate under XHTML 1.0 Strict,
|
||||
you've got to put paragraph tags in your blockquotes:
|
||||
|
||||
<blockquote>
|
||||
<p>For example.</p>
|
||||
</blockquote>
|
||||
|
||||
Output:
|
||||
|
||||
<p>If you want your page to validate under XHTML 1.0 Strict,
|
||||
you've got to put paragraph tags in your blockquotes:</p>
|
||||
|
||||
<pre><code><blockquote>
|
||||
<p>For example.</p>
|
||||
</blockquote>
|
||||
</code></pre>
|
942
supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Markdown Documentation - Syntax.html
Normal file
942
supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Markdown Documentation - Syntax.html
Normal file
@ -0,0 +1,942 @@
|
||||
<h1>Markdown: Syntax</h1>
|
||||
|
||||
<ul id="ProjectSubmenu">
|
||||
<li><a href="/projects/markdown/" title="Markdown Project Page">Main</a></li>
|
||||
<li><a href="/projects/markdown/basics" title="Markdown Basics">Basics</a></li>
|
||||
<li><a class="selected" title="Markdown Syntax Documentation">Syntax</a></li>
|
||||
<li><a href="/projects/markdown/license" title="Pricing and License Information">License</a></li>
|
||||
<li><a href="/projects/markdown/dingus" title="Online Markdown Web Form">Dingus</a></li>
|
||||
</ul>
|
||||
|
||||
<ul>
|
||||
<li><a href="#overview">Overview</a>
|
||||
<ul>
|
||||
<li><a href="#philosophy">Philosophy</a></li>
|
||||
<li><a href="#html">Inline HTML</a></li>
|
||||
<li><a href="#autoescape">Automatic Escaping for Special Characters</a></li>
|
||||
</ul></li>
|
||||
<li><a href="#block">Block Elements</a>
|
||||
<ul>
|
||||
<li><a href="#p">Paragraphs and Line Breaks</a></li>
|
||||
<li><a href="#header">Headers</a></li>
|
||||
<li><a href="#blockquote">Blockquotes</a></li>
|
||||
<li><a href="#list">Lists</a></li>
|
||||
<li><a href="#precode">Code Blocks</a></li>
|
||||
<li><a href="#hr">Horizontal Rules</a></li>
|
||||
</ul></li>
|
||||
<li><a href="#span">Span Elements</a>
|
||||
<ul>
|
||||
<li><a href="#link">Links</a></li>
|
||||
<li><a href="#em">Emphasis</a></li>
|
||||
<li><a href="#code">Code</a></li>
|
||||
<li><a href="#img">Images</a></li>
|
||||
</ul></li>
|
||||
<li><a href="#misc">Miscellaneous</a>
|
||||
<ul>
|
||||
<li><a href="#backslash">Backslash Escapes</a></li>
|
||||
<li><a href="#autolink">Automatic Links</a></li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
|
||||
<p><strong>Note:</strong> This document is itself written using Markdown; you
|
||||
can <a href="/projects/markdown/syntax.text">see the source for it by adding '.text' to the URL</a>.</p>
|
||||
|
||||
<hr />
|
||||
|
||||
<h2 id="overview">Overview</h2>
|
||||
|
||||
<h3 id="philosophy">Philosophy</h3>
|
||||
|
||||
<p>Markdown is intended to be as easy-to-read and easy-to-write as is feasible.</p>
|
||||
|
||||
<p>Readability, however, is emphasized above all else. A Markdown-formatted
|
||||
document should be publishable as-is, as plain text, without looking
|
||||
like it's been marked up with tags or formatting instructions. While
|
||||
Markdown's syntax has been influenced by several existing text-to-HTML
|
||||
filters -- including <a href="http://docutils.sourceforge.net/mirror/setext.html">Setext</a>, <a href="http://www.aaronsw.com/2002/atx/">atx</a>, <a href="http://textism.com/tools/textile/">Textile</a>, <a href="http://docutils.sourceforge.net/rst.html">reStructuredText</a>,
|
||||
<a href="http://www.triptico.com/software/grutatxt.html">Grutatext</a>, and <a href="http://ettext.taint.org/doc/">EtText</a> -- the single biggest source of
|
||||
inspiration for Markdown's syntax is the format of plain text email.</p>
|
||||
|
||||
<p>To this end, Markdown's syntax is comprised entirely of punctuation
|
||||
characters, which punctuation characters have been carefully chosen so
|
||||
as to look like what they mean. E.g., asterisks around a word actually
|
||||
look like *emphasis*. Markdown lists look like, well, lists. Even
|
||||
blockquotes look like quoted passages of text, assuming you've ever
|
||||
used email.</p>
|
||||
|
||||
<h3 id="html">Inline HTML</h3>
|
||||
|
||||
<p>Markdown's syntax is intended for one purpose: to be used as a
|
||||
format for <em>writing</em> for the web.</p>
|
||||
|
||||
<p>Markdown is not a replacement for HTML, or even close to it. Its
|
||||
syntax is very small, corresponding only to a very small subset of
|
||||
HTML tags. The idea is <em>not</em> to create a syntax that makes it easier
|
||||
to insert HTML tags. In my opinion, HTML tags are already easy to
|
||||
insert. The idea for Markdown is to make it easy to read, write, and
|
||||
edit prose. HTML is a <em>publishing</em> format; Markdown is a <em>writing</em>
|
||||
format. Thus, Markdown's formatting syntax only addresses issues that
|
||||
can be conveyed in plain text.</p>
|
||||
|
||||
<p>For any markup that is not covered by Markdown's syntax, you simply
|
||||
use HTML itself. There's no need to preface it or delimit it to
|
||||
indicate that you're switching from Markdown to HTML; you just use
|
||||
the tags.</p>
|
||||
|
||||
<p>The only restrictions are that block-level HTML elements -- e.g. <code><div></code>,
|
||||
<code><table></code>, <code><pre></code>, <code><p></code>, etc. -- must be separated from surrounding
|
||||
content by blank lines, and the start and end tags of the block should
|
||||
not be indented with tabs or spaces. Markdown is smart enough not
|
||||
to add extra (unwanted) <code><p></code> tags around HTML block-level tags.</p>
|
||||
|
||||
<p>For example, to add an HTML table to a Markdown article:</p>
|
||||
|
||||
<pre><code>This is a regular paragraph.
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td>Foo</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
This is another regular paragraph.
|
||||
</code></pre>
|
||||
|
||||
<p>Note that Markdown formatting syntax is not processed within block-level
|
||||
HTML tags. E.g., you can't use Markdown-style <code>*emphasis*</code> inside an
|
||||
HTML block.</p>
|
||||
|
||||
<p>Span-level HTML tags -- e.g. <code><span></code>, <code><cite></code>, or <code><del></code> -- can be
|
||||
used anywhere in a Markdown paragraph, list item, or header. If you
|
||||
want, you can even use HTML tags instead of Markdown formatting; e.g. if
|
||||
you'd prefer to use HTML <code><a></code> or <code><img></code> tags instead of Markdown's
|
||||
link or image syntax, go right ahead.</p>
|
||||
|
||||
<p>Unlike block-level HTML tags, Markdown syntax <em>is</em> processed within
|
||||
span-level tags.</p>
|
||||
|
||||
<h3 id="autoescape">Automatic Escaping for Special Characters</h3>
|
||||
|
||||
<p>In HTML, there are two characters that demand special treatment: <code><</code>
|
||||
and <code>&</code>. Left angle brackets are used to start tags; ampersands are
|
||||
used to denote HTML entities. If you want to use them as literal
|
||||
characters, you must escape them as entities, e.g. <code>&lt;</code>, and
|
||||
<code>&amp;</code>.</p>
|
||||
|
||||
<p>Ampersands in particular are bedeviling for web writers. If you want to
|
||||
write about 'AT&T', you need to write '<code>AT&amp;T</code>'. You even need to
|
||||
escape ampersands within URLs. Thus, if you want to link to:</p>
|
||||
|
||||
<pre><code>http://images.google.com/images?num=30&q=larry+bird
|
||||
</code></pre>
|
||||
|
||||
<p>you need to encode the URL as:</p>
|
||||
|
||||
<pre><code>http://images.google.com/images?num=30&amp;q=larry+bird
|
||||
</code></pre>
|
||||
|
||||
<p>in your anchor tag <code>href</code> attribute. Needless to say, this is easy to
|
||||
forget, and is probably the single most common source of HTML validation
|
||||
errors in otherwise well-marked-up web sites.</p>
|
||||
|
||||
<p>Markdown allows you to use these characters naturally, taking care of
|
||||
all the necessary escaping for you. If you use an ampersand as part of
|
||||
an HTML entity, it remains unchanged; otherwise it will be translated
|
||||
into <code>&amp;</code>.</p>
|
||||
|
||||
<p>So, if you want to include a copyright symbol in your article, you can write:</p>
|
||||
|
||||
<pre><code>&copy;
|
||||
</code></pre>
|
||||
|
||||
<p>and Markdown will leave it alone. But if you write:</p>
|
||||
|
||||
<pre><code>AT&T
|
||||
</code></pre>
|
||||
|
||||
<p>Markdown will translate it to:</p>
|
||||
|
||||
<pre><code>AT&amp;T
|
||||
</code></pre>
|
||||
|
||||
<p>Similarly, because Markdown supports <a href="#html">inline HTML</a>, if you use
|
||||
angle brackets as delimiters for HTML tags, Markdown will treat them as
|
||||
such. But if you write:</p>
|
||||
|
||||
<pre><code>4 < 5
|
||||
</code></pre>
|
||||
|
||||
<p>Markdown will translate it to:</p>
|
||||
|
||||
<pre><code>4 &lt; 5
|
||||
</code></pre>
|
||||
|
||||
<p>However, inside Markdown code spans and blocks, angle brackets and
|
||||
ampersands are <em>always</em> encoded automatically. This makes it easy to use
|
||||
Markdown to write about HTML code. (As opposed to raw HTML, which is a
|
||||
terrible format for writing about HTML syntax, because every single <code><</code>
|
||||
and <code>&</code> in your example code needs to be escaped.)</p>
|
||||
|
||||
<hr />
|
||||
|
||||
<h2 id="block">Block Elements</h2>
|
||||
|
||||
<h3 id="p">Paragraphs and Line Breaks</h3>
|
||||
|
||||
<p>A paragraph is simply one or more consecutive lines of text, separated
|
||||
by one or more blank lines. (A blank line is any line that looks like a
|
||||
blank line -- a line containing nothing but spaces or tabs is considered
|
||||
blank.) Normal paragraphs should not be intended with spaces or tabs.</p>
|
||||
|
||||
<p>The implication of the "one or more consecutive lines of text" rule is
|
||||
that Markdown supports "hard-wrapped" text paragraphs. This differs
|
||||
significantly from most other text-to-HTML formatters (including Movable
|
||||
Type's "Convert Line Breaks" option) which translate every line break
|
||||
character in a paragraph into a <code><br /></code> tag.</p>
|
||||
|
||||
<p>When you <em>do</em> want to insert a <code><br /></code> break tag using Markdown, you
|
||||
end a line with two or more spaces, then type return.</p>
|
||||
|
||||
<p>Yes, this takes a tad more effort to create a <code><br /></code>, but a simplistic
|
||||
"every line break is a <code><br /></code>" rule wouldn't work for Markdown.
|
||||
Markdown's email-style <a href="#blockquote">blockquoting</a> and multi-paragraph <a href="#list">list items</a>
|
||||
work best -- and look better -- when you format them with hard breaks.</p>
|
||||
|
||||
<h3 id="header">Headers</h3>
|
||||
|
||||
<p>Markdown supports two styles of headers, <a href="http://docutils.sourceforge.net/mirror/setext.html">Setext</a> and <a href="http://www.aaronsw.com/2002/atx/">atx</a>.</p>
|
||||
|
||||
<p>Setext-style headers are "underlined" using equal signs (for first-level
|
||||
headers) and dashes (for second-level headers). For example:</p>
|
||||
|
||||
<pre><code>This is an H1
|
||||
=============
|
||||
|
||||
This is an H2
|
||||
-------------
|
||||
</code></pre>
|
||||
|
||||
<p>Any number of underlining <code>=</code>'s or <code>-</code>'s will work.</p>
|
||||
|
||||
<p>Atx-style headers use 1-6 hash characters at the start of the line,
|
||||
corresponding to header levels 1-6. For example:</p>
|
||||
|
||||
<pre><code># This is an H1
|
||||
|
||||
## This is an H2
|
||||
|
||||
###### This is an H6
|
||||
</code></pre>
|
||||
|
||||
<p>Optionally, you may "close" atx-style headers. This is purely
|
||||
cosmetic -- you can use this if you think it looks better. The
|
||||
closing hashes don't even need to match the number of hashes
|
||||
used to open the header. (The number of opening hashes
|
||||
determines the header level.) :</p>
|
||||
|
||||
<pre><code># This is an H1 #
|
||||
|
||||
## This is an H2 ##
|
||||
|
||||
### This is an H3 ######
|
||||
</code></pre>
|
||||
|
||||
<h3 id="blockquote">Blockquotes</h3>
|
||||
|
||||
<p>Markdown uses email-style <code>></code> characters for blockquoting. If you're
|
||||
familiar with quoting passages of text in an email message, then you
|
||||
know how to create a blockquote in Markdown. It looks best if you hard
|
||||
wrap the text and put a <code>></code> before every line:</p>
|
||||
|
||||
<pre><code>> This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
|
||||
> consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
|
||||
> Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.
|
||||
>
|
||||
> Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
|
||||
> id sem consectetuer libero luctus adipiscing.
|
||||
</code></pre>
|
||||
|
||||
<p>Markdown allows you to be lazy and only put the <code>></code> before the first
|
||||
line of a hard-wrapped paragraph:</p>
|
||||
|
||||
<pre><code>> This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
|
||||
consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
|
||||
Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.
|
||||
|
||||
> Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
|
||||
id sem consectetuer libero luctus adipiscing.
|
||||
</code></pre>
|
||||
|
||||
<p>Blockquotes can be nested (i.e. a blockquote-in-a-blockquote) by
|
||||
adding additional levels of <code>></code>:</p>
|
||||
|
||||
<pre><code>> This is the first level of quoting.
|
||||
>
|
||||
> > This is nested blockquote.
|
||||
>
|
||||
> Back to the first level.
|
||||
</code></pre>
|
||||
|
||||
<p>Blockquotes can contain other Markdown elements, including headers, lists,
|
||||
and code blocks:</p>
|
||||
|
||||
<pre><code>> ## This is a header.
|
||||
>
|
||||
> 1. This is the first list item.
|
||||
> 2. This is the second list item.
|
||||
>
|
||||
> Here's some example code:
|
||||
>
|
||||
> return shell_exec("echo $input | $markdown_script");
|
||||
</code></pre>
|
||||
|
||||
<p>Any decent text editor should make email-style quoting easy. For
|
||||
example, with BBEdit, you can make a selection and choose Increase
|
||||
Quote Level from the Text menu.</p>
|
||||
|
||||
<h3 id="list">Lists</h3>
|
||||
|
||||
<p>Markdown supports ordered (numbered) and unordered (bulleted) lists.</p>
|
||||
|
||||
<p>Unordered lists use asterisks, pluses, and hyphens -- interchangably
|
||||
-- as list markers:</p>
|
||||
|
||||
<pre><code>* Red
|
||||
* Green
|
||||
* Blue
|
||||
</code></pre>
|
||||
|
||||
<p>is equivalent to:</p>
|
||||
|
||||
<pre><code>+ Red
|
||||
+ Green
|
||||
+ Blue
|
||||
</code></pre>
|
||||
|
||||
<p>and:</p>
|
||||
|
||||
<pre><code>- Red
|
||||
- Green
|
||||
- Blue
|
||||
</code></pre>
|
||||
|
||||
<p>Ordered lists use numbers followed by periods:</p>
|
||||
|
||||
<pre><code>1. Bird
|
||||
2. McHale
|
||||
3. Parish
|
||||
</code></pre>
|
||||
|
||||
<p>It's important to note that the actual numbers you use to mark the
|
||||
list have no effect on the HTML output Markdown produces. The HTML
|
||||
Markdown produces from the above list is:</p>
|
||||
|
||||
<pre><code><ol>
|
||||
<li>Bird</li>
|
||||
<li>McHale</li>
|
||||
<li>Parish</li>
|
||||
</ol>
|
||||
</code></pre>
|
||||
|
||||
<p>If you instead wrote the list in Markdown like this:</p>
|
||||
|
||||
<pre><code>1. Bird
|
||||
1. McHale
|
||||
1. Parish
|
||||
</code></pre>
|
||||
|
||||
<p>or even:</p>
|
||||
|
||||
<pre><code>3. Bird
|
||||
1. McHale
|
||||
8. Parish
|
||||
</code></pre>
|
||||
|
||||
<p>you'd get the exact same HTML output. The point is, if you want to,
|
||||
you can use ordinal numbers in your ordered Markdown lists, so that
|
||||
the numbers in your source match the numbers in your published HTML.
|
||||
But if you want to be lazy, you don't have to.</p>
|
||||
|
||||
<p>If you do use lazy list numbering, however, you should still start the
|
||||
list with the number 1. At some point in the future, Markdown may support
|
||||
starting ordered lists at an arbitrary number.</p>
|
||||
|
||||
<p>List markers typically start at the left margin, but may be indented by
|
||||
up to three spaces. List markers must be followed by one or more spaces
|
||||
or a tab.</p>
|
||||
|
||||
<p>To make lists look nice, you can wrap items with hanging indents:</p>
|
||||
|
||||
<pre><code>* Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
|
||||
Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,
|
||||
viverra nec, fringilla in, laoreet vitae, risus.
|
||||
* Donec sit amet nisl. Aliquam semper ipsum sit amet velit.
|
||||
Suspendisse id sem consectetuer libero luctus adipiscing.
|
||||
</code></pre>
|
||||
|
||||
<p>But if you want to be lazy, you don't have to:</p>
|
||||
|
||||
<pre><code>* Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
|
||||
Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,
|
||||
viverra nec, fringilla in, laoreet vitae, risus.
|
||||
* Donec sit amet nisl. Aliquam semper ipsum sit amet velit.
|
||||
Suspendisse id sem consectetuer libero luctus adipiscing.
|
||||
</code></pre>
|
||||
|
||||
<p>If list items are separated by blank lines, Markdown will wrap the
|
||||
items in <code><p></code> tags in the HTML output. For example, this input:</p>
|
||||
|
||||
<pre><code>* Bird
|
||||
* Magic
|
||||
</code></pre>
|
||||
|
||||
<p>will turn into:</p>
|
||||
|
||||
<pre><code><ul>
|
||||
<li>Bird</li>
|
||||
<li>Magic</li>
|
||||
</ul>
|
||||
</code></pre>
|
||||
|
||||
<p>But this:</p>
|
||||
|
||||
<pre><code>* Bird
|
||||
|
||||
* Magic
|
||||
</code></pre>
|
||||
|
||||
<p>will turn into:</p>
|
||||
|
||||
<pre><code><ul>
|
||||
<li><p>Bird</p></li>
|
||||
<li><p>Magic</p></li>
|
||||
</ul>
|
||||
</code></pre>
|
||||
|
||||
<p>List items may consist of multiple paragraphs. Each subsequent
|
||||
paragraph in a list item must be intended by either 4 spaces
|
||||
or one tab:</p>
|
||||
|
||||
<pre><code>1. This is a list item with two paragraphs. Lorem ipsum dolor
|
||||
sit amet, consectetuer adipiscing elit. Aliquam hendrerit
|
||||
mi posuere lectus.
|
||||
|
||||
Vestibulum enim wisi, viverra nec, fringilla in, laoreet
|
||||
vitae, risus. Donec sit amet nisl. Aliquam semper ipsum
|
||||
sit amet velit.
|
||||
|
||||
2. Suspendisse id sem consectetuer libero luctus adipiscing.
|
||||
</code></pre>
|
||||
|
||||
<p>It looks nice if you indent every line of the subsequent
|
||||
paragraphs, but here again, Markdown will allow you to be
|
||||
lazy:</p>
|
||||
|
||||
<pre><code>* This is a list item with two paragraphs.
|
||||
|
||||
This is the second paragraph in the list item. You're
|
||||
only required to indent the first line. Lorem ipsum dolor
|
||||
sit amet, consectetuer adipiscing elit.
|
||||
|
||||
* Another item in the same list.
|
||||
</code></pre>
|
||||
|
||||
<p>To put a blockquote within a list item, the blockquote's <code>></code>
|
||||
delimiters need to be indented:</p>
|
||||
|
||||
<pre><code>* A list item with a blockquote:
|
||||
|
||||
> This is a blockquote
|
||||
> inside a list item.
|
||||
</code></pre>
|
||||
|
||||
<p>To put a code block within a list item, the code block needs
|
||||
to be indented <em>twice</em> -- 8 spaces or two tabs:</p>
|
||||
|
||||
<pre><code>* A list item with a code block:
|
||||
|
||||
<code goes here>
|
||||
</code></pre>
|
||||
|
||||
<p>It's worth noting that it's possible to trigger an ordered list by
|
||||
accident, by writing something like this:</p>
|
||||
|
||||
<pre><code>1986. What a great season.
|
||||
</code></pre>
|
||||
|
||||
<p>In other words, a <em>number-period-space</em> sequence at the beginning of a
|
||||
line. To avoid this, you can backslash-escape the period:</p>
|
||||
|
||||
<pre><code>1986\. What a great season.
|
||||
</code></pre>
|
||||
|
||||
<h3 id="precode">Code Blocks</h3>
|
||||
|
||||
<p>Pre-formatted code blocks are used for writing about programming or
|
||||
markup source code. Rather than forming normal paragraphs, the lines
|
||||
of a code block are interpreted literally. Markdown wraps a code block
|
||||
in both <code><pre></code> and <code><code></code> tags.</p>
|
||||
|
||||
<p>To produce a code block in Markdown, simply indent every line of the
|
||||
block by at least 4 spaces or 1 tab. For example, given this input:</p>
|
||||
|
||||
<pre><code>This is a normal paragraph:
|
||||
|
||||
This is a code block.
|
||||
</code></pre>
|
||||
|
||||
<p>Markdown will generate:</p>
|
||||
|
||||
<pre><code><p>This is a normal paragraph:</p>
|
||||
|
||||
<pre><code>This is a code block.
|
||||
</code></pre>
|
||||
</code></pre>
|
||||
|
||||
<p>One level of indentation -- 4 spaces or 1 tab -- is removed from each
|
||||
line of the code block. For example, this:</p>
|
||||
|
||||
<pre><code>Here is an example of AppleScript:
|
||||
|
||||
tell application "Foo"
|
||||
beep
|
||||
end tell
|
||||
</code></pre>
|
||||
|
||||
<p>will turn into:</p>
|
||||
|
||||
<pre><code><p>Here is an example of AppleScript:</p>
|
||||
|
||||
<pre><code>tell application "Foo"
|
||||
beep
|
||||
end tell
|
||||
</code></pre>
|
||||
</code></pre>
|
||||
|
||||
<p>A code block continues until it reaches a line that is not indented
|
||||
(or the end of the article).</p>
|
||||
|
||||
<p>Within a code block, ampersands (<code>&</code>) and angle brackets (<code><</code> and <code>></code>)
|
||||
are automatically converted into HTML entities. This makes it very
|
||||
easy to include example HTML source code using Markdown -- just paste
|
||||
it and indent it, and Markdown will handle the hassle of encoding the
|
||||
ampersands and angle brackets. For example, this:</p>
|
||||
|
||||
<pre><code> <div class="footer">
|
||||
&copy; 2004 Foo Corporation
|
||||
</div>
|
||||
</code></pre>
|
||||
|
||||
<p>will turn into:</p>
|
||||
|
||||
<pre><code><pre><code>&lt;div class="footer"&gt;
|
||||
&amp;copy; 2004 Foo Corporation
|
||||
&lt;/div&gt;
|
||||
</code></pre>
|
||||
</code></pre>
|
||||
|
||||
<p>Regular Markdown syntax is not processed within code blocks. E.g.,
|
||||
asterisks are just literal asterisks within a code block. This means
|
||||
it's also easy to use Markdown to write about Markdown's own syntax.</p>
|
||||
|
||||
<h3 id="hr">Horizontal Rules</h3>
|
||||
|
||||
<p>You can produce a horizontal rule tag (<code><hr /></code>) by placing three or
|
||||
more hyphens, asterisks, or underscores on a line by themselves. If you
|
||||
wish, you may use spaces between the hyphens or asterisks. Each of the
|
||||
following lines will produce a horizontal rule:</p>
|
||||
|
||||
<pre><code>* * *
|
||||
|
||||
***
|
||||
|
||||
*****
|
||||
|
||||
- - -
|
||||
|
||||
---------------------------------------
|
||||
|
||||
_ _ _
|
||||
</code></pre>
|
||||
|
||||
<hr />
|
||||
|
||||
<h2 id="span">Span Elements</h2>
|
||||
|
||||
<h3 id="link">Links</h3>
|
||||
|
||||
<p>Markdown supports two style of links: <em>inline</em> and <em>reference</em>.</p>
|
||||
|
||||
<p>In both styles, the link text is delimited by [square brackets].</p>
|
||||
|
||||
<p>To create an inline link, use a set of regular parentheses immediately
|
||||
after the link text's closing square bracket. Inside the parentheses,
|
||||
put the URL where you want the link to point, along with an <em>optional</em>
|
||||
title for the link, surrounded in quotes. For example:</p>
|
||||
|
||||
<pre><code>This is [an example](http://example.com/ "Title") inline link.
|
||||
|
||||
[This link](http://example.net/) has no title attribute.
|
||||
</code></pre>
|
||||
|
||||
<p>Will produce:</p>
|
||||
|
||||
<pre><code><p>This is <a href="http://example.com/" title="Title">
|
||||
an example</a> inline link.</p>
|
||||
|
||||
<p><a href="http://example.net/">This link</a> has no
|
||||
title attribute.</p>
|
||||
</code></pre>
|
||||
|
||||
<p>If you're referring to a local resource on the same server, you can
|
||||
use relative paths:</p>
|
||||
|
||||
<pre><code>See my [About](/about/) page for details.
|
||||
</code></pre>
|
||||
|
||||
<p>Reference-style links use a second set of square brackets, inside
|
||||
which you place a label of your choosing to identify the link:</p>
|
||||
|
||||
<pre><code>This is [an example][id] reference-style link.
|
||||
</code></pre>
|
||||
|
||||
<p>You can optionally use a space to separate the sets of brackets:</p>
|
||||
|
||||
<pre><code>This is [an example] [id] reference-style link.
|
||||
</code></pre>
|
||||
|
||||
<p>Then, anywhere in the document, you define your link label like this,
|
||||
on a line by itself:</p>
|
||||
|
||||
<pre><code>[id]: http://example.com/ "Optional Title Here"
|
||||
</code></pre>
|
||||
|
||||
<p>That is:</p>
|
||||
|
||||
<ul>
|
||||
<li>Square brackets containing the link identifier (optionally
|
||||
indented from the left margin using up to three spaces);</li>
|
||||
<li>followed by a colon;</li>
|
||||
<li>followed by one or more spaces (or tabs);</li>
|
||||
<li>followed by the URL for the link;</li>
|
||||
<li>optionally followed by a title attribute for the link, enclosed
|
||||
in double or single quotes.</li>
|
||||
</ul>
|
||||
|
||||
<p>The link URL may, optionally, be surrounded by angle brackets:</p>
|
||||
|
||||
<pre><code>[id]: <http://example.com/> "Optional Title Here"
|
||||
</code></pre>
|
||||
|
||||
<p>You can put the title attribute on the next line and use extra spaces
|
||||
or tabs for padding, which tends to look better with longer URLs:</p>
|
||||
|
||||
<pre><code>[id]: http://example.com/longish/path/to/resource/here
|
||||
"Optional Title Here"
|
||||
</code></pre>
|
||||
|
||||
<p>Link definitions are only used for creating links during Markdown
|
||||
processing, and are stripped from your document in the HTML output.</p>
|
||||
|
||||
<p>Link definition names may constist of letters, numbers, spaces, and punctuation -- but they are <em>not</em> case sensitive. E.g. these two links:</p>
|
||||
|
||||
<pre><code>[link text][a]
|
||||
[link text][A]
|
||||
</code></pre>
|
||||
|
||||
<p>are equivalent.</p>
|
||||
|
||||
<p>The <em>implicit link name</em> shortcut allows you to omit the name of the
|
||||
link, in which case the link text itself is used as the name.
|
||||
Just use an empty set of square brackets -- e.g., to link the word
|
||||
"Google" to the google.com web site, you could simply write:</p>
|
||||
|
||||
<pre><code>[Google][]
|
||||
</code></pre>
|
||||
|
||||
<p>And then define the link:</p>
|
||||
|
||||
<pre><code>[Google]: http://google.com/
|
||||
</code></pre>
|
||||
|
||||
<p>Because link names may contain spaces, this shortcut even works for
|
||||
multiple words in the link text:</p>
|
||||
|
||||
<pre><code>Visit [Daring Fireball][] for more information.
|
||||
</code></pre>
|
||||
|
||||
<p>And then define the link:</p>
|
||||
|
||||
<pre><code>[Daring Fireball]: http://daringfireball.net/
|
||||
</code></pre>
|
||||
|
||||
<p>Link definitions can be placed anywhere in your Markdown document. I
|
||||
tend to put them immediately after each paragraph in which they're
|
||||
used, but if you want, you can put them all at the end of your
|
||||
document, sort of like footnotes.</p>
|
||||
|
||||
<p>Here's an example of reference links in action:</p>
|
||||
|
||||
<pre><code>I get 10 times more traffic from [Google] [1] than from
|
||||
[Yahoo] [2] or [MSN] [3].
|
||||
|
||||
[1]: http://google.com/ "Google"
|
||||
[2]: http://search.yahoo.com/ "Yahoo Search"
|
||||
[3]: http://search.msn.com/ "MSN Search"
|
||||
</code></pre>
|
||||
|
||||
<p>Using the implicit link name shortcut, you could instead write:</p>
|
||||
|
||||
<pre><code>I get 10 times more traffic from [Google][] than from
|
||||
[Yahoo][] or [MSN][].
|
||||
|
||||
[google]: http://google.com/ "Google"
|
||||
[yahoo]: http://search.yahoo.com/ "Yahoo Search"
|
||||
[msn]: http://search.msn.com/ "MSN Search"
|
||||
</code></pre>
|
||||
|
||||
<p>Both of the above examples will produce the following HTML output:</p>
|
||||
|
||||
<pre><code><p>I get 10 times more traffic from <a href="http://google.com/"
|
||||
title="Google">Google</a> than from
|
||||
<a href="http://search.yahoo.com/" title="Yahoo Search">Yahoo</a>
|
||||
or <a href="http://search.msn.com/" title="MSN Search">MSN</a>.</p>
|
||||
</code></pre>
|
||||
|
||||
<p>For comparison, here is the same paragraph written using
|
||||
Markdown's inline link style:</p>
|
||||
|
||||
<pre><code>I get 10 times more traffic from [Google](http://google.com/ "Google")
|
||||
than from [Yahoo](http://search.yahoo.com/ "Yahoo Search") or
|
||||
[MSN](http://search.msn.com/ "MSN Search").
|
||||
</code></pre>
|
||||
|
||||
<p>The point of reference-style links is not that they're easier to
|
||||
write. The point is that with reference-style links, your document
|
||||
source is vastly more readable. Compare the above examples: using
|
||||
reference-style links, the paragraph itself is only 81 characters
|
||||
long; with inline-style links, it's 176 characters; and as raw HTML,
|
||||
it's 234 characters. In the raw HTML, there's more markup than there
|
||||
is text.</p>
|
||||
|
||||
<p>With Markdown's reference-style links, a source document much more
|
||||
closely resembles the final output, as rendered in a browser. By
|
||||
allowing you to move the markup-related metadata out of the paragraph,
|
||||
you can add links without interrupting the narrative flow of your
|
||||
prose.</p>
|
||||
|
||||
<h3 id="em">Emphasis</h3>
|
||||
|
||||
<p>Markdown treats asterisks (<code>*</code>) and underscores (<code>_</code>) as indicators of
|
||||
emphasis. Text wrapped with one <code>*</code> or <code>_</code> will be wrapped with an
|
||||
HTML <code><em></code> tag; double <code>*</code>'s or <code>_</code>'s will be wrapped with an HTML
|
||||
<code><strong></code> tag. E.g., this input:</p>
|
||||
|
||||
<pre><code>*single asterisks*
|
||||
|
||||
_single underscores_
|
||||
|
||||
**double asterisks**
|
||||
|
||||
__double underscores__
|
||||
</code></pre>
|
||||
|
||||
<p>will produce:</p>
|
||||
|
||||
<pre><code><em>single asterisks</em>
|
||||
|
||||
<em>single underscores</em>
|
||||
|
||||
<strong>double asterisks</strong>
|
||||
|
||||
<strong>double underscores</strong>
|
||||
</code></pre>
|
||||
|
||||
<p>You can use whichever style you prefer; the lone restriction is that
|
||||
the same character must be used to open and close an emphasis span.</p>
|
||||
|
||||
<p>Emphasis can be used in the middle of a word:</p>
|
||||
|
||||
<pre><code>un*fucking*believable
|
||||
</code></pre>
|
||||
|
||||
<p>But if you surround an <code>*</code> or <code>_</code> with spaces, it'll be treated as a
|
||||
literal asterisk or underscore.</p>
|
||||
|
||||
<p>To produce a literal asterisk or underscore at a position where it
|
||||
would otherwise be used as an emphasis delimiter, you can backslash
|
||||
escape it:</p>
|
||||
|
||||
<pre><code>\*this text is surrounded by literal asterisks\*
|
||||
</code></pre>
|
||||
|
||||
<h3 id="code">Code</h3>
|
||||
|
||||
<p>To indicate a span of code, wrap it with backtick quotes (<code>`</code>).
|
||||
Unlike a pre-formatted code block, a code span indicates code within a
|
||||
normal paragraph. For example:</p>
|
||||
|
||||
<pre><code>Use the `printf()` function.
|
||||
</code></pre>
|
||||
|
||||
<p>will produce:</p>
|
||||
|
||||
<pre><code><p>Use the <code>printf()</code> function.</p>
|
||||
</code></pre>
|
||||
|
||||
<p>To include a literal backtick character within a code span, you can use
|
||||
multiple backticks as the opening and closing delimiters:</p>
|
||||
|
||||
<pre><code>``There is a literal backtick (`) here.``
|
||||
</code></pre>
|
||||
|
||||
<p>which will produce this:</p>
|
||||
|
||||
<pre><code><p><code>There is a literal backtick (`) here.</code></p>
|
||||
</code></pre>
|
||||
|
||||
<p>The backtick delimiters surrounding a code span may include spaces --
|
||||
one after the opening, one before the closing. This allows you to place
|
||||
literal backtick characters at the beginning or end of a code span:</p>
|
||||
|
||||
<pre><code>A single backtick in a code span: `` ` ``
|
||||
|
||||
A backtick-delimited string in a code span: `` `foo` ``
|
||||
</code></pre>
|
||||
|
||||
<p>will produce:</p>
|
||||
|
||||
<pre><code><p>A single backtick in a code span: <code>`</code></p>
|
||||
|
||||
<p>A backtick-delimited string in a code span: <code>`foo`</code></p>
|
||||
</code></pre>
|
||||
|
||||
<p>With a code span, ampersands and angle brackets are encoded as HTML
|
||||
entities automatically, which makes it easy to include example HTML
|
||||
tags. Markdown will turn this:</p>
|
||||
|
||||
<pre><code>Please don't use any `<blink>` tags.
|
||||
</code></pre>
|
||||
|
||||
<p>into:</p>
|
||||
|
||||
<pre><code><p>Please don't use any <code>&lt;blink&gt;</code> tags.</p>
|
||||
</code></pre>
|
||||
|
||||
<p>You can write this:</p>
|
||||
|
||||
<pre><code>`&#8212;` is the decimal-encoded equivalent of `&mdash;`.
|
||||
</code></pre>
|
||||
|
||||
<p>to produce:</p>
|
||||
|
||||
<pre><code><p><code>&amp;#8212;</code> is the decimal-encoded
|
||||
equivalent of <code>&amp;mdash;</code>.</p>
|
||||
</code></pre>
|
||||
|
||||
<h3 id="img">Images</h3>
|
||||
|
||||
<p>Admittedly, it's fairly difficult to devise a "natural" syntax for
|
||||
placing images into a plain text document format.</p>
|
||||
|
||||
<p>Markdown uses an image syntax that is intended to resemble the syntax
|
||||
for links, allowing for two styles: <em>inline</em> and <em>reference</em>.</p>
|
||||
|
||||
<p>Inline image syntax looks like this:</p>
|
||||
|
||||
<pre><code>
|
||||
|
||||

|
||||
</code></pre>
|
||||
|
||||
<p>That is:</p>
|
||||
|
||||
<ul>
|
||||
<li>An exclamation mark: <code>!</code>;</li>
|
||||
<li>followed by a set of square brackets, containing the <code>alt</code>
|
||||
attribute text for the image;</li>
|
||||
<li>followed by a set of parentheses, containing the URL or path to
|
||||
the image, and an optional <code>title</code> attribute enclosed in double
|
||||
or single quotes.</li>
|
||||
</ul>
|
||||
|
||||
<p>Reference-style image syntax looks like this:</p>
|
||||
|
||||
<pre><code>![Alt text][id]
|
||||
</code></pre>
|
||||
|
||||
<p>Where "id" is the name of a defined image reference. Image references
|
||||
are defined using syntax identical to link references:</p>
|
||||
|
||||
<pre><code>[id]: url/to/image "Optional title attribute"
|
||||
</code></pre>
|
||||
|
||||
<p>As of this writing, Markdown has no syntax for specifying the
|
||||
dimensions of an image; if this is important to you, you can simply
|
||||
use regular HTML <code><img></code> tags.</p>
|
||||
|
||||
<hr />
|
||||
|
||||
<h2 id="misc">Miscellaneous</h2>
|
||||
|
||||
<h3 id="autolink">Automatic Links</h3>
|
||||
|
||||
<p>Markdown supports a shortcut style for creating "automatic" links for URLs and email addresses: simply surround the URL or email address with angle brackets. What this means is that if you want to show the actual text of a URL or email address, and also have it be a clickable link, you can do this:</p>
|
||||
|
||||
<pre><code><http://example.com/>
|
||||
</code></pre>
|
||||
|
||||
<p>Markdown will turn this into:</p>
|
||||
|
||||
<pre><code><a href="http://example.com/">http://example.com/</a>
|
||||
</code></pre>
|
||||
|
||||
<p>Automatic links for email addresses work similarly, except that
|
||||
Markdown will also perform a bit of randomized decimal and hex
|
||||
entity-encoding to help obscure your address from address-harvesting
|
||||
spambots. For example, Markdown will turn this:</p>
|
||||
|
||||
<pre><code><address@example.com>
|
||||
</code></pre>
|
||||
|
||||
<p>into something like this:</p>
|
||||
|
||||
<pre><code><a href="&#x6D;&#x61;i&#x6C;&#x74;&#x6F;:&#x61;&#x64;&#x64;&#x72;&#x65;
|
||||
&#115;&#115;&#64;&#101;&#120;&#x61;&#109;&#x70;&#x6C;e&#x2E;&#99;&#111;
|
||||
&#109;">&#x61;&#x64;&#x64;&#x72;&#x65;&#115;&#115;&#64;&#101;&#120;&#x61;
|
||||
&#109;&#x70;&#x6C;e&#x2E;&#99;&#111;&#109;</a>
|
||||
</code></pre>
|
||||
|
||||
<p>which will render in a browser as a clickable link to "address@example.com".</p>
|
||||
|
||||
<p>(This sort of entity-encoding trick will indeed fool many, if not
|
||||
most, address-harvesting bots, but it definitely won't fool all of
|
||||
them. It's better than nothing, but an address published in this way
|
||||
will probably eventually start receiving spam.)</p>
|
||||
|
||||
<h3 id="backslash">Backslash Escapes</h3>
|
||||
|
||||
<p>Markdown allows you to use backslash escapes to generate literal
|
||||
characters which would otherwise have special meaning in Markdown's
|
||||
formatting syntax. For example, if you wanted to surround a word with
|
||||
literal asterisks (instead of an HTML <code><em></code> tag), you can backslashes
|
||||
before the asterisks, like this:</p>
|
||||
|
||||
<pre><code>\*literal asterisks\*
|
||||
</code></pre>
|
||||
|
||||
<p>Markdown provides backslash escapes for the following characters:</p>
|
||||
|
||||
<pre><code>\ backslash
|
||||
` backtick
|
||||
* asterisk
|
||||
_ underscore
|
||||
{} curly braces
|
||||
[] square brackets
|
||||
() parentheses
|
||||
# hash mark
|
||||
+ plus sign
|
||||
- minus sign (hyphen)
|
||||
. dot
|
||||
! exclamation mark
|
||||
</code></pre>
|
888
supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Markdown Documentation - Syntax.text
Normal file
888
supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Markdown Documentation - Syntax.text
Normal file
@ -0,0 +1,888 @@
|
||||
Markdown: Syntax
|
||||
================
|
||||
|
||||
<ul id="ProjectSubmenu">
|
||||
<li><a href="/projects/markdown/" title="Markdown Project Page">Main</a></li>
|
||||
<li><a href="/projects/markdown/basics" title="Markdown Basics">Basics</a></li>
|
||||
<li><a class="selected" title="Markdown Syntax Documentation">Syntax</a></li>
|
||||
<li><a href="/projects/markdown/license" title="Pricing and License Information">License</a></li>
|
||||
<li><a href="/projects/markdown/dingus" title="Online Markdown Web Form">Dingus</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
* [Overview](#overview)
|
||||
* [Philosophy](#philosophy)
|
||||
* [Inline HTML](#html)
|
||||
* [Automatic Escaping for Special Characters](#autoescape)
|
||||
* [Block Elements](#block)
|
||||
* [Paragraphs and Line Breaks](#p)
|
||||
* [Headers](#header)
|
||||
* [Blockquotes](#blockquote)
|
||||
* [Lists](#list)
|
||||
* [Code Blocks](#precode)
|
||||
* [Horizontal Rules](#hr)
|
||||
* [Span Elements](#span)
|
||||
* [Links](#link)
|
||||
* [Emphasis](#em)
|
||||
* [Code](#code)
|
||||
* [Images](#img)
|
||||
* [Miscellaneous](#misc)
|
||||
* [Backslash Escapes](#backslash)
|
||||
* [Automatic Links](#autolink)
|
||||
|
||||
|
||||
**Note:** This document is itself written using Markdown; you
|
||||
can [see the source for it by adding '.text' to the URL][src].
|
||||
|
||||
[src]: /projects/markdown/syntax.text
|
||||
|
||||
* * *
|
||||
|
||||
<h2 id="overview">Overview</h2>
|
||||
|
||||
<h3 id="philosophy">Philosophy</h3>
|
||||
|
||||
Markdown is intended to be as easy-to-read and easy-to-write as is feasible.
|
||||
|
||||
Readability, however, is emphasized above all else. A Markdown-formatted
|
||||
document should be publishable as-is, as plain text, without looking
|
||||
like it's been marked up with tags or formatting instructions. While
|
||||
Markdown's syntax has been influenced by several existing text-to-HTML
|
||||
filters -- including [Setext] [1], [atx] [2], [Textile] [3], [reStructuredText] [4],
|
||||
[Grutatext] [5], and [EtText] [6] -- the single biggest source of
|
||||
inspiration for Markdown's syntax is the format of plain text email.
|
||||
|
||||
[1]: http://docutils.sourceforge.net/mirror/setext.html
|
||||
[2]: http://www.aaronsw.com/2002/atx/
|
||||
[3]: http://textism.com/tools/textile/
|
||||
[4]: http://docutils.sourceforge.net/rst.html
|
||||
[5]: http://www.triptico.com/software/grutatxt.html
|
||||
[6]: http://ettext.taint.org/doc/
|
||||
|
||||
To this end, Markdown's syntax is comprised entirely of punctuation
|
||||
characters, which punctuation characters have been carefully chosen so
|
||||
as to look like what they mean. E.g., asterisks around a word actually
|
||||
look like \*emphasis\*. Markdown lists look like, well, lists. Even
|
||||
blockquotes look like quoted passages of text, assuming you've ever
|
||||
used email.
|
||||
|
||||
|
||||
|
||||
<h3 id="html">Inline HTML</h3>
|
||||
|
||||
Markdown's syntax is intended for one purpose: to be used as a
|
||||
format for *writing* for the web.
|
||||
|
||||
Markdown is not a replacement for HTML, or even close to it. Its
|
||||
syntax is very small, corresponding only to a very small subset of
|
||||
HTML tags. The idea is *not* to create a syntax that makes it easier
|
||||
to insert HTML tags. In my opinion, HTML tags are already easy to
|
||||
insert. The idea for Markdown is to make it easy to read, write, and
|
||||
edit prose. HTML is a *publishing* format; Markdown is a *writing*
|
||||
format. Thus, Markdown's formatting syntax only addresses issues that
|
||||
can be conveyed in plain text.
|
||||
|
||||
For any markup that is not covered by Markdown's syntax, you simply
|
||||
use HTML itself. There's no need to preface it or delimit it to
|
||||
indicate that you're switching from Markdown to HTML; you just use
|
||||
the tags.
|
||||
|
||||
The only restrictions are that block-level HTML elements -- e.g. `<div>`,
|
||||
`<table>`, `<pre>`, `<p>`, etc. -- must be separated from surrounding
|
||||
content by blank lines, and the start and end tags of the block should
|
||||
not be indented with tabs or spaces. Markdown is smart enough not
|
||||
to add extra (unwanted) `<p>` tags around HTML block-level tags.
|
||||
|
||||
For example, to add an HTML table to a Markdown article:
|
||||
|
||||
This is a regular paragraph.
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td>Foo</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
This is another regular paragraph.
|
||||
|
||||
Note that Markdown formatting syntax is not processed within block-level
|
||||
HTML tags. E.g., you can't use Markdown-style `*emphasis*` inside an
|
||||
HTML block.
|
||||
|
||||
Span-level HTML tags -- e.g. `<span>`, `<cite>`, or `<del>` -- can be
|
||||
used anywhere in a Markdown paragraph, list item, or header. If you
|
||||
want, you can even use HTML tags instead of Markdown formatting; e.g. if
|
||||
you'd prefer to use HTML `<a>` or `<img>` tags instead of Markdown's
|
||||
link or image syntax, go right ahead.
|
||||
|
||||
Unlike block-level HTML tags, Markdown syntax *is* processed within
|
||||
span-level tags.
|
||||
|
||||
|
||||
<h3 id="autoescape">Automatic Escaping for Special Characters</h3>
|
||||
|
||||
In HTML, there are two characters that demand special treatment: `<`
|
||||
and `&`. Left angle brackets are used to start tags; ampersands are
|
||||
used to denote HTML entities. If you want to use them as literal
|
||||
characters, you must escape them as entities, e.g. `<`, and
|
||||
`&`.
|
||||
|
||||
Ampersands in particular are bedeviling for web writers. If you want to
|
||||
write about 'AT&T', you need to write '`AT&T`'. You even need to
|
||||
escape ampersands within URLs. Thus, if you want to link to:
|
||||
|
||||
http://images.google.com/images?num=30&q=larry+bird
|
||||
|
||||
you need to encode the URL as:
|
||||
|
||||
http://images.google.com/images?num=30&q=larry+bird
|
||||
|
||||
in your anchor tag `href` attribute. Needless to say, this is easy to
|
||||
forget, and is probably the single most common source of HTML validation
|
||||
errors in otherwise well-marked-up web sites.
|
||||
|
||||
Markdown allows you to use these characters naturally, taking care of
|
||||
all the necessary escaping for you. If you use an ampersand as part of
|
||||
an HTML entity, it remains unchanged; otherwise it will be translated
|
||||
into `&`.
|
||||
|
||||
So, if you want to include a copyright symbol in your article, you can write:
|
||||
|
||||
©
|
||||
|
||||
and Markdown will leave it alone. But if you write:
|
||||
|
||||
AT&T
|
||||
|
||||
Markdown will translate it to:
|
||||
|
||||
AT&T
|
||||
|
||||
Similarly, because Markdown supports [inline HTML](#html), if you use
|
||||
angle brackets as delimiters for HTML tags, Markdown will treat them as
|
||||
such. But if you write:
|
||||
|
||||
4 < 5
|
||||
|
||||
Markdown will translate it to:
|
||||
|
||||
4 < 5
|
||||
|
||||
However, inside Markdown code spans and blocks, angle brackets and
|
||||
ampersands are *always* encoded automatically. This makes it easy to use
|
||||
Markdown to write about HTML code. (As opposed to raw HTML, which is a
|
||||
terrible format for writing about HTML syntax, because every single `<`
|
||||
and `&` in your example code needs to be escaped.)
|
||||
|
||||
|
||||
* * *
|
||||
|
||||
|
||||
<h2 id="block">Block Elements</h2>
|
||||
|
||||
|
||||
<h3 id="p">Paragraphs and Line Breaks</h3>
|
||||
|
||||
A paragraph is simply one or more consecutive lines of text, separated
|
||||
by one or more blank lines. (A blank line is any line that looks like a
|
||||
blank line -- a line containing nothing but spaces or tabs is considered
|
||||
blank.) Normal paragraphs should not be intended with spaces or tabs.
|
||||
|
||||
The implication of the "one or more consecutive lines of text" rule is
|
||||
that Markdown supports "hard-wrapped" text paragraphs. This differs
|
||||
significantly from most other text-to-HTML formatters (including Movable
|
||||
Type's "Convert Line Breaks" option) which translate every line break
|
||||
character in a paragraph into a `<br />` tag.
|
||||
|
||||
When you *do* want to insert a `<br />` break tag using Markdown, you
|
||||
end a line with two or more spaces, then type return.
|
||||
|
||||
Yes, this takes a tad more effort to create a `<br />`, but a simplistic
|
||||
"every line break is a `<br />`" rule wouldn't work for Markdown.
|
||||
Markdown's email-style [blockquoting][bq] and multi-paragraph [list items][l]
|
||||
work best -- and look better -- when you format them with hard breaks.
|
||||
|
||||
[bq]: #blockquote
|
||||
[l]: #list
|
||||
|
||||
|
||||
|
||||
<h3 id="header">Headers</h3>
|
||||
|
||||
Markdown supports two styles of headers, [Setext] [1] and [atx] [2].
|
||||
|
||||
Setext-style headers are "underlined" using equal signs (for first-level
|
||||
headers) and dashes (for second-level headers). For example:
|
||||
|
||||
This is an H1
|
||||
=============
|
||||
|
||||
This is an H2
|
||||
-------------
|
||||
|
||||
Any number of underlining `=`'s or `-`'s will work.
|
||||
|
||||
Atx-style headers use 1-6 hash characters at the start of the line,
|
||||
corresponding to header levels 1-6. For example:
|
||||
|
||||
# This is an H1
|
||||
|
||||
## This is an H2
|
||||
|
||||
###### This is an H6
|
||||
|
||||
Optionally, you may "close" atx-style headers. This is purely
|
||||
cosmetic -- you can use this if you think it looks better. The
|
||||
closing hashes don't even need to match the number of hashes
|
||||
used to open the header. (The number of opening hashes
|
||||
determines the header level.) :
|
||||
|
||||
# This is an H1 #
|
||||
|
||||
## This is an H2 ##
|
||||
|
||||
### This is an H3 ######
|
||||
|
||||
|
||||
<h3 id="blockquote">Blockquotes</h3>
|
||||
|
||||
Markdown uses email-style `>` characters for blockquoting. If you're
|
||||
familiar with quoting passages of text in an email message, then you
|
||||
know how to create a blockquote in Markdown. It looks best if you hard
|
||||
wrap the text and put a `>` before every line:
|
||||
|
||||
> This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
|
||||
> consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
|
||||
> Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.
|
||||
>
|
||||
> Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
|
||||
> id sem consectetuer libero luctus adipiscing.
|
||||
|
||||
Markdown allows you to be lazy and only put the `>` before the first
|
||||
line of a hard-wrapped paragraph:
|
||||
|
||||
> This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
|
||||
consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
|
||||
Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.
|
||||
|
||||
> Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
|
||||
id sem consectetuer libero luctus adipiscing.
|
||||
|
||||
Blockquotes can be nested (i.e. a blockquote-in-a-blockquote) by
|
||||
adding additional levels of `>`:
|
||||
|
||||
> This is the first level of quoting.
|
||||
>
|
||||
> > This is nested blockquote.
|
||||
>
|
||||
> Back to the first level.
|
||||
|
||||
Blockquotes can contain other Markdown elements, including headers, lists,
|
||||
and code blocks:
|
||||
|
||||
> ## This is a header.
|
||||
>
|
||||
> 1. This is the first list item.
|
||||
> 2. This is the second list item.
|
||||
>
|
||||
> Here's some example code:
|
||||
>
|
||||
> return shell_exec("echo $input | $markdown_script");
|
||||
|
||||
Any decent text editor should make email-style quoting easy. For
|
||||
example, with BBEdit, you can make a selection and choose Increase
|
||||
Quote Level from the Text menu.
|
||||
|
||||
|
||||
<h3 id="list">Lists</h3>
|
||||
|
||||
Markdown supports ordered (numbered) and unordered (bulleted) lists.
|
||||
|
||||
Unordered lists use asterisks, pluses, and hyphens -- interchangably
|
||||
-- as list markers:
|
||||
|
||||
* Red
|
||||
* Green
|
||||
* Blue
|
||||
|
||||
is equivalent to:
|
||||
|
||||
+ Red
|
||||
+ Green
|
||||
+ Blue
|
||||
|
||||
and:
|
||||
|
||||
- Red
|
||||
- Green
|
||||
- Blue
|
||||
|
||||
Ordered lists use numbers followed by periods:
|
||||
|
||||
1. Bird
|
||||
2. McHale
|
||||
3. Parish
|
||||
|
||||
It's important to note that the actual numbers you use to mark the
|
||||
list have no effect on the HTML output Markdown produces. The HTML
|
||||
Markdown produces from the above list is:
|
||||
|
||||
<ol>
|
||||
<li>Bird</li>
|
||||
<li>McHale</li>
|
||||
<li>Parish</li>
|
||||
</ol>
|
||||
|
||||
If you instead wrote the list in Markdown like this:
|
||||
|
||||
1. Bird
|
||||
1. McHale
|
||||
1. Parish
|
||||
|
||||
or even:
|
||||
|
||||
3. Bird
|
||||
1. McHale
|
||||
8. Parish
|
||||
|
||||
you'd get the exact same HTML output. The point is, if you want to,
|
||||
you can use ordinal numbers in your ordered Markdown lists, so that
|
||||
the numbers in your source match the numbers in your published HTML.
|
||||
But if you want to be lazy, you don't have to.
|
||||
|
||||
If you do use lazy list numbering, however, you should still start the
|
||||
list with the number 1. At some point in the future, Markdown may support
|
||||
starting ordered lists at an arbitrary number.
|
||||
|
||||
List markers typically start at the left margin, but may be indented by
|
||||
up to three spaces. List markers must be followed by one or more spaces
|
||||
or a tab.
|
||||
|
||||
To make lists look nice, you can wrap items with hanging indents:
|
||||
|
||||
* Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
|
||||
Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,
|
||||
viverra nec, fringilla in, laoreet vitae, risus.
|
||||
* Donec sit amet nisl. Aliquam semper ipsum sit amet velit.
|
||||
Suspendisse id sem consectetuer libero luctus adipiscing.
|
||||
|
||||
But if you want to be lazy, you don't have to:
|
||||
|
||||
* Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
|
||||
Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,
|
||||
viverra nec, fringilla in, laoreet vitae, risus.
|
||||
* Donec sit amet nisl. Aliquam semper ipsum sit amet velit.
|
||||
Suspendisse id sem consectetuer libero luctus adipiscing.
|
||||
|
||||
If list items are separated by blank lines, Markdown will wrap the
|
||||
items in `<p>` tags in the HTML output. For example, this input:
|
||||
|
||||
* Bird
|
||||
* Magic
|
||||
|
||||
will turn into:
|
||||
|
||||
<ul>
|
||||
<li>Bird</li>
|
||||
<li>Magic</li>
|
||||
</ul>
|
||||
|
||||
But this:
|
||||
|
||||
* Bird
|
||||
|
||||
* Magic
|
||||
|
||||
will turn into:
|
||||
|
||||
<ul>
|
||||
<li><p>Bird</p></li>
|
||||
<li><p>Magic</p></li>
|
||||
</ul>
|
||||
|
||||
List items may consist of multiple paragraphs. Each subsequent
|
||||
paragraph in a list item must be intended by either 4 spaces
|
||||
or one tab:
|
||||
|
||||
1. This is a list item with two paragraphs. Lorem ipsum dolor
|
||||
sit amet, consectetuer adipiscing elit. Aliquam hendrerit
|
||||
mi posuere lectus.
|
||||
|
||||
Vestibulum enim wisi, viverra nec, fringilla in, laoreet
|
||||
vitae, risus. Donec sit amet nisl. Aliquam semper ipsum
|
||||
sit amet velit.
|
||||
|
||||
2. Suspendisse id sem consectetuer libero luctus adipiscing.
|
||||
|
||||
It looks nice if you indent every line of the subsequent
|
||||
paragraphs, but here again, Markdown will allow you to be
|
||||
lazy:
|
||||
|
||||
* This is a list item with two paragraphs.
|
||||
|
||||
This is the second paragraph in the list item. You're
|
||||
only required to indent the first line. Lorem ipsum dolor
|
||||
sit amet, consectetuer adipiscing elit.
|
||||
|
||||
* Another item in the same list.
|
||||
|
||||
To put a blockquote within a list item, the blockquote's `>`
|
||||
delimiters need to be indented:
|
||||
|
||||
* A list item with a blockquote:
|
||||
|
||||
> This is a blockquote
|
||||
> inside a list item.
|
||||
|
||||
To put a code block within a list item, the code block needs
|
||||
to be indented *twice* -- 8 spaces or two tabs:
|
||||
|
||||
* A list item with a code block:
|
||||
|
||||
<code goes here>
|
||||
|
||||
|
||||
It's worth noting that it's possible to trigger an ordered list by
|
||||
accident, by writing something like this:
|
||||
|
||||
1986. What a great season.
|
||||
|
||||
In other words, a *number-period-space* sequence at the beginning of a
|
||||
line. To avoid this, you can backslash-escape the period:
|
||||
|
||||
1986\. What a great season.
|
||||
|
||||
|
||||
|
||||
<h3 id="precode">Code Blocks</h3>
|
||||
|
||||
Pre-formatted code blocks are used for writing about programming or
|
||||
markup source code. Rather than forming normal paragraphs, the lines
|
||||
of a code block are interpreted literally. Markdown wraps a code block
|
||||
in both `<pre>` and `<code>` tags.
|
||||
|
||||
To produce a code block in Markdown, simply indent every line of the
|
||||
block by at least 4 spaces or 1 tab. For example, given this input:
|
||||
|
||||
This is a normal paragraph:
|
||||
|
||||
This is a code block.
|
||||
|
||||
Markdown will generate:
|
||||
|
||||
<p>This is a normal paragraph:</p>
|
||||
|
||||
<pre><code>This is a code block.
|
||||
</code></pre>
|
||||
|
||||
One level of indentation -- 4 spaces or 1 tab -- is removed from each
|
||||
line of the code block. For example, this:
|
||||
|
||||
Here is an example of AppleScript:
|
||||
|
||||
tell application "Foo"
|
||||
beep
|
||||
end tell
|
||||
|
||||
will turn into:
|
||||
|
||||
<p>Here is an example of AppleScript:</p>
|
||||
|
||||
<pre><code>tell application "Foo"
|
||||
beep
|
||||
end tell
|
||||
</code></pre>
|
||||
|
||||
A code block continues until it reaches a line that is not indented
|
||||
(or the end of the article).
|
||||
|
||||
Within a code block, ampersands (`&`) and angle brackets (`<` and `>`)
|
||||
are automatically converted into HTML entities. This makes it very
|
||||
easy to include example HTML source code using Markdown -- just paste
|
||||
it and indent it, and Markdown will handle the hassle of encoding the
|
||||
ampersands and angle brackets. For example, this:
|
||||
|
||||
<div class="footer">
|
||||
© 2004 Foo Corporation
|
||||
</div>
|
||||
|
||||
will turn into:
|
||||
|
||||
<pre><code><div class="footer">
|
||||
&copy; 2004 Foo Corporation
|
||||
</div>
|
||||
</code></pre>
|
||||
|
||||
Regular Markdown syntax is not processed within code blocks. E.g.,
|
||||
asterisks are just literal asterisks within a code block. This means
|
||||
it's also easy to use Markdown to write about Markdown's own syntax.
|
||||
|
||||
|
||||
|
||||
<h3 id="hr">Horizontal Rules</h3>
|
||||
|
||||
You can produce a horizontal rule tag (`<hr />`) by placing three or
|
||||
more hyphens, asterisks, or underscores on a line by themselves. If you
|
||||
wish, you may use spaces between the hyphens or asterisks. Each of the
|
||||
following lines will produce a horizontal rule:
|
||||
|
||||
* * *
|
||||
|
||||
***
|
||||
|
||||
*****
|
||||
|
||||
- - -
|
||||
|
||||
---------------------------------------
|
||||
|
||||
_ _ _
|
||||
|
||||
|
||||
* * *
|
||||
|
||||
<h2 id="span">Span Elements</h2>
|
||||
|
||||
<h3 id="link">Links</h3>
|
||||
|
||||
Markdown supports two style of links: *inline* and *reference*.
|
||||
|
||||
In both styles, the link text is delimited by [square brackets].
|
||||
|
||||
To create an inline link, use a set of regular parentheses immediately
|
||||
after the link text's closing square bracket. Inside the parentheses,
|
||||
put the URL where you want the link to point, along with an *optional*
|
||||
title for the link, surrounded in quotes. For example:
|
||||
|
||||
This is [an example](http://example.com/ "Title") inline link.
|
||||
|
||||
[This link](http://example.net/) has no title attribute.
|
||||
|
||||
Will produce:
|
||||
|
||||
<p>This is <a href="http://example.com/" title="Title">
|
||||
an example</a> inline link.</p>
|
||||
|
||||
<p><a href="http://example.net/">This link</a> has no
|
||||
title attribute.</p>
|
||||
|
||||
If you're referring to a local resource on the same server, you can
|
||||
use relative paths:
|
||||
|
||||
See my [About](/about/) page for details.
|
||||
|
||||
Reference-style links use a second set of square brackets, inside
|
||||
which you place a label of your choosing to identify the link:
|
||||
|
||||
This is [an example][id] reference-style link.
|
||||
|
||||
You can optionally use a space to separate the sets of brackets:
|
||||
|
||||
This is [an example] [id] reference-style link.
|
||||
|
||||
Then, anywhere in the document, you define your link label like this,
|
||||
on a line by itself:
|
||||
|
||||
[id]: http://example.com/ "Optional Title Here"
|
||||
|
||||
That is:
|
||||
|
||||
* Square brackets containing the link identifier (optionally
|
||||
indented from the left margin using up to three spaces);
|
||||
* followed by a colon;
|
||||
* followed by one or more spaces (or tabs);
|
||||
* followed by the URL for the link;
|
||||
* optionally followed by a title attribute for the link, enclosed
|
||||
in double or single quotes.
|
||||
|
||||
The link URL may, optionally, be surrounded by angle brackets:
|
||||
|
||||
[id]: <http://example.com/> "Optional Title Here"
|
||||
|
||||
You can put the title attribute on the next line and use extra spaces
|
||||
or tabs for padding, which tends to look better with longer URLs:
|
||||
|
||||
[id]: http://example.com/longish/path/to/resource/here
|
||||
"Optional Title Here"
|
||||
|
||||
Link definitions are only used for creating links during Markdown
|
||||
processing, and are stripped from your document in the HTML output.
|
||||
|
||||
Link definition names may constist of letters, numbers, spaces, and punctuation -- but they are *not* case sensitive. E.g. these two links:
|
||||
|
||||
[link text][a]
|
||||
[link text][A]
|
||||
|
||||
are equivalent.
|
||||
|
||||
The *implicit link name* shortcut allows you to omit the name of the
|
||||
link, in which case the link text itself is used as the name.
|
||||
Just use an empty set of square brackets -- e.g., to link the word
|
||||
"Google" to the google.com web site, you could simply write:
|
||||
|
||||
[Google][]
|
||||
|
||||
And then define the link:
|
||||
|
||||
[Google]: http://google.com/
|
||||
|
||||
Because link names may contain spaces, this shortcut even works for
|
||||
multiple words in the link text:
|
||||
|
||||
Visit [Daring Fireball][] for more information.
|
||||
|
||||
And then define the link:
|
||||
|
||||
[Daring Fireball]: http://daringfireball.net/
|
||||
|
||||
Link definitions can be placed anywhere in your Markdown document. I
|
||||
tend to put them immediately after each paragraph in which they're
|
||||
used, but if you want, you can put them all at the end of your
|
||||
document, sort of like footnotes.
|
||||
|
||||
Here's an example of reference links in action:
|
||||
|
||||
I get 10 times more traffic from [Google] [1] than from
|
||||
[Yahoo] [2] or [MSN] [3].
|
||||
|
||||
[1]: http://google.com/ "Google"
|
||||
[2]: http://search.yahoo.com/ "Yahoo Search"
|
||||
[3]: http://search.msn.com/ "MSN Search"
|
||||
|
||||
Using the implicit link name shortcut, you could instead write:
|
||||
|
||||
I get 10 times more traffic from [Google][] than from
|
||||
[Yahoo][] or [MSN][].
|
||||
|
||||
[google]: http://google.com/ "Google"
|
||||
[yahoo]: http://search.yahoo.com/ "Yahoo Search"
|
||||
[msn]: http://search.msn.com/ "MSN Search"
|
||||
|
||||
Both of the above examples will produce the following HTML output:
|
||||
|
||||
<p>I get 10 times more traffic from <a href="http://google.com/"
|
||||
title="Google">Google</a> than from
|
||||
<a href="http://search.yahoo.com/" title="Yahoo Search">Yahoo</a>
|
||||
or <a href="http://search.msn.com/" title="MSN Search">MSN</a>.</p>
|
||||
|
||||
For comparison, here is the same paragraph written using
|
||||
Markdown's inline link style:
|
||||
|
||||
I get 10 times more traffic from [Google](http://google.com/ "Google")
|
||||
than from [Yahoo](http://search.yahoo.com/ "Yahoo Search") or
|
||||
[MSN](http://search.msn.com/ "MSN Search").
|
||||
|
||||
The point of reference-style links is not that they're easier to
|
||||
write. The point is that with reference-style links, your document
|
||||
source is vastly more readable. Compare the above examples: using
|
||||
reference-style links, the paragraph itself is only 81 characters
|
||||
long; with inline-style links, it's 176 characters; and as raw HTML,
|
||||
it's 234 characters. In the raw HTML, there's more markup than there
|
||||
is text.
|
||||
|
||||
With Markdown's reference-style links, a source document much more
|
||||
closely resembles the final output, as rendered in a browser. By
|
||||
allowing you to move the markup-related metadata out of the paragraph,
|
||||
you can add links without interrupting the narrative flow of your
|
||||
prose.
|
||||
|
||||
|
||||
<h3 id="em">Emphasis</h3>
|
||||
|
||||
Markdown treats asterisks (`*`) and underscores (`_`) as indicators of
|
||||
emphasis. Text wrapped with one `*` or `_` will be wrapped with an
|
||||
HTML `<em>` tag; double `*`'s or `_`'s will be wrapped with an HTML
|
||||
`<strong>` tag. E.g., this input:
|
||||
|
||||
*single asterisks*
|
||||
|
||||
_single underscores_
|
||||
|
||||
**double asterisks**
|
||||
|
||||
__double underscores__
|
||||
|
||||
will produce:
|
||||
|
||||
<em>single asterisks</em>
|
||||
|
||||
<em>single underscores</em>
|
||||
|
||||
<strong>double asterisks</strong>
|
||||
|
||||
<strong>double underscores</strong>
|
||||
|
||||
You can use whichever style you prefer; the lone restriction is that
|
||||
the same character must be used to open and close an emphasis span.
|
||||
|
||||
Emphasis can be used in the middle of a word:
|
||||
|
||||
un*fucking*believable
|
||||
|
||||
But if you surround an `*` or `_` with spaces, it'll be treated as a
|
||||
literal asterisk or underscore.
|
||||
|
||||
To produce a literal asterisk or underscore at a position where it
|
||||
would otherwise be used as an emphasis delimiter, you can backslash
|
||||
escape it:
|
||||
|
||||
\*this text is surrounded by literal asterisks\*
|
||||
|
||||
|
||||
|
||||
<h3 id="code">Code</h3>
|
||||
|
||||
To indicate a span of code, wrap it with backtick quotes (`` ` ``).
|
||||
Unlike a pre-formatted code block, a code span indicates code within a
|
||||
normal paragraph. For example:
|
||||
|
||||
Use the `printf()` function.
|
||||
|
||||
will produce:
|
||||
|
||||
<p>Use the <code>printf()</code> function.</p>
|
||||
|
||||
To include a literal backtick character within a code span, you can use
|
||||
multiple backticks as the opening and closing delimiters:
|
||||
|
||||
``There is a literal backtick (`) here.``
|
||||
|
||||
which will produce this:
|
||||
|
||||
<p><code>There is a literal backtick (`) here.</code></p>
|
||||
|
||||
The backtick delimiters surrounding a code span may include spaces --
|
||||
one after the opening, one before the closing. This allows you to place
|
||||
literal backtick characters at the beginning or end of a code span:
|
||||
|
||||
A single backtick in a code span: `` ` ``
|
||||
|
||||
A backtick-delimited string in a code span: `` `foo` ``
|
||||
|
||||
will produce:
|
||||
|
||||
<p>A single backtick in a code span: <code>`</code></p>
|
||||
|
||||
<p>A backtick-delimited string in a code span: <code>`foo`</code></p>
|
||||
|
||||
With a code span, ampersands and angle brackets are encoded as HTML
|
||||
entities automatically, which makes it easy to include example HTML
|
||||
tags. Markdown will turn this:
|
||||
|
||||
Please don't use any `<blink>` tags.
|
||||
|
||||
into:
|
||||
|
||||
<p>Please don't use any <code><blink></code> tags.</p>
|
||||
|
||||
You can write this:
|
||||
|
||||
`—` is the decimal-encoded equivalent of `—`.
|
||||
|
||||
to produce:
|
||||
|
||||
<p><code>&#8212;</code> is the decimal-encoded
|
||||
equivalent of <code>&mdash;</code>.</p>
|
||||
|
||||
|
||||
|
||||
<h3 id="img">Images</h3>
|
||||
|
||||
Admittedly, it's fairly difficult to devise a "natural" syntax for
|
||||
placing images into a plain text document format.
|
||||
|
||||
Markdown uses an image syntax that is intended to resemble the syntax
|
||||
for links, allowing for two styles: *inline* and *reference*.
|
||||
|
||||
Inline image syntax looks like this:
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
That is:
|
||||
|
||||
* An exclamation mark: `!`;
|
||||
* followed by a set of square brackets, containing the `alt`
|
||||
attribute text for the image;
|
||||
* followed by a set of parentheses, containing the URL or path to
|
||||
the image, and an optional `title` attribute enclosed in double
|
||||
or single quotes.
|
||||
|
||||
Reference-style image syntax looks like this:
|
||||
|
||||
![Alt text][id]
|
||||
|
||||
Where "id" is the name of a defined image reference. Image references
|
||||
are defined using syntax identical to link references:
|
||||
|
||||
[id]: url/to/image "Optional title attribute"
|
||||
|
||||
As of this writing, Markdown has no syntax for specifying the
|
||||
dimensions of an image; if this is important to you, you can simply
|
||||
use regular HTML `<img>` tags.
|
||||
|
||||
|
||||
* * *
|
||||
|
||||
|
||||
<h2 id="misc">Miscellaneous</h2>
|
||||
|
||||
<h3 id="autolink">Automatic Links</h3>
|
||||
|
||||
Markdown supports a shortcut style for creating "automatic" links for URLs and email addresses: simply surround the URL or email address with angle brackets. What this means is that if you want to show the actual text of a URL or email address, and also have it be a clickable link, you can do this:
|
||||
|
||||
<http://example.com/>
|
||||
|
||||
Markdown will turn this into:
|
||||
|
||||
<a href="http://example.com/">http://example.com/</a>
|
||||
|
||||
Automatic links for email addresses work similarly, except that
|
||||
Markdown will also perform a bit of randomized decimal and hex
|
||||
entity-encoding to help obscure your address from address-harvesting
|
||||
spambots. For example, Markdown will turn this:
|
||||
|
||||
<address@example.com>
|
||||
|
||||
into something like this:
|
||||
|
||||
<a href="mailto:addre
|
||||
ss@example.co
|
||||
m">address@exa
|
||||
mple.com</a>
|
||||
|
||||
which will render in a browser as a clickable link to "address@example.com".
|
||||
|
||||
(This sort of entity-encoding trick will indeed fool many, if not
|
||||
most, address-harvesting bots, but it definitely won't fool all of
|
||||
them. It's better than nothing, but an address published in this way
|
||||
will probably eventually start receiving spam.)
|
||||
|
||||
|
||||
|
||||
<h3 id="backslash">Backslash Escapes</h3>
|
||||
|
||||
Markdown allows you to use backslash escapes to generate literal
|
||||
characters which would otherwise have special meaning in Markdown's
|
||||
formatting syntax. For example, if you wanted to surround a word with
|
||||
literal asterisks (instead of an HTML `<em>` tag), you can backslashes
|
||||
before the asterisks, like this:
|
||||
|
||||
\*literal asterisks\*
|
||||
|
||||
Markdown provides backslash escapes for the following characters:
|
||||
|
||||
\ backslash
|
||||
` backtick
|
||||
* asterisk
|
||||
_ underscore
|
||||
{} curly braces
|
||||
[] square brackets
|
||||
() parentheses
|
||||
# hash mark
|
||||
+ plus sign
|
||||
- minus sign (hyphen)
|
||||
. dot
|
||||
! exclamation mark
|
||||
|
@ -0,0 +1,9 @@
|
||||
<blockquote>
|
||||
<p>foo</p>
|
||||
|
||||
<blockquote>
|
||||
<p>bar</p>
|
||||
</blockquote>
|
||||
|
||||
<p>foo</p>
|
||||
</blockquote>
|
@ -0,0 +1,5 @@
|
||||
> foo
|
||||
>
|
||||
> > bar
|
||||
>
|
||||
> foo
|
@ -0,0 +1,148 @@
|
||||
<h2>Unordered</h2>
|
||||
|
||||
<p>Asterisks tight:</p>
|
||||
|
||||
<ul>
|
||||
<li>asterisk 1</li>
|
||||
<li>asterisk 2</li>
|
||||
<li>asterisk 3</li>
|
||||
</ul>
|
||||
|
||||
<p>Asterisks loose:</p>
|
||||
|
||||
<ul>
|
||||
<li><p>asterisk 1</p></li>
|
||||
<li><p>asterisk 2</p></li>
|
||||
<li><p>asterisk 3</p></li>
|
||||
</ul>
|
||||
|
||||
<hr />
|
||||
|
||||
<p>Pluses tight:</p>
|
||||
|
||||
<ul>
|
||||
<li>Plus 1</li>
|
||||
<li>Plus 2</li>
|
||||
<li>Plus 3</li>
|
||||
</ul>
|
||||
|
||||
<p>Pluses loose:</p>
|
||||
|
||||
<ul>
|
||||
<li><p>Plus 1</p></li>
|
||||
<li><p>Plus 2</p></li>
|
||||
<li><p>Plus 3</p></li>
|
||||
</ul>
|
||||
|
||||
<hr />
|
||||
|
||||
<p>Minuses tight:</p>
|
||||
|
||||
<ul>
|
||||
<li>Minus 1</li>
|
||||
<li>Minus 2</li>
|
||||
<li>Minus 3</li>
|
||||
</ul>
|
||||
|
||||
<p>Minuses loose:</p>
|
||||
|
||||
<ul>
|
||||
<li><p>Minus 1</p></li>
|
||||
<li><p>Minus 2</p></li>
|
||||
<li><p>Minus 3</p></li>
|
||||
</ul>
|
||||
|
||||
<h2>Ordered</h2>
|
||||
|
||||
<p>Tight:</p>
|
||||
|
||||
<ol>
|
||||
<li>First</li>
|
||||
<li>Second</li>
|
||||
<li>Third</li>
|
||||
</ol>
|
||||
|
||||
<p>and:</p>
|
||||
|
||||
<ol>
|
||||
<li>One</li>
|
||||
<li>Two</li>
|
||||
<li>Three</li>
|
||||
</ol>
|
||||
|
||||
<p>Loose using tabs:</p>
|
||||
|
||||
<ol>
|
||||
<li><p>First</p></li>
|
||||
<li><p>Second</p></li>
|
||||
<li><p>Third</p></li>
|
||||
</ol>
|
||||
|
||||
<p>and using spaces:</p>
|
||||
|
||||
<ol>
|
||||
<li><p>One</p></li>
|
||||
<li><p>Two</p></li>
|
||||
<li><p>Three</p></li>
|
||||
</ol>
|
||||
|
||||
<p>Multiple paragraphs:</p>
|
||||
|
||||
<ol>
|
||||
<li><p>Item 1, graf one.</p>
|
||||
|
||||
<p>Item 2. graf two. The quick brown fox jumped over the lazy dog's
|
||||
back.</p></li>
|
||||
<li><p>Item 2.</p></li>
|
||||
<li><p>Item 3.</p></li>
|
||||
</ol>
|
||||
|
||||
<h2>Nested</h2>
|
||||
|
||||
<ul>
|
||||
<li>Tab
|
||||
<ul>
|
||||
<li>Tab
|
||||
<ul>
|
||||
<li>Tab</li>
|
||||
</ul></li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
|
||||
<p>Here's another:</p>
|
||||
|
||||
<ol>
|
||||
<li>First</li>
|
||||
<li>Second:
|
||||
<ul>
|
||||
<li>Fee</li>
|
||||
<li>Fie</li>
|
||||
<li>Foe</li>
|
||||
</ul></li>
|
||||
<li>Third</li>
|
||||
</ol>
|
||||
|
||||
<p>Same thing but with paragraphs:</p>
|
||||
|
||||
<ol>
|
||||
<li><p>First</p></li>
|
||||
<li><p>Second:</p>
|
||||
|
||||
<ul>
|
||||
<li>Fee</li>
|
||||
<li>Fie</li>
|
||||
<li>Foe</li>
|
||||
</ul></li>
|
||||
<li><p>Third</p></li>
|
||||
</ol>
|
||||
|
||||
|
||||
<p>This was an error in Markdown 1.0.1:</p>
|
||||
|
||||
<ul>
|
||||
<li><p>this</p>
|
||||
|
||||
<ul><li>sub</li></ul>
|
||||
|
||||
<p>that</p></li>
|
||||
</ul>
|
@ -0,0 +1,131 @@
|
||||
## Unordered
|
||||
|
||||
Asterisks tight:
|
||||
|
||||
* asterisk 1
|
||||
* asterisk 2
|
||||
* asterisk 3
|
||||
|
||||
|
||||
Asterisks loose:
|
||||
|
||||
* asterisk 1
|
||||
|
||||
* asterisk 2
|
||||
|
||||
* asterisk 3
|
||||
|
||||
* * *
|
||||
|
||||
Pluses tight:
|
||||
|
||||
+ Plus 1
|
||||
+ Plus 2
|
||||
+ Plus 3
|
||||
|
||||
|
||||
Pluses loose:
|
||||
|
||||
+ Plus 1
|
||||
|
||||
+ Plus 2
|
||||
|
||||
+ Plus 3
|
||||
|
||||
* * *
|
||||
|
||||
|
||||
Minuses tight:
|
||||
|
||||
- Minus 1
|
||||
- Minus 2
|
||||
- Minus 3
|
||||
|
||||
|
||||
Minuses loose:
|
||||
|
||||
- Minus 1
|
||||
|
||||
- Minus 2
|
||||
|
||||
- Minus 3
|
||||
|
||||
|
||||
## Ordered
|
||||
|
||||
Tight:
|
||||
|
||||
1. First
|
||||
2. Second
|
||||
3. Third
|
||||
|
||||
and:
|
||||
|
||||
1. One
|
||||
2. Two
|
||||
3. Three
|
||||
|
||||
|
||||
Loose using tabs:
|
||||
|
||||
1. First
|
||||
|
||||
2. Second
|
||||
|
||||
3. Third
|
||||
|
||||
and using spaces:
|
||||
|
||||
1. One
|
||||
|
||||
2. Two
|
||||
|
||||
3. Three
|
||||
|
||||
Multiple paragraphs:
|
||||
|
||||
1. Item 1, graf one.
|
||||
|
||||
Item 2. graf two. The quick brown fox jumped over the lazy dog's
|
||||
back.
|
||||
|
||||
2. Item 2.
|
||||
|
||||
3. Item 3.
|
||||
|
||||
|
||||
|
||||
## Nested
|
||||
|
||||
* Tab
|
||||
* Tab
|
||||
* Tab
|
||||
|
||||
Here's another:
|
||||
|
||||
1. First
|
||||
2. Second:
|
||||
* Fee
|
||||
* Fie
|
||||
* Foe
|
||||
3. Third
|
||||
|
||||
Same thing but with paragraphs:
|
||||
|
||||
1. First
|
||||
|
||||
2. Second:
|
||||
* Fee
|
||||
* Fie
|
||||
* Foe
|
||||
|
||||
3. Third
|
||||
|
||||
|
||||
This was an error in Markdown 1.0.1:
|
||||
|
||||
* this
|
||||
|
||||
* sub
|
||||
|
||||
that
|
@ -0,0 +1,7 @@
|
||||
<p><strong><em>This is strong and em.</em></strong></p>
|
||||
|
||||
<p>So is <strong><em>this</em></strong> word.</p>
|
||||
|
||||
<p><strong><em>This is strong and em.</em></strong></p>
|
||||
|
||||
<p>So is <strong><em>this</em></strong> word.</p>
|
@ -0,0 +1,7 @@
|
||||
***This is strong and em.***
|
||||
|
||||
So is ***this*** word.
|
||||
|
||||
___This is strong and em.___
|
||||
|
||||
So is ___this___ word.
|
25
supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Tabs.html
Normal file
25
supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Tabs.html
Normal file
@ -0,0 +1,25 @@
|
||||
<ul>
|
||||
<li><p>this is a list item
|
||||
indented with tabs</p></li>
|
||||
<li><p>this is a list item
|
||||
indented with spaces</p></li>
|
||||
</ul>
|
||||
|
||||
<p>Code:</p>
|
||||
|
||||
<pre><code>this code block is indented by one tab
|
||||
</code></pre>
|
||||
|
||||
<p>And:</p>
|
||||
|
||||
<pre><code> this code block is indented by two tabs
|
||||
</code></pre>
|
||||
|
||||
<p>And:</p>
|
||||
|
||||
<pre><code>+ this is an example list item
|
||||
indented with tabs
|
||||
|
||||
+ this is an example list item
|
||||
indented with spaces
|
||||
</code></pre>
|
21
supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Tabs.text
Normal file
21
supportlibs/pegmarkdown/MarkdownTest_1.0.3/Tests/Tabs.text
Normal file
@ -0,0 +1,21 @@
|
||||
+ this is a list item
|
||||
indented with tabs
|
||||
|
||||
+ this is a list item
|
||||
indented with spaces
|
||||
|
||||
Code:
|
||||
|
||||
this code block is indented by one tab
|
||||
|
||||
And:
|
||||
|
||||
this code block is indented by two tabs
|
||||
|
||||
And:
|
||||
|
||||
+ this is an example list item
|
||||
indented with tabs
|
||||
|
||||
+ this is an example list item
|
||||
indented with spaces
|
@ -0,0 +1,8 @@
|
||||
<blockquote>
|
||||
<p>A list within a blockquote:</p>
|
||||
<ul>
|
||||
<li>asterisk 1</li>
|
||||
<li>asterisk 2</li>
|
||||
<li>asterisk 3</li>
|
||||
</ul>
|
||||
</blockquote>
|
@ -0,0 +1,5 @@
|
||||
> A list within a blockquote:
|
||||
>
|
||||
> * asterisk 1
|
||||
> * asterisk 2
|
||||
> * asterisk 3
|
225
supportlibs/pegmarkdown/README.markdown
Normal file
225
supportlibs/pegmarkdown/README.markdown
Normal file
@ -0,0 +1,225 @@
|
||||
|
||||
This a forked version of peg-markdown.... only minor changes:
|
||||
|
||||
* Switch to Qt .pro make system for easy x-platform.
|
||||
|
||||
* build a library instead of exec.
|
||||
|
||||
* Add GLibFacade from multimarkdown to allow Win32 compilations.
|
||||
|
||||
* Added ifdefs for C++ linking,
|
||||
|
||||
|
||||
What is this?
|
||||
=============
|
||||
|
||||
This is an implementation of John Gruber's [markdown][] in C. It uses a
|
||||
[parsing expression grammar (PEG)][] to define the syntax. This should
|
||||
allow easy modification and extension. It currently supports output in
|
||||
HTML, LaTeX, ODF, or groff_mm formats, and adding new formats is
|
||||
relatively easy.
|
||||
|
||||
[parsing expression grammar (PEG)]: http://en.wikipedia.org/wiki/Parsing_expression_grammar
|
||||
[markdown]: http://daringfireball.net/projects/markdown/
|
||||
|
||||
It is pretty fast. A 179K text file that takes 5.7 seconds for
|
||||
Markdown.pl (v. 1.0.1) to parse takes less than 0.2 seconds for this
|
||||
markdown. It does, however, use a lot of memory (up to 4M of heap space
|
||||
while parsing the 179K file, and up to 80K for a 4K file). (Note that
|
||||
the memory leaks in earlier versions of this program have now been
|
||||
plugged.)
|
||||
|
||||
Both a library and a standalone program are provided.
|
||||
|
||||
peg-markdown is written and maintained by John MacFarlane (jgm on
|
||||
github), with significant contributions by Ryan Tomayko (rtomayko).
|
||||
It is released under both the GPL and the MIT license; see LICENSE for
|
||||
details.
|
||||
|
||||
Installing
|
||||
==========
|
||||
|
||||
On a linux or unix-based system
|
||||
-------------------------------
|
||||
|
||||
This program is written in portable ANSI C. It requires
|
||||
[glib2](http://www.gtk.org/download/index.php). Most *nix systems will have
|
||||
this installed already. The build system requires GNU make.
|
||||
|
||||
The other required dependency, [Ian Piumarta's peg/leg PEG parser
|
||||
generator](http://piumarta.com/software/peg/), is included in the source
|
||||
directory. It will be built automatically. (However, it is not as portable
|
||||
as peg-markdown itself, and seems to require gcc.)
|
||||
|
||||
To make the 'markdown' executable:
|
||||
|
||||
make
|
||||
|
||||
(Or, on some systems, `gmake`.) Then, for usage instructions:
|
||||
|
||||
./markdown --help
|
||||
|
||||
To run John Gruber's Markdown 1.0.3 test suite:
|
||||
|
||||
make test
|
||||
|
||||
The test suite will fail on one of the list tests. Here's why.
|
||||
Markdown.pl encloses "item one" in the following list in `<p>` tags:
|
||||
|
||||
1. item one
|
||||
* subitem
|
||||
* subitem
|
||||
|
||||
2. item two
|
||||
|
||||
3. item three
|
||||
|
||||
peg-markdown does not enclose "item one" in `<p>` tags unless it has a
|
||||
following blank line. This is consistent with the official markdown
|
||||
syntax description, and lets the author of the document choose whether
|
||||
`<p>` tags are desired.
|
||||
|
||||
Cross-compiling for Windows with MinGW on a linux box
|
||||
-----------------------------------------------------
|
||||
|
||||
Prerequisites:
|
||||
|
||||
* Linux system with MinGW cross compiler For Ubuntu:
|
||||
|
||||
sudo apt-get install mingw32
|
||||
|
||||
* [Windows glib-2.0 binary & development files](http://www.gtk.org/download-windows.html).
|
||||
Unzip files into cross-compiler directory tree (e.g., `/usr/i586-mingw32msvc`).
|
||||
|
||||
Steps:
|
||||
|
||||
1. Create the markdown parser using Linux-compiled `leg` from peg-0.1.4:
|
||||
|
||||
./peg-0.1.4/leg markdown_parser.leg >markdown_parser.c
|
||||
|
||||
(Note: The same thing could be accomplished by cross-compiling leg,
|
||||
executing it on Windows, and copying the resulting C file to the Linux
|
||||
cross-compiler host.)
|
||||
|
||||
2. Run the cross compiler with include flag for the Windows glib-2.0 headers:
|
||||
for example,
|
||||
|
||||
/usr/bin/i586-mingw32msvc-cc -c \
|
||||
-I/usr/i586-mingw32msvc/include/glib-2.0 \
|
||||
-I/usr/i586-mingw32msvc/lib/glib-2.0/include -Wall -O3 -ansi markdown*.c
|
||||
|
||||
3. Link against Windows glib-2.0 headers: for example,
|
||||
|
||||
/usr/bin/i586-mingw32msvc-cc markdown*.o \
|
||||
-Wl,-L/usr/i586-mingw32msvc/lib/glib,--dy,--warn-unresolved-symbols,-lglib-2.0 \
|
||||
-o markdown.exe
|
||||
|
||||
The resulting executable depends on the glib dll file, so be sure to
|
||||
load the glib binary on the Windows host.
|
||||
|
||||
Compiling with MinGW on Windows
|
||||
-------------------------------
|
||||
|
||||
These directions assume that MinGW is installed in `c:\MinGW` and glib-2.0
|
||||
is installed in the MinGW directory hierarchy (with the mingw bin directory
|
||||
in the system path).
|
||||
|
||||
Unzip peg-markdown in a temp directory. From the directory with the
|
||||
peg-markdown source, execute:
|
||||
|
||||
cd peg-0.1.4
|
||||
make PKG_CONFIG=c:/path/to/glib/bin/pkg-config.exe
|
||||
|
||||
Extensions
|
||||
==========
|
||||
|
||||
peg-markdown supports extensions to standard markdown syntax.
|
||||
These can be turned on using the command line flag `-x` or
|
||||
`--extensions`. `-x` by itself turns on all extensions. Extensions
|
||||
can also be turned on selectively, using individual command-line
|
||||
options. To see the available extensions:
|
||||
|
||||
./markdown --help-extensions
|
||||
|
||||
The `--smart` extension provides "smart quotes", dashes, and ellipses.
|
||||
|
||||
The `--notes` extension provides a footnote syntax like that of
|
||||
Pandoc or PHP Markdown Extra.
|
||||
|
||||
Using the library
|
||||
=================
|
||||
|
||||
The library exports two functions:
|
||||
|
||||
GString * markdown_to_g_string(char *text, int extensions, int output_format);
|
||||
char * markdown_to_string(char *text, int extensions, int output_format);
|
||||
|
||||
The only difference between these is that `markdown_to_g_string` returns a
|
||||
`GString` (glib's automatically resizable string), while `markdown_to_string`
|
||||
returns a regular character pointer. The memory allocated for these must be
|
||||
freed by the calling program, using `g_string_free()` or `free()`.
|
||||
|
||||
`text` is the markdown-formatted text to be converted. Note that tabs will
|
||||
be converted to spaces, using a four-space tab stop. Character encodings are
|
||||
ignored.
|
||||
|
||||
`extensions` is a bit-field specifying which syntax extensions should be used.
|
||||
If `extensions` is 0, no extensions will be used. If it is `0xFFFFFF`,
|
||||
all extensions will be used. To set extensions selectively, use the
|
||||
bitwise `&` operator and the following constants:
|
||||
|
||||
- `EXT_SMART` turns on smart quotes, dashes, and ellipses.
|
||||
- `EXT_NOTES` turns on footnote syntax. [Pandoc's footnote syntax][] is used here.
|
||||
- `EXT_FILTER_HTML` filters out raw HTML (except for styles).
|
||||
- `EXT_FILTER_STYLES` filters out styles in HTML.
|
||||
|
||||
[Pandoc's footnote syntax]: http://johnmacfarlane.net/pandoc/README.html#footnotes
|
||||
|
||||
`output_format` is either `HTML_FORMAT`, `LATEX_FORMAT`, `ODF_FORMAT`,
|
||||
or `GROFF_MM_FORMAT`.
|
||||
|
||||
To use the library, include `markdown_lib.h`. See `markdown.c` for an example.
|
||||
|
||||
Hacking
|
||||
=======
|
||||
|
||||
It should be pretty easy to modify the program to produce other formats,
|
||||
and to parse syntax extensions. A quick guide:
|
||||
|
||||
* `markdown_parser.leg` contains the grammar itself.
|
||||
|
||||
* `markdown_output.c` contains functions for printing the `Element`
|
||||
structure in various output formats.
|
||||
|
||||
* To add an output format, add the format to `markdown_formats` in
|
||||
`markdown_lib.h`. Then modify `print_element` in `markdown_output.c`,
|
||||
and add functions `print_XXXX_string`, `print_XXXX_element`, and
|
||||
`print_XXXX_element_list`. Also add an option in the main program
|
||||
that selects the new format. Don't forget to add it to the list of
|
||||
formats in the usage message.
|
||||
|
||||
* To add syntax extensions, define them in the PEG grammar
|
||||
(`markdown_parser.leg`), using existing extensions as a guide. New
|
||||
inline elements will need to be added to `Inline =`; new block
|
||||
elements will need to be added to `Block =`. (Note: the order
|
||||
of the alternatives does matter in PEG grammars.)
|
||||
|
||||
* If you need to add new types of elements, modify the `keys`
|
||||
enum in `markdown_peg.h`.
|
||||
|
||||
* By using `&{ }` rules one can selectively disable extensions
|
||||
depending on command-line options. For example,
|
||||
`&{ extension(EXT_SMART) }` succeeds only if the `EXT_SMART` bit
|
||||
of the global `syntax_extensions` is set. Add your option to
|
||||
`markdown_extensions` in `markdown_lib.h`, and add an option in
|
||||
`markdown.c` to turn on your extension.
|
||||
|
||||
* Note: Avoid using `[^abc]` character classes in the grammar, because
|
||||
they cause problems with non-ascii input. Instead, use: `( !'a' !'b'
|
||||
!'c' . )`
|
||||
|
||||
Acknowledgements
|
||||
================
|
||||
|
||||
Support for ODF output was added by Fletcher T. Penney.
|
||||
|
11
supportlibs/pegmarkdown/glib.h
Normal file
11
supportlibs/pegmarkdown/glib.h
Normal file
@ -0,0 +1,11 @@
|
||||
/*
|
||||
* glib.h
|
||||
* MultiMarkdown
|
||||
*
|
||||
* Created by Daniel Jalkut on 7/26/11.
|
||||
* Copyright 2011 __MyCompanyName__. All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
/* Just a dummy file to keep the glib-dependent sources compiling as we would hope */
|
||||
#include "GLibFacade.h"
|
183
supportlibs/pegmarkdown/markdown.c
Normal file
183
supportlibs/pegmarkdown/markdown.c
Normal file
@ -0,0 +1,183 @@
|
||||
/**********************************************************************
|
||||
|
||||
markdown.c - markdown in C using a PEG grammar.
|
||||
(c) 2008 John MacFarlane (jgm at berkeley dot edu).
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License or the MIT
|
||||
license. See LICENSE for details.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <glib.h>
|
||||
#include "markdown_peg.h"
|
||||
|
||||
static int extensions;
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
The main program is just a wrapper around the library functions in
|
||||
markdown_lib.c. It parses command-line options, reads the text to
|
||||
be converted from input files or stdin, converts the text, and sends
|
||||
the output to stdout or a file. Character encodings are ignored.
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#define VERSION "0.4.14"
|
||||
#define COPYRIGHT "Copyright (c) 2008-2009 John MacFarlane. License GPLv2+ or MIT.\n" \
|
||||
"This is free software: you are free to change and redistribute it.\n" \
|
||||
"There is NO WARRANTY, to the extent permitted by law."
|
||||
|
||||
/* print version and copyright information */
|
||||
void version(const char *progname)
|
||||
{
|
||||
printf("peg-markdown version %s\n"
|
||||
"%s\n",
|
||||
VERSION,
|
||||
COPYRIGHT);
|
||||
}
|
||||
|
||||
int main(int argc, char * argv[]) {
|
||||
|
||||
int numargs; /* number of filename arguments */
|
||||
int i;
|
||||
|
||||
GString *inputbuf;
|
||||
char *out; /* string containing processed output */
|
||||
|
||||
FILE *input;
|
||||
FILE *output;
|
||||
char curchar;
|
||||
char *progname = argv[0];
|
||||
|
||||
int output_format = HTML_FORMAT;
|
||||
|
||||
/* Code for command-line option parsing. */
|
||||
|
||||
static gboolean opt_version = FALSE;
|
||||
static gchar *opt_output = 0;
|
||||
static gchar *opt_to = 0;
|
||||
static gboolean opt_smart = FALSE;
|
||||
static gboolean opt_notes = FALSE;
|
||||
static gboolean opt_filter_html = FALSE;
|
||||
static gboolean opt_filter_styles = FALSE;
|
||||
static gboolean opt_allext = FALSE;
|
||||
|
||||
static GOptionEntry entries[] =
|
||||
{
|
||||
{ "version", 'v', 0, G_OPTION_ARG_NONE, &opt_version, "print version and exit", NULL },
|
||||
{ "output", 'o', 0, G_OPTION_ARG_STRING, &opt_output, "send output to FILE (default is stdout)", "FILE" },
|
||||
{ "to", 't', 0, G_OPTION_ARG_STRING, &opt_to, "convert to FORMAT (default is html)", "FORMAT" },
|
||||
{ "extensions", 'x', 0, G_OPTION_ARG_NONE, &opt_allext, "use all syntax extensions", NULL },
|
||||
{ "filter-html", 0, 0, G_OPTION_ARG_NONE, &opt_filter_html, "filter out raw HTML (except styles)", NULL },
|
||||
{ "filter-styles", 0, 0, G_OPTION_ARG_NONE, &opt_filter_styles, "filter out HTML styles", NULL },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
/* Options to active syntax extensions. These appear separately in --help. */
|
||||
static GOptionEntry ext_entries[] =
|
||||
{
|
||||
{ "smart", 0, 0, G_OPTION_ARG_NONE, &opt_smart, "use smart typography extension", NULL },
|
||||
{ "notes", 0, 0, G_OPTION_ARG_NONE, &opt_notes, "use notes extension", NULL },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
GError *error = NULL;
|
||||
GOptionContext *context;
|
||||
GOptionGroup *ext_group;
|
||||
|
||||
context = g_option_context_new ("[FILE...]");
|
||||
g_option_context_add_main_entries (context, entries, NULL);
|
||||
ext_group = g_option_group_new ("extensions", "Syntax extensions", "show available syntax extensions", NULL, NULL);
|
||||
g_option_group_add_entries (ext_group, ext_entries);
|
||||
g_option_context_add_group (context, ext_group);
|
||||
g_option_context_set_description (context, "Converts text in specified files (or stdin) from markdown to FORMAT.\n"
|
||||
"Available FORMATs: html, latex, groff-mm, odf");
|
||||
if (!g_option_context_parse (context, &argc, &argv, &error)) {
|
||||
g_print ("option parsing failed: %s\n", error->message);
|
||||
exit (1);
|
||||
}
|
||||
g_option_context_free(context);
|
||||
|
||||
/* Process command-line options and arguments. */
|
||||
|
||||
if (opt_version) {
|
||||
version(progname);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
extensions = 0;
|
||||
if (opt_allext)
|
||||
extensions = 0xFFFFFF; /* turn on all extensions */
|
||||
if (opt_smart)
|
||||
extensions = extensions | EXT_SMART;
|
||||
if (opt_notes)
|
||||
extensions = extensions | EXT_NOTES;
|
||||
if (opt_filter_html)
|
||||
extensions = extensions | EXT_FILTER_HTML;
|
||||
if (opt_filter_styles)
|
||||
extensions = extensions | EXT_FILTER_STYLES;
|
||||
|
||||
if (opt_to == NULL)
|
||||
output_format = HTML_FORMAT;
|
||||
else if (strcmp(opt_to, "html") == 0)
|
||||
output_format = HTML_FORMAT;
|
||||
else if (strcmp(opt_to, "latex") == 0)
|
||||
output_format = LATEX_FORMAT;
|
||||
else if (strcmp(opt_to, "groff-mm") == 0)
|
||||
output_format = GROFF_MM_FORMAT;
|
||||
else if (strcmp(opt_to, "odf") == 0)
|
||||
output_format = ODF_FORMAT;
|
||||
else {
|
||||
fprintf(stderr, "%s: Unknown output format '%s'\n", progname, opt_to);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* we allow "-" as a synonym for stdout here */
|
||||
if (opt_output == NULL || strcmp(opt_output, "-") == 0)
|
||||
output = stdout;
|
||||
else if (!(output = fopen(opt_output, "w"))) {
|
||||
perror(opt_output);
|
||||
return 1;
|
||||
}
|
||||
|
||||
inputbuf = g_string_new(""); /* string for concatenated input */
|
||||
|
||||
/* Read input from stdin or input files into inputbuf */
|
||||
|
||||
numargs = argc - 1;
|
||||
if (numargs == 0) { /* use stdin if no files specified */
|
||||
while ((curchar = fgetc(stdin)) != EOF)
|
||||
g_string_append_c(inputbuf, curchar);
|
||||
fclose(stdin);
|
||||
}
|
||||
else { /* open all the files on command line */
|
||||
for (i = 0; i < numargs; i++) {
|
||||
if ((input = fopen(argv[i+1], "r")) == NULL) {
|
||||
perror(argv[i+1]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
while ((curchar = fgetc(input)) != EOF)
|
||||
g_string_append_c(inputbuf, curchar);
|
||||
fclose(input);
|
||||
}
|
||||
}
|
||||
|
||||
out = markdown_to_string(inputbuf->str, extensions, output_format);
|
||||
fprintf(output, "%s\n", out);
|
||||
free(out);
|
||||
|
||||
g_string_free(inputbuf, true);
|
||||
|
||||
return(EXIT_SUCCESS);
|
||||
}
|
181
supportlibs/pegmarkdown/markdown_lib.c
Normal file
181
supportlibs/pegmarkdown/markdown_lib.c
Normal file
@ -0,0 +1,181 @@
|
||||
/**********************************************************************
|
||||
|
||||
markdown_lib.c - markdown in C using a PEG grammar.
|
||||
(c) 2008 John MacFarlane (jgm at berkeley dot edu).
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License or the MIT
|
||||
license. See LICENSE for details.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "markdown_peg.h"
|
||||
|
||||
#define TABSTOP 4
|
||||
|
||||
/* preformat_text - allocate and copy text buffer while
|
||||
* performing tab expansion. */
|
||||
static GString *preformat_text(char *text) {
|
||||
GString *buf;
|
||||
char next_char;
|
||||
int charstotab;
|
||||
|
||||
int len = 0;
|
||||
|
||||
buf = g_string_new("");
|
||||
|
||||
charstotab = TABSTOP;
|
||||
while ((next_char = *text++) != '\0') {
|
||||
switch (next_char) {
|
||||
case '\t':
|
||||
while (charstotab > 0)
|
||||
g_string_append_c(buf, ' '), len++, charstotab--;
|
||||
break;
|
||||
case '\n':
|
||||
g_string_append_c(buf, '\n'), len++, charstotab = TABSTOP;
|
||||
break;
|
||||
default:
|
||||
g_string_append_c(buf, next_char), len++, charstotab--;
|
||||
}
|
||||
if (charstotab == 0)
|
||||
charstotab = TABSTOP;
|
||||
}
|
||||
g_string_append(buf, "\n\n");
|
||||
return(buf);
|
||||
}
|
||||
|
||||
/* print_tree - print tree of elements, for debugging only. */
|
||||
static void print_tree(element * elt, int indent) {
|
||||
int i;
|
||||
char * key;
|
||||
while (elt != NULL) {
|
||||
for (i = 0; i < indent; i++)
|
||||
fputc(' ', stderr);
|
||||
switch (elt->key) {
|
||||
case LIST: key = "LIST"; break;
|
||||
case RAW: key = "RAW"; break;
|
||||
case SPACE: key = "SPACE"; break;
|
||||
case LINEBREAK: key = "LINEBREAK"; break;
|
||||
case ELLIPSIS: key = "ELLIPSIS"; break;
|
||||
case EMDASH: key = "EMDASH"; break;
|
||||
case ENDASH: key = "ENDASH"; break;
|
||||
case APOSTROPHE: key = "APOSTROPHE"; break;
|
||||
case SINGLEQUOTED: key = "SINGLEQUOTED"; break;
|
||||
case DOUBLEQUOTED: key = "DOUBLEQUOTED"; break;
|
||||
case STR: key = "STR"; break;
|
||||
case LINK: key = "LINK"; break;
|
||||
case IMAGE: key = "IMAGE"; break;
|
||||
case CODE: key = "CODE"; break;
|
||||
case HTML: key = "HTML"; break;
|
||||
case EMPH: key = "EMPH"; break;
|
||||
case STRONG: key = "STRONG"; break;
|
||||
case PLAIN: key = "PLAIN"; break;
|
||||
case PARA: key = "PARA"; break;
|
||||
case LISTITEM: key = "LISTITEM"; break;
|
||||
case BULLETLIST: key = "BULLETLIST"; break;
|
||||
case ORDEREDLIST: key = "ORDEREDLIST"; break;
|
||||
case H1: key = "H1"; break;
|
||||
case H2: key = "H2"; break;
|
||||
case H3: key = "H3"; break;
|
||||
case H4: key = "H4"; break;
|
||||
case H5: key = "H5"; break;
|
||||
case H6: key = "H6"; break;
|
||||
case BLOCKQUOTE: key = "BLOCKQUOTE"; break;
|
||||
case VERBATIM: key = "VERBATIM"; break;
|
||||
case HTMLBLOCK: key = "HTMLBLOCK"; break;
|
||||
case HRULE: key = "HRULE"; break;
|
||||
case REFERENCE: key = "REFERENCE"; break;
|
||||
case NOTE: key = "NOTE"; break;
|
||||
default: key = "?";
|
||||
}
|
||||
if ( elt->key == STR ) {
|
||||
fprintf(stderr, "0x%p: %s '%s'\n", (void *)elt, key, elt->contents.str);
|
||||
} else {
|
||||
fprintf(stderr, "0x%p: %s\n", (void *)elt, key);
|
||||
}
|
||||
if (elt->children)
|
||||
print_tree(elt->children, indent + 4);
|
||||
elt = elt->next;
|
||||
}
|
||||
}
|
||||
|
||||
/* process_raw_blocks - traverses an element list, replacing any RAW elements with
|
||||
* the result of parsing them as markdown text, and recursing into the children
|
||||
* of parent elements. The result should be a tree of elements without any RAWs. */
|
||||
static element * process_raw_blocks(element *input, int extensions, element *references, element *notes) {
|
||||
element *current = NULL;
|
||||
element *last_child = NULL;
|
||||
char *contents;
|
||||
current = input;
|
||||
|
||||
while (current != NULL) {
|
||||
if (current->key == RAW) {
|
||||
/* \001 is used to indicate boundaries between nested lists when there
|
||||
* is no blank line. We split the string by \001 and parse
|
||||
* each chunk separately. */
|
||||
contents = strtok(current->contents.str, "\001");
|
||||
current->key = LIST;
|
||||
current->children = parse_markdown(contents, extensions, references, notes);
|
||||
last_child = current->children;
|
||||
while ((contents = strtok(NULL, "\001"))) {
|
||||
while (last_child->next != NULL)
|
||||
last_child = last_child->next;
|
||||
last_child->next = parse_markdown(contents, extensions, references, notes);
|
||||
}
|
||||
free(current->contents.str);
|
||||
current->contents.str = NULL;
|
||||
}
|
||||
if (current->children != NULL)
|
||||
current->children = process_raw_blocks(current->children, extensions, references, notes);
|
||||
current = current->next;
|
||||
}
|
||||
return input;
|
||||
}
|
||||
|
||||
/* markdown_to_gstring - convert markdown text to the output format specified.
|
||||
* Returns a GString, which must be freed after use using g_string_free(). */
|
||||
GString * markdown_to_g_string(char *text, int extensions, int output_format) {
|
||||
element *result;
|
||||
element *references;
|
||||
element *notes;
|
||||
GString *formatted_text;
|
||||
GString *out;
|
||||
out = g_string_new("");
|
||||
|
||||
formatted_text = preformat_text(text);
|
||||
|
||||
references = parse_references(formatted_text->str, extensions);
|
||||
notes = parse_notes(formatted_text->str, extensions, references);
|
||||
result = parse_markdown(formatted_text->str, extensions, references, notes);
|
||||
|
||||
result = process_raw_blocks(result, extensions, references, notes);
|
||||
|
||||
g_string_free(formatted_text, TRUE);
|
||||
|
||||
print_element_list(out, result, output_format, extensions);
|
||||
|
||||
free_element_list(result);
|
||||
free_element_list(references);
|
||||
return out;
|
||||
}
|
||||
|
||||
/* markdown_to_string - convert markdown text to the output format specified.
|
||||
* Returns a null-terminated string, which must be freed after use. */
|
||||
char * markdown_to_string(char *text, int extensions, int output_format) {
|
||||
GString *out;
|
||||
char *char_out;
|
||||
out = markdown_to_g_string(text, extensions, output_format);
|
||||
char_out = out->str;
|
||||
g_string_free(out, FALSE);
|
||||
return char_out;
|
||||
}
|
||||
|
||||
/* vim:set ts=4 sw=4: */
|
38
supportlibs/pegmarkdown/markdown_lib.h
Normal file
38
supportlibs/pegmarkdown/markdown_lib.h
Normal file
@ -0,0 +1,38 @@
|
||||
#ifndef MARKDOWN_LIB_H
|
||||
#define MARKDOWN_LIB_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <glib.h>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
enum markdown_extensions {
|
||||
EXT_SMART = 0x01,
|
||||
EXT_NOTES = 0x02,
|
||||
EXT_FILTER_HTML = 0x04,
|
||||
EXT_FILTER_STYLES = 0x08
|
||||
};
|
||||
|
||||
enum markdown_formats {
|
||||
HTML_FORMAT,
|
||||
LATEX_FORMAT,
|
||||
GROFF_MM_FORMAT,
|
||||
ODF_FORMAT
|
||||
};
|
||||
|
||||
GString * markdown_to_g_string(char *text, int extensions, int output_format);
|
||||
char * markdown_to_string(char *text, int extensions, int output_format);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/* vim: set ts=4 sw=4 : */
|
||||
#endif
|
||||
|
1121
supportlibs/pegmarkdown/markdown_output.c
Normal file
1121
supportlibs/pegmarkdown/markdown_output.c
Normal file
File diff suppressed because it is too large
Load Diff
6665
supportlibs/pegmarkdown/markdown_parser.c
Normal file
6665
supportlibs/pegmarkdown/markdown_parser.c
Normal file
File diff suppressed because it is too large
Load Diff
770
supportlibs/pegmarkdown/markdown_parser.leg
Normal file
770
supportlibs/pegmarkdown/markdown_parser.leg
Normal file
@ -0,0 +1,770 @@
|
||||
%{
|
||||
/**********************************************************************
|
||||
|
||||
markdown_parser.leg - markdown parser in C using a PEG grammar.
|
||||
(c) 2008 John MacFarlane (jgm at berkeley dot edu).
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License or the MIT
|
||||
license. See LICENSE for details.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
#include "markdown_peg.h"
|
||||
#include "utility_functions.h"
|
||||
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
Definitions for leg parser generator.
|
||||
YY_INPUT is the function the parser calls to get new input.
|
||||
We take all new input from (static) charbuf.
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
|
||||
|
||||
# define YYSTYPE element *
|
||||
#ifdef __DEBUG__
|
||||
# define YY_DEBUG 1
|
||||
#endif
|
||||
|
||||
#define YY_INPUT(buf, result, max_size) \
|
||||
{ \
|
||||
int yyc; \
|
||||
if (charbuf && *charbuf != '\0') { \
|
||||
yyc= *charbuf++; \
|
||||
} else { \
|
||||
yyc= EOF; \
|
||||
} \
|
||||
result= (EOF == yyc) ? 0 : (*(buf)= yyc, 1); \
|
||||
}
|
||||
|
||||
#define YY_RULE(T) T
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
|
||||
PEG grammar and parser actions for markdown syntax.
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
%}
|
||||
|
||||
Doc = BOM? a:StartList ( Block { a = cons($$, a); } )*
|
||||
{ parse_result = reverse(a); }
|
||||
|
||||
Block = BlankLine*
|
||||
( BlockQuote
|
||||
| Verbatim
|
||||
| Note
|
||||
| Reference
|
||||
| HorizontalRule
|
||||
| Heading
|
||||
| OrderedList
|
||||
| BulletList
|
||||
| HtmlBlock
|
||||
| StyleBlock
|
||||
| Para
|
||||
| Plain )
|
||||
|
||||
Para = NonindentSpace a:Inlines BlankLine+
|
||||
{ $$ = a; $$->key = PARA; }
|
||||
|
||||
Plain = a:Inlines
|
||||
{ $$ = a; $$->key = PLAIN; }
|
||||
|
||||
AtxInline = !Newline !(Sp? '#'* Sp Newline) Inline
|
||||
|
||||
AtxStart = < ( "######" | "#####" | "####" | "###" | "##" | "#" ) >
|
||||
{ $$ = mk_element(H1 + (strlen(yytext) - 1)); }
|
||||
|
||||
AtxHeading = s:AtxStart Sp? a:StartList ( AtxInline { a = cons($$, a); } )+ (Sp? '#'* Sp)? Newline
|
||||
{ $$ = mk_list(s->key, a);
|
||||
free(s); }
|
||||
|
||||
SetextHeading = SetextHeading1 | SetextHeading2
|
||||
|
||||
SetextBottom1 = '='+ Newline
|
||||
|
||||
SetextBottom2 = '-'+ Newline
|
||||
|
||||
SetextHeading1 = &(RawLine SetextBottom1)
|
||||
a:StartList ( !Endline Inline { a = cons($$, a); } )+ Sp? Newline
|
||||
SetextBottom1 { $$ = mk_list(H1, a); }
|
||||
|
||||
SetextHeading2 = &(RawLine SetextBottom2)
|
||||
a:StartList ( !Endline Inline { a = cons($$, a); } )+ Sp? Newline
|
||||
SetextBottom2 { $$ = mk_list(H2, a); }
|
||||
|
||||
Heading = SetextHeading | AtxHeading
|
||||
|
||||
BlockQuote = a:BlockQuoteRaw
|
||||
{ $$ = mk_element(BLOCKQUOTE);
|
||||
$$->children = a;
|
||||
}
|
||||
|
||||
BlockQuoteRaw = a:StartList
|
||||
(( '>' ' '? Line { a = cons($$, a); } )
|
||||
( !'>' !BlankLine Line { a = cons($$, a); } )*
|
||||
( BlankLine { a = cons(mk_str("\n"), a); } )*
|
||||
)+
|
||||
{ $$ = mk_str_from_list(a, true);
|
||||
$$->key = RAW;
|
||||
}
|
||||
|
||||
NonblankIndentedLine = !BlankLine IndentedLine
|
||||
|
||||
VerbatimChunk = a:StartList
|
||||
( BlankLine { a = cons(mk_str("\n"), a); } )*
|
||||
( NonblankIndentedLine { a = cons($$, a); } )+
|
||||
{ $$ = mk_str_from_list(a, false); }
|
||||
|
||||
Verbatim = a:StartList ( VerbatimChunk { a = cons($$, a); } )+
|
||||
{ $$ = mk_str_from_list(a, false);
|
||||
$$->key = VERBATIM; }
|
||||
|
||||
HorizontalRule = NonindentSpace
|
||||
( '*' Sp '*' Sp '*' (Sp '*')*
|
||||
| '-' Sp '-' Sp '-' (Sp '-')*
|
||||
| '_' Sp '_' Sp '_' (Sp '_')*)
|
||||
Sp Newline BlankLine+
|
||||
{ $$ = mk_element(HRULE); }
|
||||
|
||||
Bullet = !HorizontalRule NonindentSpace ('+' | '*' | '-') Spacechar+
|
||||
|
||||
BulletList = &Bullet (ListTight | ListLoose)
|
||||
{ $$->key = BULLETLIST; }
|
||||
|
||||
ListTight = a:StartList
|
||||
( ListItemTight { a = cons($$, a); } )+
|
||||
BlankLine* !(Bullet | Enumerator)
|
||||
{ $$ = mk_list(LIST, a); }
|
||||
|
||||
ListLoose = a:StartList
|
||||
( b:ListItem BlankLine*
|
||||
{ element *li;
|
||||
li = b->children;
|
||||
li->contents.str = realloc(li->contents.str, strlen(li->contents.str) + 3);
|
||||
strcat(li->contents.str, "\n\n"); /* In loose list, \n\n added to end of each element */
|
||||
a = cons(b, a);
|
||||
} )+
|
||||
{ $$ = mk_list(LIST, a); }
|
||||
|
||||
ListItem = ( Bullet | Enumerator )
|
||||
a:StartList
|
||||
ListBlock { a = cons($$, a); }
|
||||
( ListContinuationBlock { a = cons($$, a); } )*
|
||||
{ element *raw;
|
||||
raw = mk_str_from_list(a, false);
|
||||
raw->key = RAW;
|
||||
$$ = mk_element(LISTITEM);
|
||||
$$->children = raw;
|
||||
}
|
||||
|
||||
ListItemTight =
|
||||
( Bullet | Enumerator )
|
||||
a:StartList
|
||||
ListBlock { a = cons($$, a); }
|
||||
( !BlankLine
|
||||
ListContinuationBlock { a = cons($$, a); } )*
|
||||
!ListContinuationBlock
|
||||
{ element *raw;
|
||||
raw = mk_str_from_list(a, false);
|
||||
raw->key = RAW;
|
||||
$$ = mk_element(LISTITEM);
|
||||
$$->children = raw;
|
||||
}
|
||||
|
||||
ListBlock = a:StartList
|
||||
!BlankLine Line { a = cons($$, a); }
|
||||
( ListBlockLine { a = cons($$, a); } )*
|
||||
{ $$ = mk_str_from_list(a, false); }
|
||||
|
||||
ListContinuationBlock = a:StartList
|
||||
( < BlankLine* >
|
||||
{ if (strlen(yytext) == 0)
|
||||
a = cons(mk_str("\001"), a); /* block separator */
|
||||
else
|
||||
a = cons(mk_str(yytext), a); } )
|
||||
( Indent ListBlock { a = cons($$, a); } )+
|
||||
{ $$ = mk_str_from_list(a, false); }
|
||||
|
||||
Enumerator = NonindentSpace [0-9]+ '.' Spacechar+
|
||||
|
||||
OrderedList = &Enumerator (ListTight | ListLoose)
|
||||
{ $$->key = ORDEREDLIST; }
|
||||
|
||||
ListBlockLine = !BlankLine
|
||||
!( Indent? (Bullet | Enumerator) )
|
||||
!HorizontalRule
|
||||
OptionallyIndentedLine
|
||||
|
||||
# Parsers for different kinds of block-level HTML content.
|
||||
# This is repetitive due to constraints of PEG grammar.
|
||||
|
||||
HtmlBlockOpenAddress = '<' Spnl ("address" | "ADDRESS") Spnl HtmlAttribute* '>'
|
||||
HtmlBlockCloseAddress = '<' Spnl '/' ("address" | "ADDRESS") Spnl '>'
|
||||
HtmlBlockAddress = HtmlBlockOpenAddress (HtmlBlockAddress | !HtmlBlockCloseAddress .)* HtmlBlockCloseAddress
|
||||
|
||||
HtmlBlockOpenBlockquote = '<' Spnl ("blockquote" | "BLOCKQUOTE") Spnl HtmlAttribute* '>'
|
||||
HtmlBlockCloseBlockquote = '<' Spnl '/' ("blockquote" | "BLOCKQUOTE") Spnl '>'
|
||||
HtmlBlockBlockquote = HtmlBlockOpenBlockquote (HtmlBlockBlockquote | !HtmlBlockCloseBlockquote .)* HtmlBlockCloseBlockquote
|
||||
|
||||
HtmlBlockOpenCenter = '<' Spnl ("center" | "CENTER") Spnl HtmlAttribute* '>'
|
||||
HtmlBlockCloseCenter = '<' Spnl '/' ("center" | "CENTER") Spnl '>'
|
||||
HtmlBlockCenter = HtmlBlockOpenCenter (HtmlBlockCenter | !HtmlBlockCloseCenter .)* HtmlBlockCloseCenter
|
||||
|
||||
HtmlBlockOpenDir = '<' Spnl ("dir" | "DIR") Spnl HtmlAttribute* '>'
|
||||
HtmlBlockCloseDir = '<' Spnl '/' ("dir" | "DIR") Spnl '>'
|
||||
HtmlBlockDir = HtmlBlockOpenDir (HtmlBlockDir | !HtmlBlockCloseDir .)* HtmlBlockCloseDir
|
||||
|
||||
HtmlBlockOpenDiv = '<' Spnl ("div" | "DIV") Spnl HtmlAttribute* '>'
|
||||
HtmlBlockCloseDiv = '<' Spnl '/' ("div" | "DIV") Spnl '>'
|
||||
HtmlBlockDiv = HtmlBlockOpenDiv (HtmlBlockDiv | !HtmlBlockCloseDiv .)* HtmlBlockCloseDiv
|
||||
|
||||
HtmlBlockOpenDl = '<' Spnl ("dl" | "DL") Spnl HtmlAttribute* '>'
|
||||
HtmlBlockCloseDl = '<' Spnl '/' ("dl" | "DL") Spnl '>'
|
||||
HtmlBlockDl = HtmlBlockOpenDl (HtmlBlockDl | !HtmlBlockCloseDl .)* HtmlBlockCloseDl
|
||||
|
||||
HtmlBlockOpenFieldset = '<' Spnl ("fieldset" | "FIELDSET") Spnl HtmlAttribute* '>'
|
||||
HtmlBlockCloseFieldset = '<' Spnl '/' ("fieldset" | "FIELDSET") Spnl '>'
|
||||
HtmlBlockFieldset = HtmlBlockOpenFieldset (HtmlBlockFieldset | !HtmlBlockCloseFieldset .)* HtmlBlockCloseFieldset
|
||||
|
||||
HtmlBlockOpenForm = '<' Spnl ("form" | "FORM") Spnl HtmlAttribute* '>'
|
||||
HtmlBlockCloseForm = '<' Spnl '/' ("form" | "FORM") Spnl '>'
|
||||
HtmlBlockForm = HtmlBlockOpenForm (HtmlBlockForm | !HtmlBlockCloseForm .)* HtmlBlockCloseForm
|
||||
|
||||
HtmlBlockOpenH1 = '<' Spnl ("h1" | "H1") Spnl HtmlAttribute* '>'
|
||||
HtmlBlockCloseH1 = '<' Spnl '/' ("h1" | "H1") Spnl '>'
|
||||
HtmlBlockH1 = HtmlBlockOpenH1 (HtmlBlockH1 | !HtmlBlockCloseH1 .)* HtmlBlockCloseH1
|
||||
|
||||
HtmlBlockOpenH2 = '<' Spnl ("h2" | "H2") Spnl HtmlAttribute* '>'
|
||||
HtmlBlockCloseH2 = '<' Spnl '/' ("h2" | "H2") Spnl '>'
|
||||
HtmlBlockH2 = HtmlBlockOpenH2 (HtmlBlockH2 | !HtmlBlockCloseH2 .)* HtmlBlockCloseH2
|
||||
|
||||
HtmlBlockOpenH3 = '<' Spnl ("h3" | "H3") Spnl HtmlAttribute* '>'
|
||||
HtmlBlockCloseH3 = '<' Spnl '/' ("h3" | "H3") Spnl '>'
|
||||
HtmlBlockH3 = HtmlBlockOpenH3 (HtmlBlockH3 | !HtmlBlockCloseH3 .)* HtmlBlockCloseH3
|
||||
|
||||
HtmlBlockOpenH4 = '<' Spnl ("h4" | "H4") Spnl HtmlAttribute* '>'
|
||||
HtmlBlockCloseH4 = '<' Spnl '/' ("h4" | "H4") Spnl '>'
|
||||
HtmlBlockH4 = HtmlBlockOpenH4 (HtmlBlockH4 | !HtmlBlockCloseH4 .)* HtmlBlockCloseH4
|
||||
|
||||
HtmlBlockOpenH5 = '<' Spnl ("h5" | "H5") Spnl HtmlAttribute* '>'
|
||||
HtmlBlockCloseH5 = '<' Spnl '/' ("h5" | "H5") Spnl '>'
|
||||
HtmlBlockH5 = HtmlBlockOpenH5 (HtmlBlockH5 | !HtmlBlockCloseH5 .)* HtmlBlockCloseH5
|
||||
|
||||
HtmlBlockOpenH6 = '<' Spnl ("h6" | "H6") Spnl HtmlAttribute* '>'
|
||||
HtmlBlockCloseH6 = '<' Spnl '/' ("h6" | "H6") Spnl '>'
|
||||
HtmlBlockH6 = HtmlBlockOpenH6 (HtmlBlockH6 | !HtmlBlockCloseH6 .)* HtmlBlockCloseH6
|
||||
|
||||
HtmlBlockOpenMenu = '<' Spnl ("menu" | "MENU") Spnl HtmlAttribute* '>'
|
||||
HtmlBlockCloseMenu = '<' Spnl '/' ("menu" | "MENU") Spnl '>'
|
||||
HtmlBlockMenu = HtmlBlockOpenMenu (HtmlBlockMenu | !HtmlBlockCloseMenu .)* HtmlBlockCloseMenu
|
||||
|
||||
HtmlBlockOpenNoframes = '<' Spnl ("noframes" | "NOFRAMES") Spnl HtmlAttribute* '>'
|
||||
HtmlBlockCloseNoframes = '<' Spnl '/' ("noframes" | "NOFRAMES") Spnl '>'
|
||||
HtmlBlockNoframes = HtmlBlockOpenNoframes (HtmlBlockNoframes | !HtmlBlockCloseNoframes .)* HtmlBlockCloseNoframes
|
||||
|
||||
HtmlBlockOpenNoscript = '<' Spnl ("noscript" | "NOSCRIPT") Spnl HtmlAttribute* '>'
|
||||
HtmlBlockCloseNoscript = '<' Spnl '/' ("noscript" | "NOSCRIPT") Spnl '>'
|
||||
HtmlBlockNoscript = HtmlBlockOpenNoscript (HtmlBlockNoscript | !HtmlBlockCloseNoscript .)* HtmlBlockCloseNoscript
|
||||
|
||||
HtmlBlockOpenOl = '<' Spnl ("ol" | "OL") Spnl HtmlAttribute* '>'
|
||||
HtmlBlockCloseOl = '<' Spnl '/' ("ol" | "OL") Spnl '>'
|
||||
HtmlBlockOl = HtmlBlockOpenOl (HtmlBlockOl | !HtmlBlockCloseOl .)* HtmlBlockCloseOl
|
||||
|
||||
HtmlBlockOpenP = '<' Spnl ("p" | "P") Spnl HtmlAttribute* '>'
|
||||
HtmlBlockCloseP = '<' Spnl '/' ("p" | "P") Spnl '>'
|
||||
HtmlBlockP = HtmlBlockOpenP (HtmlBlockP | !HtmlBlockCloseP .)* HtmlBlockCloseP
|
||||
|
||||
HtmlBlockOpenPre = '<' Spnl ("pre" | "PRE") Spnl HtmlAttribute* '>'
|
||||
HtmlBlockClosePre = '<' Spnl '/' ("pre" | "PRE") Spnl '>'
|
||||
HtmlBlockPre = HtmlBlockOpenPre (HtmlBlockPre | !HtmlBlockClosePre .)* HtmlBlockClosePre
|
||||
|
||||
HtmlBlockOpenTable = '<' Spnl ("table" | "TABLE") Spnl HtmlAttribute* '>'
|
||||
HtmlBlockCloseTable = '<' Spnl '/' ("table" | "TABLE") Spnl '>'
|
||||
HtmlBlockTable = HtmlBlockOpenTable (HtmlBlockTable | !HtmlBlockCloseTable .)* HtmlBlockCloseTable
|
||||
|
||||
HtmlBlockOpenUl = '<' Spnl ("ul" | "UL") Spnl HtmlAttribute* '>'
|
||||
HtmlBlockCloseUl = '<' Spnl '/' ("ul" | "UL") Spnl '>'
|
||||
HtmlBlockUl = HtmlBlockOpenUl (HtmlBlockUl | !HtmlBlockCloseUl .)* HtmlBlockCloseUl
|
||||
|
||||
HtmlBlockOpenDd = '<' Spnl ("dd" | "DD") Spnl HtmlAttribute* '>'
|
||||
HtmlBlockCloseDd = '<' Spnl '/' ("dd" | "DD") Spnl '>'
|
||||
HtmlBlockDd = HtmlBlockOpenDd (HtmlBlockDd | !HtmlBlockCloseDd .)* HtmlBlockCloseDd
|
||||
|
||||
HtmlBlockOpenDt = '<' Spnl ("dt" | "DT") Spnl HtmlAttribute* '>'
|
||||
HtmlBlockCloseDt = '<' Spnl '/' ("dt" | "DT") Spnl '>'
|
||||
HtmlBlockDt = HtmlBlockOpenDt (HtmlBlockDt | !HtmlBlockCloseDt .)* HtmlBlockCloseDt
|
||||
|
||||
HtmlBlockOpenFrameset = '<' Spnl ("frameset" | "FRAMESET") Spnl HtmlAttribute* '>'
|
||||
HtmlBlockCloseFrameset = '<' Spnl '/' ("frameset" | "FRAMESET") Spnl '>'
|
||||
HtmlBlockFrameset = HtmlBlockOpenFrameset (HtmlBlockFrameset | !HtmlBlockCloseFrameset .)* HtmlBlockCloseFrameset
|
||||
|
||||
HtmlBlockOpenLi = '<' Spnl ("li" | "LI") Spnl HtmlAttribute* '>'
|
||||
HtmlBlockCloseLi = '<' Spnl '/' ("li" | "LI") Spnl '>'
|
||||
HtmlBlockLi = HtmlBlockOpenLi (HtmlBlockLi | !HtmlBlockCloseLi .)* HtmlBlockCloseLi
|
||||
|
||||
HtmlBlockOpenTbody = '<' Spnl ("tbody" | "TBODY") Spnl HtmlAttribute* '>'
|
||||
HtmlBlockCloseTbody = '<' Spnl '/' ("tbody" | "TBODY") Spnl '>'
|
||||
HtmlBlockTbody = HtmlBlockOpenTbody (HtmlBlockTbody | !HtmlBlockCloseTbody .)* HtmlBlockCloseTbody
|
||||
|
||||
HtmlBlockOpenTd = '<' Spnl ("td" | "TD") Spnl HtmlAttribute* '>'
|
||||
HtmlBlockCloseTd = '<' Spnl '/' ("td" | "TD") Spnl '>'
|
||||
HtmlBlockTd = HtmlBlockOpenTd (HtmlBlockTd | !HtmlBlockCloseTd .)* HtmlBlockCloseTd
|
||||
|
||||
HtmlBlockOpenTfoot = '<' Spnl ("tfoot" | "TFOOT") Spnl HtmlAttribute* '>'
|
||||
HtmlBlockCloseTfoot = '<' Spnl '/' ("tfoot" | "TFOOT") Spnl '>'
|
||||
HtmlBlockTfoot = HtmlBlockOpenTfoot (HtmlBlockTfoot | !HtmlBlockCloseTfoot .)* HtmlBlockCloseTfoot
|
||||
|
||||
HtmlBlockOpenTh = '<' Spnl ("th" | "TH") Spnl HtmlAttribute* '>'
|
||||
HtmlBlockCloseTh = '<' Spnl '/' ("th" | "TH") Spnl '>'
|
||||
HtmlBlockTh = HtmlBlockOpenTh (HtmlBlockTh | !HtmlBlockCloseTh .)* HtmlBlockCloseTh
|
||||
|
||||
HtmlBlockOpenThead = '<' Spnl ("thead" | "THEAD") Spnl HtmlAttribute* '>'
|
||||
HtmlBlockCloseThead = '<' Spnl '/' ("thead" | "THEAD") Spnl '>'
|
||||
HtmlBlockThead = HtmlBlockOpenThead (HtmlBlockThead | !HtmlBlockCloseThead .)* HtmlBlockCloseThead
|
||||
|
||||
HtmlBlockOpenTr = '<' Spnl ("tr" | "TR") Spnl HtmlAttribute* '>'
|
||||
HtmlBlockCloseTr = '<' Spnl '/' ("tr" | "TR") Spnl '>'
|
||||
HtmlBlockTr = HtmlBlockOpenTr (HtmlBlockTr | !HtmlBlockCloseTr .)* HtmlBlockCloseTr
|
||||
|
||||
HtmlBlockOpenScript = '<' Spnl ("script" | "SCRIPT") Spnl HtmlAttribute* '>'
|
||||
HtmlBlockCloseScript = '<' Spnl '/' ("script" | "SCRIPT") Spnl '>'
|
||||
HtmlBlockScript = HtmlBlockOpenScript (!HtmlBlockCloseScript .)* HtmlBlockCloseScript
|
||||
|
||||
|
||||
HtmlBlockInTags = HtmlBlockAddress
|
||||
| HtmlBlockBlockquote
|
||||
| HtmlBlockCenter
|
||||
| HtmlBlockDir
|
||||
| HtmlBlockDiv
|
||||
| HtmlBlockDl
|
||||
| HtmlBlockFieldset
|
||||
| HtmlBlockForm
|
||||
| HtmlBlockH1
|
||||
| HtmlBlockH2
|
||||
| HtmlBlockH3
|
||||
| HtmlBlockH4
|
||||
| HtmlBlockH5
|
||||
| HtmlBlockH6
|
||||
| HtmlBlockMenu
|
||||
| HtmlBlockNoframes
|
||||
| HtmlBlockNoscript
|
||||
| HtmlBlockOl
|
||||
| HtmlBlockP
|
||||
| HtmlBlockPre
|
||||
| HtmlBlockTable
|
||||
| HtmlBlockUl
|
||||
| HtmlBlockDd
|
||||
| HtmlBlockDt
|
||||
| HtmlBlockFrameset
|
||||
| HtmlBlockLi
|
||||
| HtmlBlockTbody
|
||||
| HtmlBlockTd
|
||||
| HtmlBlockTfoot
|
||||
| HtmlBlockTh
|
||||
| HtmlBlockThead
|
||||
| HtmlBlockTr
|
||||
| HtmlBlockScript
|
||||
|
||||
HtmlBlock = < ( HtmlBlockInTags | HtmlComment | HtmlBlockSelfClosing ) >
|
||||
BlankLine+
|
||||
{ if (extension(EXT_FILTER_HTML)) {
|
||||
$$ = mk_list(LIST, NULL);
|
||||
} else {
|
||||
$$ = mk_str(yytext);
|
||||
$$->key = HTMLBLOCK;
|
||||
}
|
||||
}
|
||||
|
||||
HtmlBlockSelfClosing = '<' Spnl HtmlBlockType Spnl HtmlAttribute* '/' Spnl '>'
|
||||
|
||||
HtmlBlockType = "address" | "blockquote" | "center" | "dir" | "div" | "dl" | "fieldset" | "form" | "h1" | "h2" | "h3" |
|
||||
"h4" | "h5" | "h6" | "hr" | "isindex" | "menu" | "noframes" | "noscript" | "ol" | "p" | "pre" | "table" |
|
||||
"ul" | "dd" | "dt" | "frameset" | "li" | "tbody" | "td" | "tfoot" | "th" | "thead" | "tr" | "script" |
|
||||
"ADDRESS" | "BLOCKQUOTE" | "CENTER" | "DIR" | "DIV" | "DL" | "FIELDSET" | "FORM" | "H1" | "H2" | "H3" |
|
||||
"H4" | "H5" | "H6" | "HR" | "ISINDEX" | "MENU" | "NOFRAMES" | "NOSCRIPT" | "OL" | "P" | "PRE" | "TABLE" |
|
||||
"UL" | "DD" | "DT" | "FRAMESET" | "LI" | "TBODY" | "TD" | "TFOOT" | "TH" | "THEAD" | "TR" | "SCRIPT"
|
||||
|
||||
StyleOpen = '<' Spnl ("style" | "STYLE") Spnl HtmlAttribute* '>'
|
||||
StyleClose = '<' Spnl '/' ("style" | "STYLE") Spnl '>'
|
||||
InStyleTags = StyleOpen (!StyleClose .)* StyleClose
|
||||
StyleBlock = < InStyleTags >
|
||||
BlankLine*
|
||||
{ if (extension(EXT_FILTER_STYLES)) {
|
||||
$$ = mk_list(LIST, NULL);
|
||||
} else {
|
||||
$$ = mk_str(yytext);
|
||||
$$->key = HTMLBLOCK;
|
||||
}
|
||||
}
|
||||
|
||||
Inlines = a:StartList ( !Endline Inline { a = cons($$, a); }
|
||||
| c:Endline &Inline { a = cons(c, a); } )+ Endline?
|
||||
{ $$ = mk_list(LIST, a); }
|
||||
|
||||
Inline = Str
|
||||
| Endline
|
||||
| UlOrStarLine
|
||||
| Space
|
||||
| Strong
|
||||
| Emph
|
||||
| Image
|
||||
| Link
|
||||
| NoteReference
|
||||
| InlineNote
|
||||
| Code
|
||||
| RawHtml
|
||||
| Entity
|
||||
| EscapedChar
|
||||
| Smart
|
||||
| Symbol
|
||||
|
||||
Space = Spacechar+
|
||||
{ $$ = mk_str(" ");
|
||||
$$->key = SPACE; }
|
||||
|
||||
Str = a:StartList < NormalChar+ > { a = cons(mk_str(yytext), a); }
|
||||
( StrChunk { a = cons($$, a); } )*
|
||||
{ if (a->next == NULL) { $$ = a; } else { $$ = mk_list(LIST, a); } }
|
||||
|
||||
StrChunk = < (NormalChar | '_'+ &Alphanumeric)+ > { $$ = mk_str(yytext); } |
|
||||
AposChunk
|
||||
|
||||
AposChunk = &{ extension(EXT_SMART) } '\'' &Alphanumeric
|
||||
{ $$ = mk_element(APOSTROPHE); }
|
||||
|
||||
EscapedChar = '\\' !Newline < [-\\`|*_{}[\]()#+.!><] >
|
||||
{ $$ = mk_str(yytext); }
|
||||
|
||||
Entity = ( HexEntity | DecEntity | CharEntity )
|
||||
{ $$ = mk_str(yytext); $$->key = HTML; }
|
||||
|
||||
Endline = LineBreak | TerminalEndline | NormalEndline
|
||||
|
||||
NormalEndline = Sp Newline !BlankLine !'>' !AtxStart
|
||||
!(Line ('='+ | '-'+) Newline)
|
||||
{ $$ = mk_str("\n");
|
||||
$$->key = SPACE; }
|
||||
|
||||
TerminalEndline = Sp Newline Eof
|
||||
{ $$ = NULL; }
|
||||
|
||||
LineBreak = " " NormalEndline
|
||||
{ $$ = mk_element(LINEBREAK); }
|
||||
|
||||
Symbol = < SpecialChar >
|
||||
{ $$ = mk_str(yytext); }
|
||||
|
||||
# This keeps the parser from getting bogged down on long strings of '*' or '_',
|
||||
# or strings of '*' or '_' with space on each side:
|
||||
UlOrStarLine = (UlLine | StarLine) { $$ = mk_str(yytext); }
|
||||
StarLine = < "****" '*'* > | < Spacechar '*'+ &Spacechar >
|
||||
UlLine = < "____" '_'* > | < Spacechar '_'+ &Spacechar >
|
||||
|
||||
Emph = EmphStar | EmphUl
|
||||
|
||||
Whitespace = Spacechar | Newline
|
||||
|
||||
EmphStar = '*' !Whitespace
|
||||
a:StartList
|
||||
( !'*' b:Inline { a = cons(b, a); }
|
||||
| b:StrongStar { a = cons(b, a); }
|
||||
)+
|
||||
'*'
|
||||
{ $$ = mk_list(EMPH, a); }
|
||||
|
||||
EmphUl = '_' !Whitespace
|
||||
a:StartList
|
||||
( !'_' b:Inline { a = cons(b, a); }
|
||||
| b:StrongUl { a = cons(b, a); }
|
||||
)+
|
||||
'_'
|
||||
{ $$ = mk_list(EMPH, a); }
|
||||
|
||||
Strong = StrongStar | StrongUl
|
||||
|
||||
StrongStar = "**" !Whitespace
|
||||
a:StartList
|
||||
( !"**" b:Inline { a = cons(b, a); })+
|
||||
"**"
|
||||
{ $$ = mk_list(STRONG, a); }
|
||||
|
||||
StrongUl = "__" !Whitespace
|
||||
a:StartList
|
||||
( !"__" b:Inline { a = cons(b, a); })+
|
||||
"__"
|
||||
{ $$ = mk_list(STRONG, a); }
|
||||
|
||||
Image = '!' ( ExplicitLink | ReferenceLink )
|
||||
{ if ($$->key == LINK) {
|
||||
$$->key = IMAGE;
|
||||
} else {
|
||||
element *result;
|
||||
result = $$;
|
||||
$$->children = cons(mk_str("!"), result->children);
|
||||
} }
|
||||
|
||||
Link = ExplicitLink | ReferenceLink | AutoLink
|
||||
|
||||
ReferenceLink = ReferenceLinkDouble | ReferenceLinkSingle
|
||||
|
||||
ReferenceLinkDouble = a:Label < Spnl > !"[]" b:Label
|
||||
{ link match;
|
||||
if (find_reference(&match, b->children)) {
|
||||
$$ = mk_link(a->children, match.url, match.title);
|
||||
free(a);
|
||||
free_element_list(b);
|
||||
} else {
|
||||
element *result;
|
||||
result = mk_element(LIST);
|
||||
result->children = cons(mk_str("["), cons(a, cons(mk_str("]"), cons(mk_str(yytext),
|
||||
cons(mk_str("["), cons(b, mk_str("]")))))));
|
||||
$$ = result;
|
||||
}
|
||||
}
|
||||
|
||||
ReferenceLinkSingle = a:Label < (Spnl "[]")? >
|
||||
{ link match;
|
||||
if (find_reference(&match, a->children)) {
|
||||
$$ = mk_link(a->children, match.url, match.title);
|
||||
free(a);
|
||||
}
|
||||
else {
|
||||
element *result;
|
||||
result = mk_element(LIST);
|
||||
result->children = cons(mk_str("["), cons(a, cons(mk_str("]"), mk_str(yytext))));
|
||||
$$ = result;
|
||||
}
|
||||
}
|
||||
|
||||
ExplicitLink = l:Label '(' Sp s:Source Spnl t:Title Sp ')'
|
||||
{ $$ = mk_link(l->children, s->contents.str, t->contents.str);
|
||||
free_element(s);
|
||||
free_element(t);
|
||||
free(l); }
|
||||
|
||||
Source = ( '<' < SourceContents > '>' | < SourceContents > )
|
||||
{ $$ = mk_str(yytext); }
|
||||
|
||||
SourceContents = ( ( !'(' !')' !'>' Nonspacechar )+ | '(' SourceContents ')')*
|
||||
|
||||
Title = ( TitleSingle | TitleDouble | < "" > )
|
||||
{ $$ = mk_str(yytext); }
|
||||
|
||||
TitleSingle = '\'' < ( !( '\'' Sp ( ')' | Newline ) ) . )* > '\''
|
||||
|
||||
TitleDouble = '"' < ( !( '"' Sp ( ')' | Newline ) ) . )* > '"'
|
||||
|
||||
AutoLink = AutoLinkUrl | AutoLinkEmail
|
||||
|
||||
AutoLinkUrl = '<' < [A-Za-z]+ "://" ( !Newline !'>' . )+ > '>'
|
||||
{ $$ = mk_link(mk_str(yytext), yytext, ""); }
|
||||
|
||||
AutoLinkEmail = '<' ( "mailto:" )? < [-A-Za-z0-9+_./!%~$]+ '@' ( !Newline !'>' . )+ > '>'
|
||||
{ char *mailto = malloc(strlen(yytext) + 8);
|
||||
sprintf(mailto, "mailto:%s", yytext);
|
||||
$$ = mk_link(mk_str(yytext), mailto, "");
|
||||
free(mailto);
|
||||
}
|
||||
|
||||
Reference = NonindentSpace !"[]" l:Label ':' Spnl s:RefSrc t:RefTitle BlankLine+
|
||||
{ $$ = mk_link(l->children, s->contents.str, t->contents.str);
|
||||
free_element(s);
|
||||
free_element(t);
|
||||
free(l);
|
||||
$$->key = REFERENCE; }
|
||||
|
||||
Label = '[' ( !'^' &{ extension(EXT_NOTES) } | &. &{ !extension(EXT_NOTES) } )
|
||||
a:StartList
|
||||
( !']' Inline { a = cons($$, a); } )*
|
||||
']'
|
||||
{ $$ = mk_list(LIST, a); }
|
||||
|
||||
RefSrc = < Nonspacechar+ >
|
||||
{ $$ = mk_str(yytext);
|
||||
$$->key = HTML; }
|
||||
|
||||
RefTitle = ( RefTitleSingle | RefTitleDouble | RefTitleParens | EmptyTitle )
|
||||
{ $$ = mk_str(yytext); }
|
||||
|
||||
EmptyTitle = < "" >
|
||||
|
||||
RefTitleSingle = Spnl '\'' < ( !( '\'' Sp Newline | Newline ) . )* > '\''
|
||||
|
||||
RefTitleDouble = Spnl '"' < ( !('"' Sp Newline | Newline) . )* > '"'
|
||||
|
||||
RefTitleParens = Spnl '(' < ( !(')' Sp Newline | Newline) . )* > ')'
|
||||
|
||||
References = a:StartList
|
||||
( b:Reference { a = cons(b, a); } | SkipBlock )*
|
||||
{ references = reverse(a); }
|
||||
|
||||
Ticks1 = "`" !'`'
|
||||
Ticks2 = "``" !'`'
|
||||
Ticks3 = "```" !'`'
|
||||
Ticks4 = "````" !'`'
|
||||
Ticks5 = "`````" !'`'
|
||||
|
||||
Code = ( Ticks1 Sp < ( ( !'`' Nonspacechar )+ | !Ticks1 '`'+ | !( Sp Ticks1 ) ( Spacechar | Newline !BlankLine ) )+ > Sp Ticks1
|
||||
| Ticks2 Sp < ( ( !'`' Nonspacechar )+ | !Ticks2 '`'+ | !( Sp Ticks2 ) ( Spacechar | Newline !BlankLine ) )+ > Sp Ticks2
|
||||
| Ticks3 Sp < ( ( !'`' Nonspacechar )+ | !Ticks3 '`'+ | !( Sp Ticks3 ) ( Spacechar | Newline !BlankLine ) )+ > Sp Ticks3
|
||||
| Ticks4 Sp < ( ( !'`' Nonspacechar )+ | !Ticks4 '`'+ | !( Sp Ticks4 ) ( Spacechar | Newline !BlankLine ) )+ > Sp Ticks4
|
||||
| Ticks5 Sp < ( ( !'`' Nonspacechar )+ | !Ticks5 '`'+ | !( Sp Ticks5 ) ( Spacechar | Newline !BlankLine ) )+ > Sp Ticks5
|
||||
)
|
||||
{ $$ = mk_str(yytext); $$->key = CODE; }
|
||||
|
||||
RawHtml = < (HtmlComment | HtmlBlockScript | HtmlTag) >
|
||||
{ if (extension(EXT_FILTER_HTML)) {
|
||||
$$ = mk_list(LIST, NULL);
|
||||
} else {
|
||||
$$ = mk_str(yytext);
|
||||
$$->key = HTML;
|
||||
}
|
||||
}
|
||||
|
||||
BlankLine = Sp Newline
|
||||
|
||||
Quoted = '"' (!'"' .)* '"' | '\'' (!'\'' .)* '\''
|
||||
HtmlAttribute = (AlphanumericAscii | '-')+ Spnl ('=' Spnl (Quoted | (!'>' Nonspacechar)+))? Spnl
|
||||
HtmlComment = "<!--" (!"-->" .)* "-->"
|
||||
HtmlTag = '<' Spnl '/'? AlphanumericAscii+ Spnl HtmlAttribute* '/'? Spnl '>'
|
||||
Eof = !.
|
||||
Spacechar = ' ' | '\t'
|
||||
Nonspacechar = !Spacechar !Newline .
|
||||
Newline = '\n' | '\r' '\n'?
|
||||
Sp = Spacechar*
|
||||
Spnl = Sp (Newline Sp)?
|
||||
SpecialChar = '*' | '_' | '`' | '&' | '[' | ']' | '(' | ')' | '<' | '!' | '#' | '\\' | '\'' | '"' | ExtendedSpecialChar
|
||||
NormalChar = !( SpecialChar | Spacechar | Newline ) .
|
||||
Alphanumeric = [0-9A-Za-z] | '\200' | '\201' | '\202' | '\203' | '\204' | '\205' | '\206' | '\207' | '\210' | '\211' | '\212' | '\213' | '\214' | '\215' | '\216' | '\217' | '\220' | '\221' | '\222' | '\223' | '\224' | '\225' | '\226' | '\227' | '\230' | '\231' | '\232' | '\233' | '\234' | '\235' | '\236' | '\237' | '\240' | '\241' | '\242' | '\243' | '\244' | '\245' | '\246' | '\247' | '\250' | '\251' | '\252' | '\253' | '\254' | '\255' | '\256' | '\257' | '\260' | '\261' | '\262' | '\263' | '\264' | '\265' | '\266' | '\267' | '\270' | '\271' | '\272' | '\273' | '\274' | '\275' | '\276' | '\277' | '\300' | '\301' | '\302' | '\303' | '\304' | '\305' | '\306' | '\307' | '\310' | '\311' | '\312' | '\313' | '\314' | '\315' | '\316' | '\317' | '\320' | '\321' | '\322' | '\323' | '\324' | '\325' | '\326' | '\327' | '\330' | '\331' | '\332' | '\333' | '\334' | '\335' | '\336' | '\337' | '\340' | '\341' | '\342' | '\343' | '\344' | '\345' | '\346' | '\347' | '\350' | '\351' | '\352' | '\353' | '\354' | '\355' | '\356' | '\357' | '\360' | '\361' | '\362' | '\363' | '\364' | '\365' | '\366' | '\367' | '\370' | '\371' | '\372' | '\373' | '\374' | '\375' | '\376' | '\377'
|
||||
AlphanumericAscii = [A-Za-z0-9]
|
||||
Digit = [0-9]
|
||||
BOM = "\357\273\277"
|
||||
|
||||
HexEntity = < '&' '#' [Xx] [0-9a-fA-F]+ ';' >
|
||||
DecEntity = < '&' '#' [0-9]+ > ';' >
|
||||
CharEntity = < '&' [A-Za-z0-9]+ ';' >
|
||||
|
||||
NonindentSpace = " " | " " | " " | ""
|
||||
Indent = "\t" | " "
|
||||
IndentedLine = Indent Line
|
||||
OptionallyIndentedLine = Indent? Line
|
||||
|
||||
# StartList starts a list data structure that can be added to with cons:
|
||||
StartList = &.
|
||||
{ $$ = NULL; }
|
||||
|
||||
Line = RawLine
|
||||
{ $$ = mk_str(yytext); }
|
||||
RawLine = ( < (!'\r' !'\n' .)* Newline > | < .+ > Eof )
|
||||
|
||||
SkipBlock = HtmlBlock
|
||||
| ( !'#' !SetextBottom1 !SetextBottom2 !BlankLine RawLine )+ BlankLine*
|
||||
| BlankLine+
|
||||
| RawLine
|
||||
|
||||
# Syntax extensions
|
||||
|
||||
ExtendedSpecialChar = &{ extension(EXT_SMART) } ('.' | '-' | '\'' | '"')
|
||||
| &{ extension(EXT_NOTES) } ( '^' )
|
||||
|
||||
Smart = &{ extension(EXT_SMART) }
|
||||
( Ellipsis | Dash | SingleQuoted | DoubleQuoted | Apostrophe )
|
||||
|
||||
Apostrophe = '\''
|
||||
{ $$ = mk_element(APOSTROPHE); }
|
||||
|
||||
Ellipsis = ("..." | ". . .")
|
||||
{ $$ = mk_element(ELLIPSIS); }
|
||||
|
||||
Dash = EmDash | EnDash
|
||||
|
||||
EnDash = '-' &Digit
|
||||
{ $$ = mk_element(ENDASH); }
|
||||
|
||||
EmDash = ("---" | "--")
|
||||
{ $$ = mk_element(EMDASH); }
|
||||
|
||||
SingleQuoteStart = '\'' !(Spacechar | Newline)
|
||||
|
||||
SingleQuoteEnd = '\'' !Alphanumeric
|
||||
|
||||
SingleQuoted = SingleQuoteStart
|
||||
a:StartList
|
||||
( !SingleQuoteEnd b:Inline { a = cons(b, a); } )+
|
||||
SingleQuoteEnd
|
||||
{ $$ = mk_list(SINGLEQUOTED, a); }
|
||||
|
||||
DoubleQuoteStart = '"'
|
||||
|
||||
DoubleQuoteEnd = '"'
|
||||
|
||||
DoubleQuoted = DoubleQuoteStart
|
||||
a:StartList
|
||||
( !DoubleQuoteEnd b:Inline { a = cons(b, a); } )+
|
||||
DoubleQuoteEnd
|
||||
{ $$ = mk_list(DOUBLEQUOTED, a); }
|
||||
|
||||
NoteReference = &{ extension(EXT_NOTES) }
|
||||
ref:RawNoteReference
|
||||
{ element *match;
|
||||
if (find_note(&match, ref->contents.str)) {
|
||||
$$ = mk_element(NOTE);
|
||||
assert(match->children != NULL);
|
||||
$$->children = match->children;
|
||||
$$->contents.str = 0;
|
||||
} else {
|
||||
char *s;
|
||||
s = malloc(strlen(ref->contents.str) + 4);
|
||||
sprintf(s, "[^%s]", ref->contents.str);
|
||||
$$ = mk_str(s);
|
||||
free(s);
|
||||
}
|
||||
}
|
||||
|
||||
RawNoteReference = "[^" < ( !Newline !']' . )+ > ']'
|
||||
{ $$ = mk_str(yytext); }
|
||||
|
||||
Note = &{ extension(EXT_NOTES) }
|
||||
NonindentSpace ref:RawNoteReference ':' Sp
|
||||
a:StartList
|
||||
( RawNoteBlock { a = cons($$, a); } )
|
||||
( &Indent RawNoteBlock { a = cons($$, a); } )*
|
||||
{ $$ = mk_list(NOTE, a);
|
||||
$$->contents.str = strdup(ref->contents.str);
|
||||
}
|
||||
|
||||
InlineNote = &{ extension(EXT_NOTES) }
|
||||
"^["
|
||||
a:StartList
|
||||
( !']' Inline { a = cons($$, a); } )+
|
||||
']'
|
||||
{ $$ = mk_list(NOTE, a);
|
||||
$$->contents.str = 0; }
|
||||
|
||||
Notes = a:StartList
|
||||
( b:Note { a = cons(b, a); } | SkipBlock )*
|
||||
{ notes = reverse(a); }
|
||||
|
||||
RawNoteBlock = a:StartList
|
||||
( !BlankLine OptionallyIndentedLine { a = cons($$, a); } )+
|
||||
( < BlankLine* > { a = cons(mk_str(yytext), a); } )
|
||||
{ $$ = mk_str_from_list(a, true);
|
||||
$$->key = RAW;
|
||||
}
|
||||
|
||||
%%
|
||||
|
||||
|
72
supportlibs/pegmarkdown/markdown_peg.h
Normal file
72
supportlibs/pegmarkdown/markdown_peg.h
Normal file
@ -0,0 +1,72 @@
|
||||
/* markdown_peg.h */
|
||||
#ifndef MARKDOWN_PEG_H
|
||||
#define MARKDOWN_PEG_H
|
||||
|
||||
#include "markdown_lib.h"
|
||||
#include <glib.h>
|
||||
|
||||
/* Information (label, URL and title) for a link. */
|
||||
struct Link {
|
||||
struct Element *label;
|
||||
char *url;
|
||||
char *title;
|
||||
};
|
||||
|
||||
typedef struct Link link;
|
||||
|
||||
/* Union for contents of an Element (string, list, or link). */
|
||||
union Contents {
|
||||
char *str;
|
||||
struct Link *link;
|
||||
};
|
||||
|
||||
/* Types of semantic values returned by parsers. */
|
||||
enum keys { LIST, /* A generic list of values. For ordered and bullet lists, see below. */
|
||||
RAW, /* Raw markdown to be processed further */
|
||||
SPACE,
|
||||
LINEBREAK,
|
||||
ELLIPSIS,
|
||||
EMDASH,
|
||||
ENDASH,
|
||||
APOSTROPHE,
|
||||
SINGLEQUOTED,
|
||||
DOUBLEQUOTED,
|
||||
STR,
|
||||
LINK,
|
||||
IMAGE,
|
||||
CODE,
|
||||
HTML,
|
||||
EMPH,
|
||||
STRONG,
|
||||
PLAIN,
|
||||
PARA,
|
||||
LISTITEM,
|
||||
BULLETLIST,
|
||||
ORDEREDLIST,
|
||||
H1, H2, H3, H4, H5, H6, /* Code assumes that these are in order. */
|
||||
BLOCKQUOTE,
|
||||
VERBATIM,
|
||||
HTMLBLOCK,
|
||||
HRULE,
|
||||
REFERENCE,
|
||||
NOTE
|
||||
};
|
||||
|
||||
/* Semantic value of a parsing action. */
|
||||
struct Element {
|
||||
int key;
|
||||
union Contents contents;
|
||||
struct Element *children;
|
||||
struct Element *next;
|
||||
};
|
||||
|
||||
typedef struct Element element;
|
||||
|
||||
element * parse_references(char *string, int extensions);
|
||||
element * parse_notes(char *string, int extensions, element *reference_list);
|
||||
element * parse_markdown(char *string, int extensions, element *reference_list, element *note_list);
|
||||
void free_element_list(element * elt);
|
||||
void free_element(element *elt);
|
||||
void print_element_list(GString *out, element *elt, int format, int exts);
|
||||
|
||||
#endif
|
181
supportlibs/pegmarkdown/odf.c
Normal file
181
supportlibs/pegmarkdown/odf.c
Normal file
@ -0,0 +1,181 @@
|
||||
/**********************************************************************
|
||||
|
||||
odf.c - Utility routines to enable ODF support in peg-multimarkdown.
|
||||
(c) 2011 Fletcher T. Penney (http://fletcherpenney.net/).
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License or the MIT
|
||||
license. See LICENSE for details.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "odf.h"
|
||||
|
||||
|
||||
void print_odf_header(GString *out){
|
||||
|
||||
/* Insert required XML header */
|
||||
g_string_append_printf(out,
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" \
|
||||
"<office:document xmlns:office=\"urn:oasis:names:tc:opendocument:xmlns:office:1.0\"\n" \
|
||||
" xmlns:style=\"urn:oasis:names:tc:opendocument:xmlns:style:1.0\"\n" \
|
||||
" xmlns:text=\"urn:oasis:names:tc:opendocument:xmlns:text:1.0\"\n" \
|
||||
" xmlns:table=\"urn:oasis:names:tc:opendocument:xmlns:table:1.0\"\n" \
|
||||
" xmlns:draw=\"urn:oasis:names:tc:opendocument:xmlns:drawing:1.0\"\n" \
|
||||
" xmlns:fo=\"urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0\"\n" \
|
||||
" xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n" \
|
||||
" xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n" \
|
||||
" xmlns:meta=\"urn:oasis:names:tc:opendocument:xmlns:meta:1.0\"\n" \
|
||||
" xmlns:number=\"urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0\"\n" \
|
||||
" xmlns:svg=\"urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0\"\n" \
|
||||
" xmlns:chart=\"urn:oasis:names:tc:opendocument:xmlns:chart:1.0\"\n" \
|
||||
" xmlns:dr3d=\"urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0\"\n" \
|
||||
" xmlns:math=\"http://www.w3.org/1998/Math/MathML\"\n" \
|
||||
" xmlns:form=\"urn:oasis:names:tc:opendocument:xmlns:form:1.0\"\n" \
|
||||
" xmlns:script=\"urn:oasis:names:tc:opendocument:xmlns:script:1.0\"\n" \
|
||||
" xmlns:config=\"urn:oasis:names:tc:opendocument:xmlns:config:1.0\"\n" \
|
||||
" xmlns:ooo=\"http://openoffice.org/2004/office\"\n" \
|
||||
" xmlns:ooow=\"http://openoffice.org/2004/writer\"\n" \
|
||||
" xmlns:oooc=\"http://openoffice.org/2004/calc\"\n" \
|
||||
" xmlns:dom=\"http://www.w3.org/2001/xml-events\"\n" \
|
||||
" xmlns:xforms=\"http://www.w3.org/2002/xforms\"\n" \
|
||||
" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n" \
|
||||
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" \
|
||||
" xmlns:rpt=\"http://openoffice.org/2005/report\"\n" \
|
||||
" xmlns:of=\"urn:oasis:names:tc:opendocument:xmlns:of:1.2\"\n" \
|
||||
" xmlns:xhtml=\"http://www.w3.org/1999/xhtml\"\n" \
|
||||
" xmlns:grddl=\"http://www.w3.org/2003/g/data-view#\"\n" \
|
||||
" xmlns:tableooo=\"http://openoffice.org/2009/table\"\n" \
|
||||
" xmlns:field=\"urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0\"\n" \
|
||||
" xmlns:formx=\"urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0\"\n" \
|
||||
" xmlns:css3t=\"http://www.w3.org/TR/css3-text/\"\n" \
|
||||
" office:version=\"1.2\"\n" \
|
||||
" grddl:transformation=\"http://docs.oasis-open.org/office/1.2/xslt/odf2rdf.xsl\"\n" \
|
||||
" office:mimetype=\"application/vnd.oasis.opendocument.text\">\n");
|
||||
|
||||
/* Font Declarations */
|
||||
g_string_append_printf(out, "<office:font-face-decls>\n" \
|
||||
" <style:font-face style:name=\"Courier New\" svg:font-family=\"'Courier New'\"\n" \
|
||||
" style:font-adornments=\"Regular\"\n" \
|
||||
" style:font-family-generic=\"modern\"\n" \
|
||||
" style:font-pitch=\"fixed\"/>\n" \
|
||||
"</office:font-face-decls>\n");
|
||||
|
||||
/* Append basic style information */
|
||||
g_string_append_printf(out, "<office:styles>\n" \
|
||||
"<style:style style:name=\"Standard\" style:family=\"paragraph\" style:class=\"text\">\n" \
|
||||
" <style:paragraph-properties fo:margin-top=\"0in\" fo:margin-bottom=\"0.15in\"" \
|
||||
" fo:text-align=\"justify\" style:justify-single-word=\"false\"/>\n" \
|
||||
" </style:style>\n" \
|
||||
"<style:style style:name=\"Preformatted_20_Text\" style:display-name=\"Preformatted Text\"\n" \
|
||||
" style:family=\"paragraph\"\n" \
|
||||
" style:parent-style-name=\"Standard\"\n" \
|
||||
" style:class=\"html\">\n" \
|
||||
" <style:paragraph-properties fo:margin-top=\"0in\" fo:margin-bottom=\"0in\" fo:text-align=\"start\"\n" \
|
||||
" style:justify-single-word=\"false\"/>\n" \
|
||||
" <style:text-properties style:font-name=\"Courier New\" fo:font-size=\"11pt\"\n" \
|
||||
" style:font-name-asian=\"Courier New\"\n" \
|
||||
" style:font-size-asian=\"11pt\"\n" \
|
||||
" style:font-name-complex=\"Courier New\"\n" \
|
||||
" style:font-size-complex=\"11pt\"/>\n" \
|
||||
"</style:style>\n" \
|
||||
"<style:style style:name=\"Source_20_Text\" style:display-name=\"Source Text\"\n" \
|
||||
" style:family=\"text\">\n" \
|
||||
" <style:text-properties style:font-name=\"Courier New\" style:font-name-asian=\"Courier New\"\n" \
|
||||
" style:font-name-complex=\"Courier New\"\n" \
|
||||
" fo:font-size=\"11pt\"/>\n" \
|
||||
"</style:style>\n" \
|
||||
"<style:style style:name=\"List\" style:family=\"paragraph\"\n" \
|
||||
" style:parent-style-name=\"Standard\"\n" \
|
||||
" style:class=\"list\">\n" \
|
||||
" <style:paragraph-properties fo:text-align=\"start\" style:justify-single-word=\"false\"/>\n" \
|
||||
" <style:text-properties style:font-size-asian=\"12pt\"/>\n" \
|
||||
"</style:style>\n" \
|
||||
"<style:style style:name=\"Quotations\" style:family=\"paragraph\"\n" \
|
||||
" style:parent-style-name=\"Standard\"\n" \
|
||||
" style:class=\"html\">\n" \
|
||||
" <style:paragraph-properties fo:margin-left=\"0.3937in\" fo:margin-right=\"0.3937in\" fo:margin-top=\"0in\"\n" \
|
||||
" fo:margin-bottom=\"0.1965in\"\n" \
|
||||
" fo:text-align=\"justify\"" \
|
||||
" style:justify-single-word=\"false\"" \
|
||||
" fo:text-indent=\"0in\"\n" \
|
||||
" style:auto-text-indent=\"false\"/>\n" \
|
||||
"</style:style>\n" \
|
||||
"<style:style style:name=\"Table_20_Heading\" style:display-name=\"Table Heading\"\n" \
|
||||
" style:family=\"paragraph\"\n" \
|
||||
" style:parent-style-name=\"Table_20_Contents\"\n" \
|
||||
" style:class=\"extra\">\n" \
|
||||
" <style:paragraph-properties fo:text-align=\"center\" style:justify-single-word=\"false\"\n" \
|
||||
" text:number-lines=\"false\"\n" \
|
||||
" text:line-number=\"0\"/>\n" \
|
||||
" <style:text-properties fo:font-weight=\"bold\" style:font-weight-asian=\"bold\"\n" \
|
||||
" style:font-weight-complex=\"bold\"/>\n" \
|
||||
"</style:style>\n" \
|
||||
"<style:style style:name=\"Horizontal_20_Line\" style:display-name=\"Horizontal Line\"\n" \
|
||||
" style:family=\"paragraph\"\n" \
|
||||
" style:parent-style-name=\"Standard\"\n" \
|
||||
" style:class=\"html\">\n" \
|
||||
" <style:paragraph-properties fo:margin-top=\"0in\" fo:margin-bottom=\"0.1965in\"\n" \
|
||||
" style:border-line-width-bottom=\"0.0008in 0.0138in 0.0008in\"\n" \
|
||||
" fo:padding=\"0in\"\n" \
|
||||
" fo:border-left=\"none\"\n" \
|
||||
" fo:border-right=\"none\"\n" \
|
||||
" fo:border-top=\"none\"\n" \
|
||||
" fo:border-bottom=\"0.0154in double #808080\"\n" \
|
||||
" text:number-lines=\"false\"\n" \
|
||||
" text:line-number=\"0\"\n" \
|
||||
" style:join-border=\"false\"/>\n" \
|
||||
" <style:text-properties fo:font-size=\"6pt\" style:font-size-asian=\"6pt\" style:font-size-complex=\"6pt\"/>\n" \
|
||||
"</style:style>\n" \
|
||||
"</office:styles>\n");
|
||||
|
||||
/* Automatic style information */
|
||||
g_string_append_printf(out, "<office:automatic-styles>" \
|
||||
" <style:style style:name=\"MMD-Italic\" style:family=\"text\">\n" \
|
||||
" <style:text-properties fo:font-style=\"italic\" style:font-style-asian=\"italic\"\n" \
|
||||
" style:font-style-complex=\"italic\"/>\n" \
|
||||
" </style:style>\n" \
|
||||
" <style:style style:name=\"MMD-Bold\" style:family=\"text\">\n" \
|
||||
" <style:text-properties fo:font-weight=\"bold\" style:font-weight-asian=\"bold\"\n" \
|
||||
" style:font-weight-complex=\"bold\"/>\n" \
|
||||
" </style:style>\n" \
|
||||
"<style:style style:name=\"MMD-Table\" style:family=\"paragraph\" style:parent-style-name=\"Standard\">\n" \
|
||||
" <style:paragraph-properties fo:margin-top=\"0in\" fo:margin-bottom=\"0.05in\"/>\n" \
|
||||
"</style:style>\n" \
|
||||
"<style:style style:name=\"MMD-Table-Center\" style:family=\"paragraph\" style:parent-style-name=\"MMD-Table\">\n" \
|
||||
" <style:paragraph-properties fo:text-align=\"center\" style:justify-single-word=\"false\"/>\n" \
|
||||
"</style:style>\n" \
|
||||
"<style:style style:name=\"MMD-Table-Right\" style:family=\"paragraph\" style:parent-style-name=\"MMD-Table\">\n" \
|
||||
" <style:paragraph-properties fo:text-align=\"right\" style:justify-single-word=\"false\"/>\n" \
|
||||
"</style:style>\n" \
|
||||
"<style:style style:name=\"P2\" style:family=\"paragraph\" style:parent-style-name=\"Standard\"\n" \
|
||||
" style:list-style-name=\"L2\">\n" \
|
||||
"<style:paragraph-properties fo:text-align=\"start\" style:justify-single-word=\"false\"/>\n" \
|
||||
"</style:style>\n" \
|
||||
"<style:style style:name=\"fr1\" style:family=\"graphic\" style:parent-style-name=\"Frame\">\n" \
|
||||
" <style:graphic-properties style:print-content=\"false\" style:vertical-pos=\"top\"\n" \
|
||||
" style:vertical-rel=\"baseline\"\n" \
|
||||
" fo:padding=\"0in\"\n" \
|
||||
" fo:border=\"none\"\n" \
|
||||
" style:shadow=\"none\"/>\n" \
|
||||
"</style:style>\n" \
|
||||
"</office:automatic-styles>\n" \
|
||||
"<style:style style:name=\"P1\" style:family=\"paragraph\" style:parent-style-name=\"Standard\"\n" \
|
||||
" style:list-style-name=\"L1\"/>\n" \
|
||||
"<text:list-style style:name=\"L1\">\n" \
|
||||
" <text:list-level-style-bullet />\n" \
|
||||
"</text:list-style>\n" \
|
||||
"<text:list-style style:name=\"L2\">\n" \
|
||||
" <text:list-level-style-number />\n" \
|
||||
"</text:list-style>\n");
|
||||
}
|
||||
|
||||
void print_odf_footer(GString *out) {
|
||||
g_string_append_printf(out, "</office:text>\n</office:body>\n</office:document>");
|
||||
}
|
||||
|
11
supportlibs/pegmarkdown/odf.h
Normal file
11
supportlibs/pegmarkdown/odf.h
Normal file
@ -0,0 +1,11 @@
|
||||
#ifndef ODF_H
|
||||
#define ODF_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <glib.h>
|
||||
|
||||
void print_odf_header(GString *out);
|
||||
void print_odf_footer(GString *out);
|
||||
#endif
|
||||
|
117
supportlibs/pegmarkdown/parsing_functions.c
Normal file
117
supportlibs/pegmarkdown/parsing_functions.c
Normal file
@ -0,0 +1,117 @@
|
||||
/* parsing_functions.c - Functions for parsing markdown and
|
||||
* freeing element lists. */
|
||||
|
||||
/* These yy_* functions come from markdown_parser.c which is
|
||||
* generated from markdown_parser.leg
|
||||
* */
|
||||
typedef int (*yyrule)();
|
||||
|
||||
extern int yyparse();
|
||||
extern int yyparsefrom(yyrule);
|
||||
extern int yy_References();
|
||||
extern int yy_Notes();
|
||||
extern int yy_Doc();
|
||||
|
||||
#include "utility_functions.h"
|
||||
#include "parsing_functions.h"
|
||||
#include "markdown_peg.h"
|
||||
|
||||
static void free_element_contents(element elt);
|
||||
|
||||
/* free_element_list - free list of elements recursively */
|
||||
void free_element_list(element * elt) {
|
||||
element * next = NULL;
|
||||
while (elt != NULL) {
|
||||
next = elt->next;
|
||||
free_element_contents(*elt);
|
||||
if (elt->children != NULL) {
|
||||
free_element_list(elt->children);
|
||||
elt->children = NULL;
|
||||
}
|
||||
free(elt);
|
||||
elt = next;
|
||||
}
|
||||
}
|
||||
|
||||
/* free_element_contents - free element contents depending on type */
|
||||
static void free_element_contents(element elt) {
|
||||
switch (elt.key) {
|
||||
case STR:
|
||||
case SPACE:
|
||||
case RAW:
|
||||
case HTMLBLOCK:
|
||||
case HTML:
|
||||
case VERBATIM:
|
||||
case CODE:
|
||||
case NOTE:
|
||||
free(elt.contents.str);
|
||||
elt.contents.str = NULL;
|
||||
break;
|
||||
case LINK:
|
||||
case IMAGE:
|
||||
case REFERENCE:
|
||||
free(elt.contents.link->url);
|
||||
elt.contents.link->url = NULL;
|
||||
free(elt.contents.link->title);
|
||||
elt.contents.link->title = NULL;
|
||||
free_element_list(elt.contents.link->label);
|
||||
free(elt.contents.link);
|
||||
elt.contents.link = NULL;
|
||||
break;
|
||||
default:
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
/* free_element - free element and contents */
|
||||
void free_element(element *elt) {
|
||||
free_element_contents(*elt);
|
||||
free(elt);
|
||||
}
|
||||
|
||||
element * parse_references(char *string, int extensions) {
|
||||
|
||||
char *oldcharbuf;
|
||||
syntax_extensions = extensions;
|
||||
|
||||
oldcharbuf = charbuf;
|
||||
charbuf = string;
|
||||
yyparsefrom(yy_References); /* first pass, just to collect references */
|
||||
charbuf = oldcharbuf;
|
||||
|
||||
return references;
|
||||
}
|
||||
|
||||
element * parse_notes(char *string, int extensions, element *reference_list) {
|
||||
|
||||
char *oldcharbuf;
|
||||
notes = NULL;
|
||||
syntax_extensions = extensions;
|
||||
|
||||
if (extension(EXT_NOTES)) {
|
||||
references = reference_list;
|
||||
oldcharbuf = charbuf;
|
||||
charbuf = string;
|
||||
yyparsefrom(yy_Notes); /* second pass for notes */
|
||||
charbuf = oldcharbuf;
|
||||
}
|
||||
|
||||
return notes;
|
||||
}
|
||||
|
||||
element * parse_markdown(char *string, int extensions, element *reference_list, element *note_list) {
|
||||
|
||||
char *oldcharbuf;
|
||||
syntax_extensions = extensions;
|
||||
references = reference_list;
|
||||
notes = note_list;
|
||||
|
||||
oldcharbuf = charbuf;
|
||||
charbuf = string;
|
||||
|
||||
yyparsefrom(yy_Doc);
|
||||
|
||||
charbuf = oldcharbuf; /* restore charbuf to original value */
|
||||
return parse_result;
|
||||
|
||||
}
|
17
supportlibs/pegmarkdown/parsing_functions.h
Normal file
17
supportlibs/pegmarkdown/parsing_functions.h
Normal file
@ -0,0 +1,17 @@
|
||||
#ifndef PARSING_FUNCTIONS_H
|
||||
#define PARSING_FUNCTIONS_H
|
||||
/* parsing_functions.c - Functions for parsing markdown and
|
||||
* freeing element lists. */
|
||||
|
||||
#include "markdown_peg.h"
|
||||
|
||||
/* free_element_list - free list of elements recursively */
|
||||
void free_element_list(element * elt);
|
||||
/* free_element - free element and contents */
|
||||
void free_element(element *elt);
|
||||
|
||||
element * parse_references(char *string, int extensions);
|
||||
element * parse_notes(char *string, int extensions, element *reference_list);
|
||||
element * parse_markdown(char *string, int extensions, element *reference_list, element *note_list);
|
||||
|
||||
#endif
|
65
supportlibs/pegmarkdown/peg-0.1.9/Makefile
Normal file
65
supportlibs/pegmarkdown/peg-0.1.9/Makefile
Normal file
@ -0,0 +1,65 @@
|
||||
CFLAGS = -g -Wall $(OFLAGS) $(XFLAGS)
|
||||
OFLAGS = -O3 -DNDEBUG
|
||||
#OFLAGS = -pg
|
||||
|
||||
OBJS = tree.o compile.o
|
||||
|
||||
all : peg leg
|
||||
|
||||
peg : peg.o $(OBJS)
|
||||
$(CC) $(CFLAGS) -o $@-new peg.o $(OBJS)
|
||||
mv $@-new $@
|
||||
|
||||
leg : leg.o $(OBJS)
|
||||
$(CC) $(CFLAGS) -o $@-new leg.o $(OBJS)
|
||||
mv $@-new $@
|
||||
|
||||
ROOT =
|
||||
PREFIX = /usr/local
|
||||
BINDIR = $(ROOT)$(PREFIX)/bin
|
||||
|
||||
install : $(BINDIR)/peg $(BINDIR)/leg
|
||||
|
||||
$(BINDIR)/% : %
|
||||
cp -p $< $@
|
||||
strip $@
|
||||
|
||||
uninstall : .FORCE
|
||||
rm -f $(BINDIR)/peg
|
||||
rm -f $(BINDIR)/leg
|
||||
|
||||
peg.o : peg.c peg.peg-c
|
||||
|
||||
%.peg-c : %.peg compile.c
|
||||
./peg -o $@ $<
|
||||
|
||||
leg.o : leg.c
|
||||
|
||||
leg.c : leg.leg compile.c
|
||||
./leg -o $@ $<
|
||||
|
||||
check : check-peg check-leg
|
||||
|
||||
check-peg : peg .FORCE
|
||||
./peg < peg.peg > peg.out
|
||||
diff peg.peg-c peg.out
|
||||
rm peg.out
|
||||
|
||||
check-leg : leg .FORCE
|
||||
./leg < leg.leg > leg.out
|
||||
diff leg.c leg.out
|
||||
rm leg.out
|
||||
|
||||
test examples : .FORCE
|
||||
$(SHELL) -ec '(cd examples; $(MAKE))'
|
||||
|
||||
clean : .FORCE
|
||||
rm -f *~ *.o *.peg.[cd] *.leg.[cd]
|
||||
$(SHELL) -ec '(cd examples; $(MAKE) $@)'
|
||||
|
||||
spotless : clean .FORCE
|
||||
rm -f peg
|
||||
rm -f leg
|
||||
$(SHELL) -ec '(cd examples; $(MAKE) $@)'
|
||||
|
||||
.FORCE :
|
717
supportlibs/pegmarkdown/peg-0.1.9/compile.c
Normal file
717
supportlibs/pegmarkdown/peg-0.1.9/compile.c
Normal file
@ -0,0 +1,717 @@
|
||||
/* Copyright (c) 2007, 2012 by Ian Piumarta
|
||||
* All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the 'Software'),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, provided that the above copyright notice(s) and this
|
||||
* permission notice appear in all copies of the Software. Acknowledgement
|
||||
* of the use of this Software in supporting documentation would be
|
||||
* appreciated but is not required.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED 'AS IS'. USE ENTIRELY AT YOUR OWN RISK.
|
||||
*
|
||||
* Last edited: 2012-04-29 16:09:36 by piumarta on emilia
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "version.h"
|
||||
#include "tree.h"
|
||||
|
||||
static int yyl(void)
|
||||
{
|
||||
static int prev= 0;
|
||||
return ++prev;
|
||||
}
|
||||
|
||||
static void charClassSet (unsigned char bits[], int c) { bits[c >> 3] |= (1 << (c & 7)); }
|
||||
static void charClassClear(unsigned char bits[], int c) { bits[c >> 3] &= ~(1 << (c & 7)); }
|
||||
|
||||
typedef void (*setter)(unsigned char bits[], int c);
|
||||
|
||||
static inline int oigit(int c) { return '0' <= c && c <= '7'; }
|
||||
|
||||
static int cnext(unsigned char **ccp)
|
||||
{
|
||||
unsigned char *cclass= *ccp;
|
||||
int c= *cclass++;
|
||||
if (c)
|
||||
{
|
||||
if ('\\' == c && *cclass)
|
||||
{
|
||||
switch (c= *cclass++)
|
||||
{
|
||||
case 'a': c= '\a'; break; /* bel */
|
||||
case 'b': c= '\b'; break; /* bs */
|
||||
case 'e': c= '\e'; break; /* esc */
|
||||
case 'f': c= '\f'; break; /* ff */
|
||||
case 'n': c= '\n'; break; /* nl */
|
||||
case 'r': c= '\r'; break; /* cr */
|
||||
case 't': c= '\t'; break; /* ht */
|
||||
case 'v': c= '\v'; break; /* vt */
|
||||
default:
|
||||
if (oigit(c))
|
||||
{
|
||||
c -= '0';
|
||||
if (oigit(*cclass)) c= (c << 3) + *cclass++ - '0';
|
||||
if (oigit(*cclass)) c= (c << 3) + *cclass++ - '0';
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
*ccp= cclass;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
static char *makeCharClass(unsigned char *cclass)
|
||||
{
|
||||
unsigned char bits[32];
|
||||
setter set;
|
||||
int c, prev= -1;
|
||||
static char string[256];
|
||||
char *ptr;
|
||||
|
||||
if ('^' == *cclass)
|
||||
{
|
||||
memset(bits, 255, 32);
|
||||
set= charClassClear;
|
||||
++cclass;
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(bits, 0, 32);
|
||||
set= charClassSet;
|
||||
}
|
||||
|
||||
while (*cclass)
|
||||
{
|
||||
if ('-' == *cclass && cclass[1] && prev >= 0)
|
||||
{
|
||||
++cclass;
|
||||
for (c= cnext(&cclass); prev <= c; ++prev)
|
||||
set(bits, prev);
|
||||
prev= -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
c= cnext(&cclass);
|
||||
set(bits, prev= c);
|
||||
}
|
||||
}
|
||||
|
||||
ptr= string;
|
||||
for (c= 0; c < 32; ++c)
|
||||
ptr += sprintf(ptr, "\\%03o", bits[c]);
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
static void begin(void) { fprintf(output, "\n {"); }
|
||||
static void end(void) { fprintf(output, "\n }"); }
|
||||
static void label(int n) { fprintf(output, "\n l%d:;\t", n); }
|
||||
static void jump(int n) { fprintf(output, " goto l%d;", n); }
|
||||
static void save(int n) { fprintf(output, " int yypos%d= ctx->pos, yythunkpos%d= ctx->thunkpos;", n, n); }
|
||||
static void restore(int n) { fprintf(output, " ctx->pos= yypos%d; ctx->thunkpos= yythunkpos%d;", n, n); }
|
||||
|
||||
static void Node_compile_c_ko(Node *node, int ko)
|
||||
{
|
||||
assert(node);
|
||||
switch (node->type)
|
||||
{
|
||||
case Rule:
|
||||
fprintf(stderr, "\ninternal error #1 (%s)\n", node->rule.name);
|
||||
exit(1);
|
||||
break;
|
||||
|
||||
case Dot:
|
||||
fprintf(output, " if (!yymatchDot(ctx)) goto l%d;", ko);
|
||||
break;
|
||||
|
||||
case Name:
|
||||
fprintf(output, " if (!yy_%s(ctx)) goto l%d;", node->name.rule->rule.name, ko);
|
||||
if (node->name.variable)
|
||||
fprintf(output, " yyDo(ctx, yySet, %d, 0);", node->name.variable->variable.offset);
|
||||
break;
|
||||
|
||||
case Character:
|
||||
case String:
|
||||
{
|
||||
int len= strlen(node->string.value);
|
||||
if (1 == len)
|
||||
{
|
||||
if ('\'' == node->string.value[0])
|
||||
fprintf(output, " if (!yymatchChar(ctx, '\\'')) goto l%d;", ko);
|
||||
else
|
||||
fprintf(output, " if (!yymatchChar(ctx, '%s')) goto l%d;", node->string.value, ko);
|
||||
}
|
||||
else
|
||||
if (2 == len && '\\' == node->string.value[0])
|
||||
fprintf(output, " if (!yymatchChar(ctx, '%s')) goto l%d;", node->string.value, ko);
|
||||
else
|
||||
fprintf(output, " if (!yymatchString(ctx, \"%s\")) goto l%d;", node->string.value, ko);
|
||||
}
|
||||
break;
|
||||
|
||||
case Class:
|
||||
fprintf(output, " if (!yymatchClass(ctx, (unsigned char *)\"%s\")) goto l%d;", makeCharClass(node->cclass.value), ko);
|
||||
break;
|
||||
|
||||
case Action:
|
||||
fprintf(output, " yyDo(ctx, yy%s, ctx->begin, ctx->end);", node->action.name);
|
||||
break;
|
||||
|
||||
case Predicate:
|
||||
fprintf(output, " yyText(ctx, ctx->begin, ctx->end); if (!(%s)) goto l%d;", node->action.text, ko);
|
||||
break;
|
||||
|
||||
case Alternate:
|
||||
{
|
||||
int ok= yyl();
|
||||
begin();
|
||||
save(ok);
|
||||
for (node= node->alternate.first; node; node= node->alternate.next)
|
||||
if (node->alternate.next)
|
||||
{
|
||||
int next= yyl();
|
||||
Node_compile_c_ko(node, next);
|
||||
jump(ok);
|
||||
label(next);
|
||||
restore(ok);
|
||||
}
|
||||
else
|
||||
Node_compile_c_ko(node, ko);
|
||||
end();
|
||||
label(ok);
|
||||
}
|
||||
break;
|
||||
|
||||
case Sequence:
|
||||
for (node= node->sequence.first; node; node= node->sequence.next)
|
||||
Node_compile_c_ko(node, ko);
|
||||
break;
|
||||
|
||||
case PeekFor:
|
||||
{
|
||||
int ok= yyl();
|
||||
begin();
|
||||
save(ok);
|
||||
Node_compile_c_ko(node->peekFor.element, ko);
|
||||
restore(ok);
|
||||
end();
|
||||
}
|
||||
break;
|
||||
|
||||
case PeekNot:
|
||||
{
|
||||
int ok= yyl();
|
||||
begin();
|
||||
save(ok);
|
||||
Node_compile_c_ko(node->peekFor.element, ok);
|
||||
jump(ko);
|
||||
label(ok);
|
||||
restore(ok);
|
||||
end();
|
||||
}
|
||||
break;
|
||||
|
||||
case Query:
|
||||
{
|
||||
int qko= yyl(), qok= yyl();
|
||||
begin();
|
||||
save(qko);
|
||||
Node_compile_c_ko(node->query.element, qko);
|
||||
jump(qok);
|
||||
label(qko);
|
||||
restore(qko);
|
||||
end();
|
||||
label(qok);
|
||||
}
|
||||
break;
|
||||
|
||||
case Star:
|
||||
{
|
||||
int again= yyl(), out= yyl();
|
||||
label(again);
|
||||
begin();
|
||||
save(out);
|
||||
Node_compile_c_ko(node->star.element, out);
|
||||
jump(again);
|
||||
label(out);
|
||||
restore(out);
|
||||
end();
|
||||
}
|
||||
break;
|
||||
|
||||
case Plus:
|
||||
{
|
||||
int again= yyl(), out= yyl();
|
||||
Node_compile_c_ko(node->plus.element, ko);
|
||||
label(again);
|
||||
begin();
|
||||
save(out);
|
||||
Node_compile_c_ko(node->plus.element, out);
|
||||
jump(again);
|
||||
label(out);
|
||||
restore(out);
|
||||
end();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "\nNode_compile_c_ko: illegal node type %d\n", node->type);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int countVariables(Node *node)
|
||||
{
|
||||
int count= 0;
|
||||
while (node)
|
||||
{
|
||||
++count;
|
||||
node= node->variable.next;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
static void defineVariables(Node *node)
|
||||
{
|
||||
int count= 0;
|
||||
while (node)
|
||||
{
|
||||
fprintf(output, "#define %s ctx->val[%d]\n", node->variable.name, --count);
|
||||
node->variable.offset= count;
|
||||
node= node->variable.next;
|
||||
}
|
||||
fprintf(output, "#define yy ctx->yy\n");
|
||||
fprintf(output, "#define yypos ctx->pos\n");
|
||||
fprintf(output, "#define yythunkpos ctx->thunkpos\n");
|
||||
}
|
||||
|
||||
static void undefineVariables(Node *node)
|
||||
{
|
||||
fprintf(output, "#undef yythunkpos\n");
|
||||
fprintf(output, "#undef yypos\n");
|
||||
fprintf(output, "#undef yy\n");
|
||||
while (node)
|
||||
{
|
||||
fprintf(output, "#undef %s\n", node->variable.name);
|
||||
node= node->variable.next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void Rule_compile_c2(Node *node)
|
||||
{
|
||||
assert(node);
|
||||
assert(Rule == node->type);
|
||||
|
||||
if (!node->rule.expression)
|
||||
fprintf(stderr, "rule '%s' used but not defined\n", node->rule.name);
|
||||
else
|
||||
{
|
||||
int ko= yyl(), safe;
|
||||
|
||||
if ((!(RuleUsed & node->rule.flags)) && (node != start))
|
||||
fprintf(stderr, "rule '%s' defined but not used\n", node->rule.name);
|
||||
|
||||
safe= ((Query == node->rule.expression->type) || (Star == node->rule.expression->type));
|
||||
|
||||
fprintf(output, "\nYY_RULE(int) yy_%s(yycontext *ctx)\n{", node->rule.name);
|
||||
if (!safe) save(0);
|
||||
if (node->rule.variables)
|
||||
fprintf(output, " yyDo(ctx, yyPush, %d, 0);", countVariables(node->rule.variables));
|
||||
fprintf(output, "\n yyprintf((stderr, \"%%s\\n\", \"%s\"));", node->rule.name);
|
||||
Node_compile_c_ko(node->rule.expression, ko);
|
||||
fprintf(output, "\n yyprintf((stderr, \" ok %%s @ %%s\\n\", \"%s\", ctx->buf+ctx->pos));", node->rule.name);
|
||||
if (node->rule.variables)
|
||||
fprintf(output, " yyDo(ctx, yyPop, %d, 0);", countVariables(node->rule.variables));
|
||||
fprintf(output, "\n return 1;");
|
||||
if (!safe)
|
||||
{
|
||||
label(ko);
|
||||
restore(0);
|
||||
fprintf(output, "\n yyprintf((stderr, \" fail %%s @ %%s\\n\", \"%s\", ctx->buf+ctx->pos));", node->rule.name);
|
||||
fprintf(output, "\n return 0;");
|
||||
}
|
||||
fprintf(output, "\n}");
|
||||
}
|
||||
|
||||
if (node->rule.next)
|
||||
Rule_compile_c2(node->rule.next);
|
||||
}
|
||||
|
||||
static char *header= "\
|
||||
#include <stdio.h>\n\
|
||||
#include <stdlib.h>\n\
|
||||
#include <string.h>\n\
|
||||
";
|
||||
|
||||
static char *preamble= "\
|
||||
#ifndef YY_LOCAL\n\
|
||||
#define YY_LOCAL(T) static T\n\
|
||||
#endif\n\
|
||||
#ifndef YY_ACTION\n\
|
||||
#define YY_ACTION(T) static T\n\
|
||||
#endif\n\
|
||||
#ifndef YY_RULE\n\
|
||||
#define YY_RULE(T) static T\n\
|
||||
#endif\n\
|
||||
#ifndef YY_PARSE\n\
|
||||
#define YY_PARSE(T) T\n\
|
||||
#endif\n\
|
||||
#ifndef YYPARSE\n\
|
||||
#define YYPARSE yyparse\n\
|
||||
#endif\n\
|
||||
#ifndef YYPARSEFROM\n\
|
||||
#define YYPARSEFROM yyparsefrom\n\
|
||||
#endif\n\
|
||||
#ifndef YY_INPUT\n\
|
||||
#define YY_INPUT(buf, result, max_size) \\\n\
|
||||
{ \\\n\
|
||||
int yyc= getchar(); \\\n\
|
||||
result= (EOF == yyc) ? 0 : (*(buf)= yyc, 1); \\\n\
|
||||
yyprintf((stderr, \"<%c>\", yyc)); \\\n\
|
||||
}\n\
|
||||
#endif\n\
|
||||
#ifndef YY_BEGIN\n\
|
||||
#define YY_BEGIN ( ctx->begin= ctx->pos, 1)\n\
|
||||
#endif\n\
|
||||
#ifndef YY_END\n\
|
||||
#define YY_END ( ctx->end= ctx->pos, 1)\n\
|
||||
#endif\n\
|
||||
#ifdef YY_DEBUG\n\
|
||||
# define yyprintf(args) fprintf args\n\
|
||||
#else\n\
|
||||
# define yyprintf(args)\n\
|
||||
#endif\n\
|
||||
#ifndef YYSTYPE\n\
|
||||
#define YYSTYPE int\n\
|
||||
#endif\n\
|
||||
\n\
|
||||
#ifndef YY_PART\n\
|
||||
\n\
|
||||
typedef struct _yycontext yycontext;\n\
|
||||
typedef void (*yyaction)(yycontext *ctx, char *yytext, int yyleng);\n\
|
||||
typedef struct _yythunk { int begin, end; yyaction action; struct _yythunk *next; } yythunk;\n\
|
||||
\n\
|
||||
struct _yycontext {\n\
|
||||
char *buf;\n\
|
||||
int buflen;\n\
|
||||
int pos;\n\
|
||||
int limit;\n\
|
||||
char *text;\n\
|
||||
int textlen;\n\
|
||||
int begin;\n\
|
||||
int end;\n\
|
||||
int textmax;\n\
|
||||
yythunk *thunks;\n\
|
||||
int thunkslen;\n\
|
||||
int thunkpos;\n\
|
||||
YYSTYPE yy;\n\
|
||||
YYSTYPE *val;\n\
|
||||
YYSTYPE *vals;\n\
|
||||
int valslen;\n\
|
||||
#ifdef YY_CTX_MEMBERS\n\
|
||||
YY_CTX_MEMBERS\n\
|
||||
#endif\n\
|
||||
};\n\
|
||||
\n\
|
||||
#ifdef YY_CTX_LOCAL\n\
|
||||
#define YY_CTX_PARAM_ yycontext *yyctx,\n\
|
||||
#define YY_CTX_PARAM yycontext *yyctx\n\
|
||||
#define YY_CTX_ARG_ yyctx,\n\
|
||||
#define YY_CTX_ARG yyctx\n\
|
||||
#else\n\
|
||||
#define YY_CTX_PARAM_\n\
|
||||
#define YY_CTX_PARAM\n\
|
||||
#define YY_CTX_ARG_\n\
|
||||
#define YY_CTX_ARG\n\
|
||||
yycontext yyctx0;\n\
|
||||
yycontext *yyctx= &yyctx0;\n\
|
||||
#endif\n\
|
||||
\n\
|
||||
YY_LOCAL(int) yyrefill(yycontext *ctx)\n\
|
||||
{\n\
|
||||
int yyn;\n\
|
||||
while (ctx->buflen - ctx->pos < 512)\n\
|
||||
{\n\
|
||||
ctx->buflen *= 2;\n\
|
||||
ctx->buf= (char *)realloc(ctx->buf, ctx->buflen);\n\
|
||||
}\n\
|
||||
YY_INPUT((ctx->buf + ctx->pos), yyn, (ctx->buflen - ctx->pos));\n\
|
||||
if (!yyn) return 0;\n\
|
||||
ctx->limit += yyn;\n\
|
||||
return 1;\n\
|
||||
}\n\
|
||||
\n\
|
||||
YY_LOCAL(int) yymatchDot(yycontext *ctx)\n\
|
||||
{\n\
|
||||
if (ctx->pos >= ctx->limit && !yyrefill(ctx)) return 0;\n\
|
||||
++ctx->pos;\n\
|
||||
return 1;\n\
|
||||
}\n\
|
||||
\n\
|
||||
YY_LOCAL(int) yymatchChar(yycontext *ctx, int c)\n\
|
||||
{\n\
|
||||
if (ctx->pos >= ctx->limit && !yyrefill(ctx)) return 0;\n\
|
||||
if ((unsigned char)ctx->buf[ctx->pos] == c)\n\
|
||||
{\n\
|
||||
++ctx->pos;\n\
|
||||
yyprintf((stderr, \" ok yymatchChar(ctx, %c) @ %s\\n\", c, ctx->buf+ctx->pos));\n\
|
||||
return 1;\n\
|
||||
}\n\
|
||||
yyprintf((stderr, \" fail yymatchChar(ctx, %c) @ %s\\n\", c, ctx->buf+ctx->pos));\n\
|
||||
return 0;\n\
|
||||
}\n\
|
||||
\n\
|
||||
YY_LOCAL(int) yymatchString(yycontext *ctx, char *s)\n\
|
||||
{\n\
|
||||
int yysav= ctx->pos;\n\
|
||||
while (*s)\n\
|
||||
{\n\
|
||||
if (ctx->pos >= ctx->limit && !yyrefill(ctx)) return 0;\n\
|
||||
if (ctx->buf[ctx->pos] != *s)\n\
|
||||
{\n\
|
||||
ctx->pos= yysav;\n\
|
||||
return 0;\n\
|
||||
}\n\
|
||||
++s;\n\
|
||||
++ctx->pos;\n\
|
||||
}\n\
|
||||
return 1;\n\
|
||||
}\n\
|
||||
\n\
|
||||
YY_LOCAL(int) yymatchClass(yycontext *ctx, unsigned char *bits)\n\
|
||||
{\n\
|
||||
int c;\n\
|
||||
if (ctx->pos >= ctx->limit && !yyrefill(ctx)) return 0;\n\
|
||||
c= (unsigned char)ctx->buf[ctx->pos];\n\
|
||||
if (bits[c >> 3] & (1 << (c & 7)))\n\
|
||||
{\n\
|
||||
++ctx->pos;\n\
|
||||
yyprintf((stderr, \" ok yymatchClass @ %s\\n\", ctx->buf+ctx->pos));\n\
|
||||
return 1;\n\
|
||||
}\n\
|
||||
yyprintf((stderr, \" fail yymatchClass @ %s\\n\", ctx->buf+ctx->pos));\n\
|
||||
return 0;\n\
|
||||
}\n\
|
||||
\n\
|
||||
YY_LOCAL(void) yyDo(yycontext *ctx, yyaction action, int begin, int end)\n\
|
||||
{\n\
|
||||
while (ctx->thunkpos >= ctx->thunkslen)\n\
|
||||
{\n\
|
||||
ctx->thunkslen *= 2;\n\
|
||||
ctx->thunks= (yythunk *)realloc(ctx->thunks, sizeof(yythunk) * ctx->thunkslen);\n\
|
||||
}\n\
|
||||
ctx->thunks[ctx->thunkpos].begin= begin;\n\
|
||||
ctx->thunks[ctx->thunkpos].end= end;\n\
|
||||
ctx->thunks[ctx->thunkpos].action= action;\n\
|
||||
++ctx->thunkpos;\n\
|
||||
}\n\
|
||||
\n\
|
||||
YY_LOCAL(int) yyText(yycontext *ctx, int begin, int end)\n\
|
||||
{\n\
|
||||
int yyleng= end - begin;\n\
|
||||
if (yyleng <= 0)\n\
|
||||
yyleng= 0;\n\
|
||||
else\n\
|
||||
{\n\
|
||||
while (ctx->textlen < (yyleng + 1))\n\
|
||||
{\n\
|
||||
ctx->textlen *= 2;\n\
|
||||
ctx->text= (char *)realloc(ctx->text, ctx->textlen);\n\
|
||||
}\n\
|
||||
memcpy(ctx->text, ctx->buf + begin, yyleng);\n\
|
||||
}\n\
|
||||
ctx->text[yyleng]= '\\0';\n\
|
||||
return yyleng;\n\
|
||||
}\n\
|
||||
\n\
|
||||
YY_LOCAL(void) yyDone(yycontext *ctx)\n\
|
||||
{\n\
|
||||
int pos;\n\
|
||||
for (pos= 0; pos < ctx->thunkpos; ++pos)\n\
|
||||
{\n\
|
||||
yythunk *thunk= &ctx->thunks[pos];\n\
|
||||
int yyleng= thunk->end ? yyText(ctx, thunk->begin, thunk->end) : thunk->begin;\n\
|
||||
yyprintf((stderr, \"DO [%d] %p %s\\n\", pos, thunk->action, ctx->text));\n\
|
||||
thunk->action(ctx, ctx->text, yyleng);\n\
|
||||
}\n\
|
||||
ctx->thunkpos= 0;\n\
|
||||
}\n\
|
||||
\n\
|
||||
YY_LOCAL(void) yyCommit(yycontext *ctx)\n\
|
||||
{\n\
|
||||
if ((ctx->limit -= ctx->pos))\n\
|
||||
{\n\
|
||||
memmove(ctx->buf, ctx->buf + ctx->pos, ctx->limit);\n\
|
||||
}\n\
|
||||
ctx->begin -= ctx->pos;\n\
|
||||
ctx->end -= ctx->pos;\n\
|
||||
ctx->pos= ctx->thunkpos= 0;\n\
|
||||
}\n\
|
||||
\n\
|
||||
YY_LOCAL(int) yyAccept(yycontext *ctx, int tp0)\n\
|
||||
{\n\
|
||||
if (tp0)\n\
|
||||
{\n\
|
||||
fprintf(stderr, \"accept denied at %d\\n\", tp0);\n\
|
||||
return 0;\n\
|
||||
}\n\
|
||||
else\n\
|
||||
{\n\
|
||||
yyDone(ctx);\n\
|
||||
yyCommit(ctx);\n\
|
||||
}\n\
|
||||
return 1;\n\
|
||||
}\n\
|
||||
\n\
|
||||
YY_LOCAL(void) yyPush(yycontext *ctx, char *text, int count) { ctx->val += count; }\n\
|
||||
YY_LOCAL(void) yyPop(yycontext *ctx, char *text, int count) { ctx->val -= count; }\n\
|
||||
YY_LOCAL(void) yySet(yycontext *ctx, char *text, int count) { ctx->val[count]= ctx->yy; }\n\
|
||||
\n\
|
||||
#endif /* YY_PART */\n\
|
||||
\n\
|
||||
#define YYACCEPT yyAccept(ctx, yythunkpos0)\n\
|
||||
\n\
|
||||
";
|
||||
|
||||
static char *footer= "\n\
|
||||
\n\
|
||||
#ifndef YY_PART\n\
|
||||
\n\
|
||||
typedef int (*yyrule)(yycontext *ctx);\n\
|
||||
\n\
|
||||
YY_PARSE(int) YYPARSEFROM(YY_CTX_PARAM_ yyrule yystart)\n\
|
||||
{\n\
|
||||
int yyok;\n\
|
||||
if (!yyctx->buflen)\n\
|
||||
{\n\
|
||||
yyctx->buflen= 1024;\n\
|
||||
yyctx->buf= (char *)malloc(yyctx->buflen);\n\
|
||||
yyctx->textlen= 1024;\n\
|
||||
yyctx->text= (char *)malloc(yyctx->textlen);\n\
|
||||
yyctx->thunkslen= 32;\n\
|
||||
yyctx->thunks= (yythunk *)malloc(sizeof(yythunk) * yyctx->thunkslen);\n\
|
||||
yyctx->valslen= 32;\n\
|
||||
yyctx->vals= (YYSTYPE *)malloc(sizeof(YYSTYPE) * yyctx->valslen);\n\
|
||||
yyctx->begin= yyctx->end= yyctx->pos= yyctx->limit= yyctx->thunkpos= 0;\n\
|
||||
}\n\
|
||||
yyctx->begin= yyctx->end= yyctx->pos;\n\
|
||||
yyctx->thunkpos= 0;\n\
|
||||
yyctx->val= yyctx->vals;\n\
|
||||
yyok= yystart(yyctx);\n\
|
||||
if (yyok) yyDone(yyctx);\n\
|
||||
yyCommit(yyctx);\n\
|
||||
return yyok;\n\
|
||||
}\n\
|
||||
\n\
|
||||
YY_PARSE(int) YYPARSE(YY_CTX_PARAM)\n\
|
||||
{\n\
|
||||
return YYPARSEFROM(YY_CTX_ARG_ yy_%s);\n\
|
||||
}\n\
|
||||
\n\
|
||||
#endif\n\
|
||||
";
|
||||
|
||||
void Rule_compile_c_header(void)
|
||||
{
|
||||
fprintf(output, "/* A recursive-descent parser generated by peg %d.%d.%d */\n", PEG_MAJOR, PEG_MINOR, PEG_LEVEL);
|
||||
fprintf(output, "\n");
|
||||
fprintf(output, "%s", header);
|
||||
fprintf(output, "#define YYRULECOUNT %d\n", ruleCount);
|
||||
}
|
||||
|
||||
int consumesInput(Node *node)
|
||||
{
|
||||
if (!node) return 0;
|
||||
|
||||
switch (node->type)
|
||||
{
|
||||
case Rule:
|
||||
{
|
||||
int result= 0;
|
||||
if (RuleReached & node->rule.flags)
|
||||
fprintf(stderr, "possible infinite left recursion in rule '%s'\n", node->rule.name);
|
||||
else
|
||||
{
|
||||
node->rule.flags |= RuleReached;
|
||||
result= consumesInput(node->rule.expression);
|
||||
node->rule.flags &= ~RuleReached;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
break;
|
||||
|
||||
case Dot: return 1;
|
||||
case Name: return consumesInput(node->name.rule);
|
||||
case Character:
|
||||
case String: return strlen(node->string.value) > 0;
|
||||
case Class: return 1;
|
||||
case Action: return 0;
|
||||
case Predicate: return 0;
|
||||
|
||||
case Alternate:
|
||||
{
|
||||
Node *n;
|
||||
for (n= node->alternate.first; n; n= n->alternate.next)
|
||||
if (!consumesInput(n))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
|
||||
case Sequence:
|
||||
{
|
||||
Node *n;
|
||||
for (n= node->alternate.first; n; n= n->alternate.next)
|
||||
if (consumesInput(n))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
||||
case PeekFor: return 0;
|
||||
case PeekNot: return 0;
|
||||
case Query: return 0;
|
||||
case Star: return 0;
|
||||
case Plus: return consumesInput(node->plus.element);
|
||||
|
||||
default:
|
||||
fprintf(stderr, "\nconsumesInput: illegal node type %d\n", node->type);
|
||||
exit(1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void Rule_compile_c(Node *node)
|
||||
{
|
||||
Node *n;
|
||||
|
||||
for (n= rules; n; n= n->rule.next)
|
||||
consumesInput(n);
|
||||
|
||||
fprintf(output, "%s", preamble);
|
||||
for (n= node; n; n= n->rule.next)
|
||||
fprintf(output, "YY_RULE(int) yy_%s(yycontext *ctx); /* %d */\n", n->rule.name, n->rule.id);
|
||||
fprintf(output, "\n");
|
||||
for (n= actions; n; n= n->action.list)
|
||||
{
|
||||
fprintf(output, "YY_ACTION(void) yy%s(yycontext *ctx, char *yytext, int yyleng)\n{\n", n->action.name);
|
||||
defineVariables(n->action.rule->rule.variables);
|
||||
fprintf(output, " yyprintf((stderr, \"do yy%s\\n\"));\n", n->action.name);
|
||||
fprintf(output, " %s;\n", n->action.text);
|
||||
undefineVariables(n->action.rule->rule.variables);
|
||||
fprintf(output, "}\n");
|
||||
}
|
||||
Rule_compile_c2(node);
|
||||
fprintf(output, footer, start->rule.name);
|
||||
}
|
88
supportlibs/pegmarkdown/peg-0.1.9/examples/Makefile
Normal file
88
supportlibs/pegmarkdown/peg-0.1.9/examples/Makefile
Normal file
@ -0,0 +1,88 @@
|
||||
EXAMPLES = test rule accept wc dc dcv calc basic localctx
|
||||
|
||||
CFLAGS = -g -O3
|
||||
|
||||
DIFF = diff
|
||||
TEE = cat >
|
||||
|
||||
all : $(EXAMPLES)
|
||||
|
||||
test : .FORCE
|
||||
../peg -o test.peg.c test.peg
|
||||
$(CC) $(CFLAGS) -o test test.c
|
||||
echo 'ab.ac.ad.ae.afg.afh.afg.afh.afi.afj.' | ./$@ | $(TEE) $@.out
|
||||
$(DIFF) $@.ref $@.out
|
||||
rm -f $@.out
|
||||
@echo
|
||||
|
||||
rule : .FORCE
|
||||
../peg -o rule.peg.c rule.peg
|
||||
$(CC) $(CFLAGS) -o rule rule.c
|
||||
echo 'abcbcdabcbcdabcbcdabcbcd' | ./$@ | $(TEE) $@.out
|
||||
$(DIFF) $@.ref $@.out
|
||||
rm -f $@.out
|
||||
@echo
|
||||
|
||||
accept : .FORCE
|
||||
../peg -o accept.peg.c accept.peg
|
||||
$(CC) $(CFLAGS) -o accept accept.c
|
||||
echo 'abcbcdabcbcdabcbcdabcbcd' | ./$@ | $(TEE) $@.out
|
||||
$(DIFF) $@.ref $@.out
|
||||
rm -f $@.out
|
||||
@echo
|
||||
|
||||
wc : .FORCE
|
||||
../leg -o wc.leg.c wc.leg
|
||||
$(CC) $(CFLAGS) -o wc wc.leg.c
|
||||
cat wc.leg | ./$@ | $(TEE) $@.out
|
||||
$(DIFF) $@.ref $@.out
|
||||
rm -f $@.out
|
||||
@echo
|
||||
|
||||
dc : .FORCE
|
||||
../peg -o dc.peg.c dc.peg
|
||||
$(CC) $(CFLAGS) -o dc dc.c
|
||||
echo ' 2 *3 *(3+ 4) ' | ./dc | $(TEE) $@.out
|
||||
$(DIFF) $@.ref $@.out
|
||||
rm -f $@.out
|
||||
@echo
|
||||
|
||||
dcv : .FORCE
|
||||
../peg -o dcv.peg.c dcv.peg
|
||||
$(CC) $(CFLAGS) -o dcv dcv.c
|
||||
echo 'a = 6; b = 7; a * b' | ./dcv | $(TEE) $@.out
|
||||
$(DIFF) $@.ref $@.out
|
||||
rm -f $@.out
|
||||
@echo
|
||||
|
||||
calc : .FORCE
|
||||
../leg -o calc.leg.c calc.leg
|
||||
$(CC) $(CFLAGS) -o calc calc.leg.c
|
||||
echo 'a = 6; b = 7; a * b' | ./calc | $(TEE) $@.out
|
||||
$(DIFF) $@.ref $@.out
|
||||
rm -f $@.out
|
||||
@echo
|
||||
|
||||
basic : .FORCE
|
||||
../leg -o basic.leg.c basic.leg
|
||||
$(CC) $(CFLAGS) -o basic basic.leg.c
|
||||
( echo 'load "test"'; echo "run" ) | ./basic | $(TEE) $@.out
|
||||
$(DIFF) $@.ref $@.out
|
||||
rm -f $@.out
|
||||
@echo
|
||||
|
||||
localctx : .FORCE
|
||||
../peg -o test.peg.c test.peg
|
||||
$(CC) $(CFLAGS) -o localctx localctx.c
|
||||
echo 'ab.ac.ad.ae.afg.afh.afg.afh.afi.afj.' | ./$@ | $(TEE) $@.out
|
||||
$(DIFF) $@.ref $@.out
|
||||
rm -f $@.out
|
||||
@echo
|
||||
|
||||
clean : .FORCE
|
||||
rm -f *~ *.o *.[pl]eg.[cd] $(EXAMPLES)
|
||||
rm -rf *.dSYM
|
||||
|
||||
spotless : clean
|
||||
|
||||
.FORCE :
|
11
supportlibs/pegmarkdown/peg-0.1.9/examples/accept.c
Normal file
11
supportlibs/pegmarkdown/peg-0.1.9/examples/accept.c
Normal file
@ -0,0 +1,11 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "accept.peg.c"
|
||||
|
||||
int main()
|
||||
{
|
||||
while (yyparse());
|
||||
|
||||
return 0;
|
||||
}
|
8
supportlibs/pegmarkdown/peg-0.1.9/examples/accept.peg
Normal file
8
supportlibs/pegmarkdown/peg-0.1.9/examples/accept.peg
Normal file
@ -0,0 +1,8 @@
|
||||
start <- abcd+
|
||||
|
||||
abcd <- 'a' { printf("A %d\n", yypos); } bc { printf("ABC %d\n", yypos); } &{YYACCEPT}
|
||||
/ 'b' { printf("B %d\n", yypos); } cd { printf("BCD %d\n", yypos); } &{YYACCEPT}
|
||||
|
||||
bc <- 'b' { printf("B %d\n", yypos); } 'c' { printf("C %d\n", yypos); }
|
||||
|
||||
cd <- 'c' { printf("C %d\n", yypos); } 'd' { printf("D %d\n", yypos); }
|
32
supportlibs/pegmarkdown/peg-0.1.9/examples/accept.ref
Normal file
32
supportlibs/pegmarkdown/peg-0.1.9/examples/accept.ref
Normal file
@ -0,0 +1,32 @@
|
||||
A 3
|
||||
B 3
|
||||
C 3
|
||||
ABC 3
|
||||
B 3
|
||||
C 3
|
||||
D 3
|
||||
BCD 3
|
||||
A 3
|
||||
B 3
|
||||
C 3
|
||||
ABC 3
|
||||
B 3
|
||||
C 3
|
||||
D 3
|
||||
BCD 3
|
||||
A 3
|
||||
B 3
|
||||
C 3
|
||||
ABC 3
|
||||
B 3
|
||||
C 3
|
||||
D 3
|
||||
BCD 3
|
||||
A 3
|
||||
B 3
|
||||
C 3
|
||||
ABC 3
|
||||
B 3
|
||||
C 3
|
||||
D 3
|
||||
BCD 3
|
361
supportlibs/pegmarkdown/peg-0.1.9/examples/basic.leg
Normal file
361
supportlibs/pegmarkdown/peg-0.1.9/examples/basic.leg
Normal file
@ -0,0 +1,361 @@
|
||||
# A 'syntax-directed interpreter' (all execution is a side-effect of parsing).
|
||||
# Inspired by Dennis Allison's original Tiny BASIC grammar, circa 1975.
|
||||
#
|
||||
# Copyright (c) 2007 by Ian Piumarta
|
||||
# All rights reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the 'Software'),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, provided that the above copyright notice(s) and this
|
||||
# permission notice appear in all copies of the Software. Acknowledgement
|
||||
# of the use of this Software in supporting documentation would be
|
||||
# appreciated but is not required.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED 'AS IS'. USE ENTIRELY AT YOUR OWN RISK.
|
||||
#
|
||||
# Last edited: 2012-04-29 15:14:06 by piumarta on emilia
|
||||
|
||||
%{
|
||||
# include <stdio.h>
|
||||
|
||||
typedef struct line line;
|
||||
|
||||
struct line
|
||||
{
|
||||
int number;
|
||||
int length;
|
||||
char *text;
|
||||
};
|
||||
|
||||
line *lines= 0;
|
||||
int numLines= 0;
|
||||
int pc= -1, epc= -1;
|
||||
int batch= 0;
|
||||
|
||||
int nextline(char *buf, int max);
|
||||
|
||||
# define min(x, y) ((x) < (y) ? (x) : (y))
|
||||
|
||||
# define YY_INPUT(buf, result, max_size) \
|
||||
{ \
|
||||
if ((pc >= 0) && (pc < numLines)) \
|
||||
{ \
|
||||
line *linep= lines+pc++; \
|
||||
result= min(max_size, linep->length); \
|
||||
memcpy(buf, linep->text, result); \
|
||||
} \
|
||||
else \
|
||||
result= nextline(buf, max_size); \
|
||||
}
|
||||
|
||||
union value {
|
||||
int number;
|
||||
char *string;
|
||||
int (*binop)(int lhs, int rhs);
|
||||
};
|
||||
|
||||
# define YYSTYPE union value
|
||||
|
||||
int variables[26];
|
||||
|
||||
void accept(int number, char *line);
|
||||
|
||||
void save(char *name);
|
||||
void load(char *name);
|
||||
void type(char *name);
|
||||
|
||||
int lessThan(int lhs, int rhs) { return lhs < rhs; }
|
||||
int lessEqual(int lhs, int rhs) { return lhs <= rhs; }
|
||||
int notEqual(int lhs, int rhs) { return lhs != rhs; }
|
||||
int equalTo(int lhs, int rhs) { return lhs == rhs; }
|
||||
int greaterEqual(int lhs, int rhs) { return lhs >= rhs; }
|
||||
int greaterThan(int lhs, int rhs) { return lhs > rhs; }
|
||||
|
||||
int input(void);
|
||||
|
||||
int stack[1024], sp= 0;
|
||||
|
||||
char *help;
|
||||
|
||||
void error(char *fmt, ...);
|
||||
int findLine(int n, int create);
|
||||
%}
|
||||
|
||||
line = - s:statement CR
|
||||
| - n:number < ( !CR . )* CR > { accept(n.number, yytext); }
|
||||
| - CR
|
||||
| - < ( !CR . )* CR > { epc= pc; error("syntax error"); }
|
||||
| - !. { exit(0); }
|
||||
|
||||
statement = 'print'- expr-list
|
||||
| 'if'- e1:expression r:relop e2:expression { if (!r.binop(e1.number, e2.number)) yythunkpos= 0; }
|
||||
'then'- statement
|
||||
| 'goto'- e:expression { epc= pc; if ((pc= findLine(e.number, 0)) < 0) error("no such line"); }
|
||||
| 'input'- var-list
|
||||
| 'let'- v:var EQUAL e:expression { variables[v.number]= e.number; }
|
||||
| 'gosub'- e:expression { epc= pc; if (sp < 1024) stack[sp++]= pc, pc= findLine(e.number, 0); else error("too many gosubs");
|
||||
if (pc < 0) error("no such line"); }
|
||||
| 'return'- { epc= pc; if ((pc= sp ? stack[--sp] : -1) < 0) error("no gosub"); }
|
||||
| 'clear'- { while (numLines) accept(lines->number, "\n"); }
|
||||
| 'list'- { int i; for (i= 0; i < numLines; ++i) printf("%5d %s", lines[i].number, lines[i].text); }
|
||||
| 'run'- s:string { load(s.string); pc= 0; }
|
||||
| 'run'- { pc= 0; }
|
||||
| 'end'- { pc= -1; if (batch) exit(0); }
|
||||
| 'rem'- ( !CR . )*
|
||||
| ('bye'|'quit'|'exit')- { exit(0); }
|
||||
| 'save'- s:string { save(s.string); }
|
||||
| 'load'- s:string { load(s.string); }
|
||||
| 'type'- s:string { type(s.string); }
|
||||
| 'dir'- { system("ls *.bas"); }
|
||||
| 'help'- { fprintf(stderr, "%s", help); }
|
||||
|
||||
expr-list = ( e:string { printf("%s", e.string); }
|
||||
| e:expression { printf("%d", e.number); }
|
||||
)? ( COMMA ( e:string { printf("%s", e.string); }
|
||||
| e:expression { printf("%d", e.number); }
|
||||
)
|
||||
)* ( COMMA
|
||||
| !COMMA { printf("\n"); }
|
||||
)
|
||||
|
||||
var-list = v:var { variables[v.number]= input(); }
|
||||
( COMMA v:var { variables[v.number]= input(); }
|
||||
)*
|
||||
|
||||
expression = ( PLUS? l:term
|
||||
| MINUS l:term { l.number = -l.number }
|
||||
) ( PLUS r:term { l.number += r.number }
|
||||
| MINUS r:term { l.number -= r.number }
|
||||
)* { $$.number = l.number }
|
||||
|
||||
term = l:factor ( STAR r:factor { l.number *= r.number }
|
||||
| SLASH r:factor { l.number /= r.number }
|
||||
)* { $$.number = l.number }
|
||||
|
||||
factor = v:var { $$.number = variables[v.number] }
|
||||
| n:number
|
||||
| OPEN expression CLOSE
|
||||
|
||||
var = < [a-z] > - { $$.number = yytext[0] - 'a' }
|
||||
|
||||
number = < digit+ > - { $$.number = atoi(yytext); }
|
||||
|
||||
digit = [0-9]
|
||||
|
||||
string = '"' < [^\"]* > '"' - { $$.string = yytext; }
|
||||
|
||||
relop = '<=' - { $$.binop= lessEqual; }
|
||||
| '<>' - { $$.binop= notEqual; }
|
||||
| '<' - { $$.binop= lessThan; }
|
||||
| '>=' - { $$.binop= greaterEqual; }
|
||||
| '>' - { $$.binop= greaterThan; }
|
||||
| '=' - { $$.binop= equalTo; }
|
||||
|
||||
EQUAL = '=' - CLOSE = ')' - OPEN = '(' -
|
||||
SLASH = '/' - STAR = '*' - MINUS = '-' -
|
||||
PLUS = '+' - COMMA = ',' -
|
||||
|
||||
- = [ \t]*
|
||||
|
||||
CR = '\n' | '\r' | '\r\n'
|
||||
|
||||
%%
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
char *help=
|
||||
"print <num>|<string> [, <num>|<string> ...] [,]\n"
|
||||
"if <expr> <|<=|<>|=|>=|> <expr> then <stmt>\n"
|
||||
"input <var> [, <var> ...] let <var> = <expr>\n"
|
||||
"goto <expr> gosub <expr>\n"
|
||||
"end return\n"
|
||||
"list clear\n"
|
||||
"run [\"filename\"] rem <comment...>\n"
|
||||
"dir type \"filename\"\n"
|
||||
"save \"filename\" load \"filename\"\n"
|
||||
"bye|quit|exit help\n"
|
||||
;
|
||||
|
||||
void error(char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
if (epc > 0)
|
||||
fprintf(stderr, "\nline %d: %s", lines[epc-1].number, lines[epc-1].text);
|
||||
else
|
||||
fprintf(stderr, "\n");
|
||||
vfprintf(stderr, fmt, ap);
|
||||
fprintf(stderr, "\n");
|
||||
va_end(ap);
|
||||
epc= pc= -1;
|
||||
}
|
||||
|
||||
#ifdef USE_READLINE
|
||||
# include <readline/readline.h>
|
||||
# include <readline/history.h>
|
||||
#endif
|
||||
|
||||
int nextline(char *buf, int max)
|
||||
{
|
||||
pc= -1;
|
||||
if (batch) exit(0);
|
||||
if (isatty(fileno(stdin)))
|
||||
{
|
||||
# ifdef USE_READLINE
|
||||
char *line= readline(">");
|
||||
if (line)
|
||||
{
|
||||
int len= strlen(line);
|
||||
if (len >= max) len= max - 1;
|
||||
strncpy(buf, line, len);
|
||||
(buf)[len]= '\n';
|
||||
add_history(line);
|
||||
free(line);
|
||||
return len + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
||||
# endif
|
||||
putchar('>');
|
||||
fflush(stdout);
|
||||
}
|
||||
return fgets(buf, max, stdin) ? strlen(buf) : 0;
|
||||
}
|
||||
|
||||
int maxLines= 0;
|
||||
|
||||
int findLine(int n, int create)
|
||||
{
|
||||
int lo= 0, hi= numLines - 1;
|
||||
while (lo <= hi)
|
||||
{
|
||||
int mid= (lo + hi) / 2, lno= lines[mid].number;
|
||||
if (lno > n)
|
||||
hi= mid - 1;
|
||||
else if (lno < n)
|
||||
lo= mid + 1;
|
||||
else
|
||||
return mid;
|
||||
}
|
||||
if (create)
|
||||
{
|
||||
if (numLines == maxLines)
|
||||
{
|
||||
maxLines *= 2;
|
||||
lines= realloc(lines, sizeof(line) * maxLines);
|
||||
}
|
||||
if (lo < numLines)
|
||||
memmove(lines + lo + 1, lines + lo, sizeof(line) * (numLines - lo));
|
||||
++numLines;
|
||||
lines[lo].number= n;
|
||||
lines[lo].text= 0;
|
||||
return lo;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void accept(int n, char *s)
|
||||
{
|
||||
if (s[0] < 32) /* delete */
|
||||
{
|
||||
int lno= findLine(n, 0);
|
||||
if (lno >= 0)
|
||||
{
|
||||
if (lno < numLines - 1)
|
||||
memmove(lines + lno, lines + lno + 1, sizeof(line) * (numLines - lno - 1));
|
||||
--numLines;
|
||||
}
|
||||
}
|
||||
else /* insert */
|
||||
{
|
||||
int lno= findLine(n, 1);
|
||||
if (lines[lno].text) free(lines[lno].text);
|
||||
lines[lno].length= strlen(s);
|
||||
lines[lno].text= strdup(s);
|
||||
}
|
||||
}
|
||||
|
||||
char *extend(char *name)
|
||||
{
|
||||
static char path[1024];
|
||||
int len= strlen(name);
|
||||
sprintf(path, "%s%s", name, (((len > 4) && !strcasecmp(".bas", name + len - 4)) ? "" : ".bas"));
|
||||
return path;
|
||||
}
|
||||
|
||||
void save(char *name)
|
||||
{
|
||||
FILE *f= fopen(name= extend(name), "w");
|
||||
if (!f)
|
||||
perror(name);
|
||||
else
|
||||
{
|
||||
int i;
|
||||
for (i= 0; i < numLines; ++i)
|
||||
fprintf(f, "%d %s", lines[i].number, lines[i].text);
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
|
||||
void load(char *name)
|
||||
{
|
||||
FILE *f= fopen(name= extend(name), "r");
|
||||
if (!f)
|
||||
perror(name);
|
||||
else
|
||||
{
|
||||
int lineNumber;
|
||||
char lineText[1024];
|
||||
while ((1 == fscanf(f, " %d ", &lineNumber)) && fgets(lineText, sizeof(lineText), f))
|
||||
accept(lineNumber, lineText);
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
|
||||
void type(char *name)
|
||||
{
|
||||
FILE *f= fopen(name= extend(name), "r");
|
||||
if (!f)
|
||||
perror(name);
|
||||
else
|
||||
{
|
||||
int c, d;
|
||||
while ((c= getc(f)) >= 0)
|
||||
putchar(d= c);
|
||||
fclose(f);
|
||||
if ('\n' != d && '\r' != d) putchar('\n');
|
||||
}
|
||||
}
|
||||
|
||||
int input(void)
|
||||
{
|
||||
char line[32];
|
||||
fgets(line, sizeof(line), stdin);
|
||||
return atoi(line);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
lines= malloc(sizeof(line) * (maxLines= 32));
|
||||
numLines= 0;
|
||||
|
||||
if (argc > 1)
|
||||
{
|
||||
batch= 1;
|
||||
while (argc-- > 1)
|
||||
load(*++argv);
|
||||
pc= 0;
|
||||
}
|
||||
|
||||
while (!feof(stdin))
|
||||
yyparse();
|
||||
|
||||
return 0;
|
||||
}
|
10
supportlibs/pegmarkdown/peg-0.1.9/examples/basic.ref
Normal file
10
supportlibs/pegmarkdown/peg-0.1.9/examples/basic.ref
Normal file
@ -0,0 +1,10 @@
|
||||
1
|
||||
2 4
|
||||
3 6 9
|
||||
4 8 12 16
|
||||
5 10 15 20 25
|
||||
6 12 18 24 30 36
|
||||
7 14 21 28 35 42 49
|
||||
8 16 24 32 40 48 56 64
|
||||
9 18 27 36 45 54 63 72 81
|
||||
10 20 30 40 50 60 70 80 90 100
|
8
supportlibs/pegmarkdown/peg-0.1.9/examples/bench.bas
Normal file
8
supportlibs/pegmarkdown/peg-0.1.9/examples/bench.bas
Normal file
@ -0,0 +1,8 @@
|
||||
100 let n=100000
|
||||
120 let m=0
|
||||
110 let s=0
|
||||
130 let m=m+1
|
||||
140 let s=s+m
|
||||
150 if m<n then goto 130
|
||||
160 print "interpreted ", n*3, " lines of code; answer is ", s
|
||||
170 end
|
46
supportlibs/pegmarkdown/peg-0.1.9/examples/calc.leg
Normal file
46
supportlibs/pegmarkdown/peg-0.1.9/examples/calc.leg
Normal file
@ -0,0 +1,46 @@
|
||||
%{
|
||||
#include <stdio.h>
|
||||
int vars[26];
|
||||
%}
|
||||
|
||||
Stmt = - e:Expr EOL { printf("%d\n", e); }
|
||||
| ( !EOL . )* EOL { printf("error\n"); }
|
||||
|
||||
Expr = i:ID ASSIGN s:Sum { $$= vars[i]= s; }
|
||||
| s:Sum { $$= s; }
|
||||
|
||||
Sum = l:Product
|
||||
( PLUS r:Product { l += r; }
|
||||
| MINUS r:Product { l -= r; }
|
||||
)* { $$= l; }
|
||||
|
||||
Product = l:Value
|
||||
( TIMES r:Value { l *= r; }
|
||||
| DIVIDE r:Value { l /= r; }
|
||||
)* { $$= l; }
|
||||
|
||||
Value = i:NUMBER { $$= atoi(yytext); }
|
||||
| i:ID !ASSIGN { $$= vars[i]; }
|
||||
| OPEN i:Expr CLOSE { $$= i; }
|
||||
|
||||
NUMBER = < [0-9]+ > - { $$= atoi(yytext); }
|
||||
ID = < [a-z] > - { $$= yytext[0] - 'a'; }
|
||||
ASSIGN = '=' -
|
||||
PLUS = '+' -
|
||||
MINUS = '-' -
|
||||
TIMES = '*' -
|
||||
DIVIDE = '/' -
|
||||
OPEN = '(' -
|
||||
CLOSE = ')' -
|
||||
|
||||
- = [ \t]*
|
||||
EOL = '\n' | '\r\n' | '\r' | ';'
|
||||
|
||||
%%
|
||||
|
||||
int main()
|
||||
{
|
||||
while (yyparse());
|
||||
|
||||
return 0;
|
||||
}
|
3
supportlibs/pegmarkdown/peg-0.1.9/examples/calc.ref
Normal file
3
supportlibs/pegmarkdown/peg-0.1.9/examples/calc.ref
Normal file
@ -0,0 +1,3 @@
|
||||
6
|
||||
7
|
||||
42
|
17
supportlibs/pegmarkdown/peg-0.1.9/examples/dc.c
Normal file
17
supportlibs/pegmarkdown/peg-0.1.9/examples/dc.c
Normal file
@ -0,0 +1,17 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int stack[1024];
|
||||
int stackp= -1;
|
||||
|
||||
int push(int n) { return stack[++stackp]= n; }
|
||||
int pop(void) { return stack[stackp--]; }
|
||||
|
||||
#include "dc.peg.c"
|
||||
|
||||
int main()
|
||||
{
|
||||
while (yyparse());
|
||||
|
||||
return 0;
|
||||
}
|
27
supportlibs/pegmarkdown/peg-0.1.9/examples/dc.peg
Normal file
27
supportlibs/pegmarkdown/peg-0.1.9/examples/dc.peg
Normal file
@ -0,0 +1,27 @@
|
||||
# Grammar
|
||||
|
||||
Expr <- SPACE Sum EOL { printf("%d\n", pop()); }
|
||||
/ (!EOL .)* EOL { printf("error\n"); }
|
||||
|
||||
Sum <- Product ( PLUS Product { int r= pop(), l= pop(); push(l + r); }
|
||||
/ MINUS Product { int r= pop(), l= pop(); push(l - r); }
|
||||
)*
|
||||
|
||||
Product <- Value ( TIMES Value { int r= pop(), l= pop(); push(l * r); }
|
||||
/ DIVIDE Value { int r= pop(), l= pop(); push(l / r); }
|
||||
)*
|
||||
|
||||
Value <- NUMBER { push(atoi(yytext)); }
|
||||
/ OPEN Sum CLOSE
|
||||
|
||||
# Lexemes
|
||||
|
||||
NUMBER <- < [0-9]+ > SPACE
|
||||
PLUS <- '+' SPACE
|
||||
MINUS <- '-' SPACE
|
||||
TIMES <- '*' SPACE
|
||||
DIVIDE <- '/' SPACE
|
||||
OPEN <- '(' SPACE
|
||||
CLOSE <- ')' SPACE
|
||||
SPACE <- [ \t]*
|
||||
EOL <- '\n' / '\r\n' / '\r'
|
1
supportlibs/pegmarkdown/peg-0.1.9/examples/dc.ref
Normal file
1
supportlibs/pegmarkdown/peg-0.1.9/examples/dc.ref
Normal file
@ -0,0 +1 @@
|
||||
42
|
20
supportlibs/pegmarkdown/peg-0.1.9/examples/dcv.c
Normal file
20
supportlibs/pegmarkdown/peg-0.1.9/examples/dcv.c
Normal file
@ -0,0 +1,20 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int stack[1024];
|
||||
int stackp= -1;
|
||||
int var= 0;
|
||||
int vars[26];
|
||||
|
||||
int push(int n) { return stack[++stackp]= n; }
|
||||
int pop(void) { return stack[stackp--]; }
|
||||
int top(void) { return stack[stackp]; }
|
||||
|
||||
#include "dcv.peg.c"
|
||||
|
||||
int main()
|
||||
{
|
||||
while (yyparse());
|
||||
|
||||
return 0;
|
||||
}
|
34
supportlibs/pegmarkdown/peg-0.1.9/examples/dcv.peg
Normal file
34
supportlibs/pegmarkdown/peg-0.1.9/examples/dcv.peg
Normal file
@ -0,0 +1,34 @@
|
||||
# Grammar
|
||||
|
||||
Stmt <- SPACE Expr EOL { printf("%d\n", pop()); }
|
||||
/ (!EOL .)* EOL { printf("error\n"); }
|
||||
|
||||
Expr <- ID { var= yytext[0] } ASSIGN Sum { vars[var - 'a']= top(); }
|
||||
/ Sum
|
||||
|
||||
Sum <- Product ( PLUS Product { int r= pop(), l= pop(); push(l + r); }
|
||||
/ MINUS Product { int r= pop(), l= pop(); push(l - r); }
|
||||
)*
|
||||
|
||||
Product <- Value ( TIMES Value { int r= pop(), l= pop(); push(l * r); }
|
||||
/ DIVIDE Value { int r= pop(), l= pop(); push(l / r); }
|
||||
)*
|
||||
|
||||
Value <- NUMBER { push(atoi(yytext)); }
|
||||
/ < ID > !ASSIGN { push(vars[yytext[0] - 'a']); }
|
||||
/ OPEN Expr CLOSE
|
||||
|
||||
# Lexemes
|
||||
|
||||
NUMBER <- < [0-9]+ > SPACE
|
||||
ID <- < [a-z] > SPACE
|
||||
ASSIGN <- '=' SPACE
|
||||
PLUS <- '+' SPACE
|
||||
MINUS <- '-' SPACE
|
||||
TIMES <- '*' SPACE
|
||||
DIVIDE <- '/' SPACE
|
||||
OPEN <- '(' SPACE
|
||||
CLOSE <- ')' SPACE
|
||||
|
||||
SPACE <- [ \t]*
|
||||
EOL <- '\n' / '\r\n' / '\r' / ';'
|
3
supportlibs/pegmarkdown/peg-0.1.9/examples/dcv.ref
Normal file
3
supportlibs/pegmarkdown/peg-0.1.9/examples/dcv.ref
Normal file
@ -0,0 +1,3 @@
|
||||
6
|
||||
7
|
||||
42
|
17
supportlibs/pegmarkdown/peg-0.1.9/examples/fibonacci.bas
Normal file
17
supportlibs/pegmarkdown/peg-0.1.9/examples/fibonacci.bas
Normal file
@ -0,0 +1,17 @@
|
||||
100 let n=32
|
||||
110 gosub 200
|
||||
120 print "fibonacci(",n,") = ", m
|
||||
130 end
|
||||
|
||||
200 let c=n
|
||||
210 let b=1
|
||||
220 if c<2 then goto 400
|
||||
230 let c=c-1
|
||||
240 let a=1
|
||||
300 let c=c-1
|
||||
310 let d=a+b
|
||||
320 let a=b
|
||||
330 let b=d+1
|
||||
340 if c<>0 then goto 300
|
||||
400 let m=b
|
||||
410 return
|
17
supportlibs/pegmarkdown/peg-0.1.9/examples/left.c
Normal file
17
supportlibs/pegmarkdown/peg-0.1.9/examples/left.c
Normal file
@ -0,0 +1,17 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#define YY_INPUT(buf, result, max) \
|
||||
{ \
|
||||
int c= getchar(); \
|
||||
result= (EOF == c) ? 0 : (*(buf)= c, 1); \
|
||||
if (EOF != c) printf("<%c>\n", c); \
|
||||
}
|
||||
|
||||
#include "left.peg.c"
|
||||
|
||||
int main()
|
||||
{
|
||||
printf(yyparse() ? "success\n" : "failure\n");
|
||||
|
||||
return 0;
|
||||
}
|
3
supportlibs/pegmarkdown/peg-0.1.9/examples/left.peg
Normal file
3
supportlibs/pegmarkdown/peg-0.1.9/examples/left.peg
Normal file
@ -0,0 +1,3 @@
|
||||
# Grammar
|
||||
|
||||
S <- (S 'a' / 'a') !'a'
|
13
supportlibs/pegmarkdown/peg-0.1.9/examples/localctx.c
Normal file
13
supportlibs/pegmarkdown/peg-0.1.9/examples/localctx.c
Normal file
@ -0,0 +1,13 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#define YY_CTX_LOCAL
|
||||
|
||||
#include "test.peg.c"
|
||||
|
||||
int main()
|
||||
{
|
||||
yycontext ctx;
|
||||
memset(&ctx, 0, sizeof(yycontext));
|
||||
while (yyparse(&ctx));
|
||||
return 0;
|
||||
}
|
10
supportlibs/pegmarkdown/peg-0.1.9/examples/localctx.ref
Normal file
10
supportlibs/pegmarkdown/peg-0.1.9/examples/localctx.ref
Normal file
@ -0,0 +1,10 @@
|
||||
a1 ab1 .
|
||||
a2 ac2 .
|
||||
a3 ad3 .
|
||||
a3 ae3 .
|
||||
a4 af4 afg4 .
|
||||
a4 af5 afh5 .
|
||||
a4 af4 afg4 .
|
||||
a4 af5 afh5 .
|
||||
af6 afi6 a6 .
|
||||
af6 af7 afj7 a6 .
|
11
supportlibs/pegmarkdown/peg-0.1.9/examples/rule.c
Normal file
11
supportlibs/pegmarkdown/peg-0.1.9/examples/rule.c
Normal file
@ -0,0 +1,11 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "rule.peg.c"
|
||||
|
||||
int main()
|
||||
{
|
||||
while (yyparse());
|
||||
|
||||
return 0;
|
||||
}
|
8
supportlibs/pegmarkdown/peg-0.1.9/examples/rule.peg
Normal file
8
supportlibs/pegmarkdown/peg-0.1.9/examples/rule.peg
Normal file
@ -0,0 +1,8 @@
|
||||
start <- abcd+
|
||||
|
||||
abcd <- 'a' { printf("A %d\n", yypos); } bc { printf("ABC %d\n", yypos); }
|
||||
/ 'b' { printf("B %d\n", yypos); } cd { printf("BCD %d\n", yypos); }
|
||||
|
||||
bc <- 'b' { printf("B %d\n", yypos); } 'c' { printf("C %d\n", yypos); }
|
||||
|
||||
cd <- 'c' { printf("C %d\n", yypos); } 'd' { printf("D %d\n", yypos); }
|
32
supportlibs/pegmarkdown/peg-0.1.9/examples/rule.ref
Normal file
32
supportlibs/pegmarkdown/peg-0.1.9/examples/rule.ref
Normal file
@ -0,0 +1,32 @@
|
||||
A 24
|
||||
B 24
|
||||
C 24
|
||||
ABC 24
|
||||
B 24
|
||||
C 24
|
||||
D 24
|
||||
BCD 24
|
||||
A 24
|
||||
B 24
|
||||
C 24
|
||||
ABC 24
|
||||
B 24
|
||||
C 24
|
||||
D 24
|
||||
BCD 24
|
||||
A 24
|
||||
B 24
|
||||
C 24
|
||||
ABC 24
|
||||
B 24
|
||||
C 24
|
||||
D 24
|
||||
BCD 24
|
||||
A 24
|
||||
B 24
|
||||
C 24
|
||||
ABC 24
|
||||
B 24
|
||||
C 24
|
||||
D 24
|
||||
BCD 24
|
12
supportlibs/pegmarkdown/peg-0.1.9/examples/test.bas
Normal file
12
supportlibs/pegmarkdown/peg-0.1.9/examples/test.bas
Normal file
@ -0,0 +1,12 @@
|
||||
10 let i=1
|
||||
20 gosub 100
|
||||
30 let i=i+1
|
||||
40 if i<=10 then goto 20
|
||||
50 end
|
||||
|
||||
100 let j=1
|
||||
110 print " ", i*j,
|
||||
120 let j=j+1
|
||||
130 if j<=i then goto 110
|
||||
140 print
|
||||
150 return
|
8
supportlibs/pegmarkdown/peg-0.1.9/examples/test.c
Normal file
8
supportlibs/pegmarkdown/peg-0.1.9/examples/test.c
Normal file
@ -0,0 +1,8 @@
|
||||
#include <stdio.h>
|
||||
#include "test.peg.c"
|
||||
|
||||
int main()
|
||||
{
|
||||
while (yyparse());
|
||||
return 0;
|
||||
}
|
13
supportlibs/pegmarkdown/peg-0.1.9/examples/test.peg
Normal file
13
supportlibs/pegmarkdown/peg-0.1.9/examples/test.peg
Normal file
@ -0,0 +1,13 @@
|
||||
start <- body '.' { printf(".\n"); }
|
||||
|
||||
body <- 'a' { printf("a1 "); } 'b' { printf("ab1 "); }
|
||||
|
||||
/ 'a' { printf("a2 "); } 'c' { printf("ac2 "); }
|
||||
|
||||
/ 'a' { printf("a3 "); } ( 'd' { printf("ad3 "); } / 'e' { printf("ae3 "); } )
|
||||
|
||||
/ 'a' { printf("a4 "); } ( 'f' { printf("af4 "); } 'g' { printf("afg4 "); }
|
||||
/ 'f' { printf("af5 "); } 'h' { printf("afh5 "); } )
|
||||
|
||||
/ 'a' { printf("a6 "); } ( 'f' &{ printf("af6 ") } 'i' &{ printf("afi6 ") }
|
||||
/ 'f' &{ printf("af7 ") } 'j' &{ printf("afj7 ") } )
|
10
supportlibs/pegmarkdown/peg-0.1.9/examples/test.ref
Normal file
10
supportlibs/pegmarkdown/peg-0.1.9/examples/test.ref
Normal file
@ -0,0 +1,10 @@
|
||||
a1 ab1 .
|
||||
a2 ac2 .
|
||||
a3 ad3 .
|
||||
a3 ae3 .
|
||||
a4 af4 afg4 .
|
||||
a4 af5 afh5 .
|
||||
a4 af4 afg4 .
|
||||
a4 af5 afh5 .
|
||||
af6 afi6 a6 .
|
||||
af6 af7 afj7 a6 .
|
14
supportlibs/pegmarkdown/peg-0.1.9/examples/username.leg
Normal file
14
supportlibs/pegmarkdown/peg-0.1.9/examples/username.leg
Normal file
@ -0,0 +1,14 @@
|
||||
%{
|
||||
#include <unistd.h>
|
||||
%}
|
||||
|
||||
start = "username" { printf("%s", getlogin()); }
|
||||
| < . > { putchar(yytext[0]); }
|
||||
|
||||
%%
|
||||
|
||||
int main()
|
||||
{
|
||||
while (yyparse());
|
||||
return 0;
|
||||
}
|
22
supportlibs/pegmarkdown/peg-0.1.9/examples/wc.leg
Normal file
22
supportlibs/pegmarkdown/peg-0.1.9/examples/wc.leg
Normal file
@ -0,0 +1,22 @@
|
||||
%{
|
||||
#include <stdio.h>
|
||||
int lines= 0, words= 0, chars= 0;
|
||||
%}
|
||||
|
||||
start = (line | word | char)
|
||||
|
||||
line = < (( '\n' '\r'* ) | ( '\r' '\n'* )) > { lines++; chars += yyleng; }
|
||||
word = < [a-zA-Z]+ > { words++; chars += yyleng; printf("<%s>\n", yytext); }
|
||||
char = . { chars++; }
|
||||
|
||||
%%
|
||||
|
||||
int main()
|
||||
{
|
||||
while (yyparse())
|
||||
;
|
||||
printf("%d lines\n", lines);
|
||||
printf("%d chars\n", chars);
|
||||
printf("%d words\n", words);
|
||||
return 0;
|
||||
}
|
55
supportlibs/pegmarkdown/peg-0.1.9/examples/wc.ref
Normal file
55
supportlibs/pegmarkdown/peg-0.1.9/examples/wc.ref
Normal file
@ -0,0 +1,55 @@
|
||||
<include>
|
||||
<stdio>
|
||||
<h>
|
||||
<int>
|
||||
<lines>
|
||||
<words>
|
||||
<chars>
|
||||
<start>
|
||||
<line>
|
||||
<word>
|
||||
<char>
|
||||
<line>
|
||||
<n>
|
||||
<r>
|
||||
<r>
|
||||
<n>
|
||||
<lines>
|
||||
<chars>
|
||||
<yyleng>
|
||||
<word>
|
||||
<a>
|
||||
<zA>
|
||||
<Z>
|
||||
<words>
|
||||
<chars>
|
||||
<yyleng>
|
||||
<printf>
|
||||
<s>
|
||||
<n>
|
||||
<yytext>
|
||||
<char>
|
||||
<chars>
|
||||
<int>
|
||||
<main>
|
||||
<while>
|
||||
<yyparse>
|
||||
<printf>
|
||||
<d>
|
||||
<lines>
|
||||
<n>
|
||||
<lines>
|
||||
<printf>
|
||||
<d>
|
||||
<chars>
|
||||
<n>
|
||||
<chars>
|
||||
<printf>
|
||||
<d>
|
||||
<words>
|
||||
<n>
|
||||
<words>
|
||||
<return>
|
||||
22 lines
|
||||
425 chars
|
||||
52 words
|
1209
supportlibs/pegmarkdown/peg-0.1.9/leg.c
Normal file
1209
supportlibs/pegmarkdown/peg-0.1.9/leg.c
Normal file
File diff suppressed because it is too large
Load Diff
292
supportlibs/pegmarkdown/peg-0.1.9/leg.leg
Normal file
292
supportlibs/pegmarkdown/peg-0.1.9/leg.leg
Normal file
@ -0,0 +1,292 @@
|
||||
# LE Grammar for LE Grammars
|
||||
#
|
||||
# Copyright (c) 2007 by Ian Piumarta
|
||||
# All rights reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the 'Software'),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, provided that the above copyright notice(s) and this
|
||||
# permission notice appear in all copies of the Software. Acknowledgement
|
||||
# of the use of this Software in supporting documentation would be
|
||||
# appreciated but is not required.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED 'AS IS'. USE ENTIRELY AT YOUR OWN RISK.
|
||||
#
|
||||
# Last edited: 2012-04-29 15:51:15 by piumarta on emilia
|
||||
|
||||
%{
|
||||
# include "tree.h"
|
||||
# include "version.h"
|
||||
|
||||
# include <stdio.h>
|
||||
# include <stdlib.h>
|
||||
# include <unistd.h>
|
||||
# include <string.h>
|
||||
# include <libgen.h>
|
||||
# include <assert.h>
|
||||
|
||||
typedef struct Header Header;
|
||||
|
||||
struct Header {
|
||||
char *text;
|
||||
Header *next;
|
||||
};
|
||||
|
||||
FILE *input= 0;
|
||||
|
||||
int verboseFlag= 0;
|
||||
|
||||
static int lineNumber= 0;
|
||||
static char *fileName= 0;
|
||||
static char *trailer= 0;
|
||||
static Header *headers= 0;
|
||||
|
||||
void makeHeader(char *text);
|
||||
void makeTrailer(char *text);
|
||||
|
||||
void yyerror(char *message);
|
||||
|
||||
# define YY_INPUT(buf, result, max) \
|
||||
{ \
|
||||
int c= getc(input); \
|
||||
if ('\n' == c || '\r' == c) ++lineNumber; \
|
||||
result= (EOF == c) ? 0 : (*(buf)= c, 1); \
|
||||
}
|
||||
|
||||
# define YY_LOCAL(T) static T
|
||||
# define YY_RULE(T) static T
|
||||
%}
|
||||
|
||||
# Hierarchical syntax
|
||||
|
||||
grammar= - ( declaration | definition )+ trailer? end-of-file
|
||||
|
||||
declaration= '%{' < ( !'%}' . )* > RPERCENT { makeHeader(yytext); } #{YYACCEPT}
|
||||
|
||||
trailer= '%%' < .* > { makeTrailer(yytext); } #{YYACCEPT}
|
||||
|
||||
definition= identifier { if (push(beginRule(findRule(yytext)))->rule.expression)
|
||||
fprintf(stderr, "rule '%s' redefined\n", yytext); }
|
||||
EQUAL expression { Node *e= pop(); Rule_setExpression(pop(), e); }
|
||||
SEMICOLON? #{YYACCEPT}
|
||||
|
||||
expression= sequence (BAR sequence { Node *f= pop(); push(Alternate_append(pop(), f)); }
|
||||
)*
|
||||
|
||||
sequence= prefix (prefix { Node *f= pop(); push(Sequence_append(pop(), f)); }
|
||||
)*
|
||||
|
||||
prefix= AND action { push(makePredicate(yytext)); }
|
||||
| AND suffix { push(makePeekFor(pop())); }
|
||||
| NOT suffix { push(makePeekNot(pop())); }
|
||||
| suffix
|
||||
|
||||
suffix= primary (QUESTION { push(makeQuery(pop())); }
|
||||
| STAR { push(makeStar (pop())); }
|
||||
| PLUS { push(makePlus (pop())); }
|
||||
)?
|
||||
|
||||
primary= identifier { push(makeVariable(yytext)); }
|
||||
COLON identifier !EQUAL { Node *name= makeName(findRule(yytext)); name->name.variable= pop(); push(name); }
|
||||
| identifier !EQUAL { push(makeName(findRule(yytext))); }
|
||||
| OPEN expression CLOSE
|
||||
| literal { push(makeString(yytext)); }
|
||||
| class { push(makeClass(yytext)); }
|
||||
| DOT { push(makeDot()); }
|
||||
| action { push(makeAction(yytext)); }
|
||||
| BEGIN { push(makePredicate("YY_BEGIN")); }
|
||||
| END { push(makePredicate("YY_END")); }
|
||||
|
||||
# Lexical syntax
|
||||
|
||||
identifier= < [-a-zA-Z_][-a-zA-Z_0-9]* > -
|
||||
|
||||
literal= ['] < ( !['] char )* > ['] -
|
||||
| ["] < ( !["] char )* > ["] -
|
||||
|
||||
class= '[' < ( !']' range )* > ']' -
|
||||
|
||||
range= char '-' char | char
|
||||
|
||||
char= '\\' [-abefnrtv'"\[\]\\]
|
||||
| '\\' [0-3][0-7][0-7]
|
||||
| '\\' [0-7][0-7]?
|
||||
| !'\\' .
|
||||
|
||||
action= '{' < braces* > '}' -
|
||||
|
||||
braces= '{' braces* '}'
|
||||
| !'}' .
|
||||
|
||||
EQUAL= '=' -
|
||||
COLON= ':' -
|
||||
SEMICOLON= ';' -
|
||||
BAR= '|' -
|
||||
AND= '&' -
|
||||
NOT= '!' -
|
||||
QUESTION= '?' -
|
||||
STAR= '*' -
|
||||
PLUS= '+' -
|
||||
OPEN= '(' -
|
||||
CLOSE= ')' -
|
||||
DOT= '.' -
|
||||
BEGIN= '<' -
|
||||
END= '>' -
|
||||
RPERCENT= '%}' -
|
||||
|
||||
-= (space | comment)*
|
||||
space= ' ' | '\t' | end-of-line
|
||||
comment= '#' (!end-of-line .)* end-of-line
|
||||
end-of-line= '\r\n' | '\n' | '\r'
|
||||
end-of-file= !.
|
||||
|
||||
%%
|
||||
|
||||
void yyerror(char *message)
|
||||
{
|
||||
fprintf(stderr, "%s:%d: %s", fileName, lineNumber, message);
|
||||
if (yyctx->text[0]) fprintf(stderr, " near token '%s'", yyctx->text);
|
||||
if (yyctx->pos < yyctx->limit || !feof(input))
|
||||
{
|
||||
yyctx->buf[yyctx->limit]= '\0';
|
||||
fprintf(stderr, " before text \"");
|
||||
while (yyctx->pos < yyctx->limit)
|
||||
{
|
||||
if ('\n' == yyctx->buf[yyctx->pos] || '\r' == yyctx->buf[yyctx->pos]) break;
|
||||
fputc(yyctx->buf[yyctx->pos++], stderr);
|
||||
}
|
||||
if (yyctx->pos == yyctx->limit)
|
||||
{
|
||||
int c;
|
||||
while (EOF != (c= fgetc(input)) && '\n' != c && '\r' != c)
|
||||
fputc(c, stderr);
|
||||
}
|
||||
fputc('\"', stderr);
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void makeHeader(char *text)
|
||||
{
|
||||
Header *header= (Header *)malloc(sizeof(Header));
|
||||
header->text= strdup(text);
|
||||
header->next= headers;
|
||||
headers= header;
|
||||
}
|
||||
|
||||
void makeTrailer(char *text)
|
||||
{
|
||||
trailer= strdup(text);
|
||||
}
|
||||
|
||||
static void version(char *name)
|
||||
{
|
||||
printf("%s version %d.%d.%d\n", name, PEG_MAJOR, PEG_MINOR, PEG_LEVEL);
|
||||
}
|
||||
|
||||
static void usage(char *name)
|
||||
{
|
||||
version(name);
|
||||
fprintf(stderr, "usage: %s [<option>...] [<file>...]\n", name);
|
||||
fprintf(stderr, "where <option> can be\n");
|
||||
fprintf(stderr, " -h print this help information\n");
|
||||
fprintf(stderr, " -o <ofile> write output to <ofile>\n");
|
||||
fprintf(stderr, " -v be verbose\n");
|
||||
fprintf(stderr, " -V print version number and exit\n");
|
||||
fprintf(stderr, "if no <file> is given, input is read from stdin\n");
|
||||
fprintf(stderr, "if no <ofile> is given, output is written to stdout\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
Node *n;
|
||||
int c;
|
||||
|
||||
output= stdout;
|
||||
input= stdin;
|
||||
lineNumber= 1;
|
||||
fileName= "<stdin>";
|
||||
|
||||
while (-1 != (c= getopt(argc, argv, "Vho:v")))
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case 'V':
|
||||
version(basename(argv[0]));
|
||||
exit(0);
|
||||
|
||||
case 'h':
|
||||
usage(basename(argv[0]));
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
if (!(output= fopen(optarg, "w")))
|
||||
{
|
||||
perror(optarg);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
verboseFlag= 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "for usage try: %s -h\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc)
|
||||
{
|
||||
for (; argc; --argc, ++argv)
|
||||
{
|
||||
if (!strcmp(*argv, "-"))
|
||||
{
|
||||
input= stdin;
|
||||
fileName= "<stdin>";
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(input= fopen(*argv, "r")))
|
||||
{
|
||||
perror(*argv);
|
||||
exit(1);
|
||||
}
|
||||
fileName= *argv;
|
||||
}
|
||||
lineNumber= 1;
|
||||
if (!yyparse())
|
||||
yyerror("syntax error");
|
||||
if (input != stdin)
|
||||
fclose(input);
|
||||
}
|
||||
}
|
||||
else
|
||||
if (!yyparse())
|
||||
yyerror("syntax error");
|
||||
|
||||
if (verboseFlag)
|
||||
for (n= rules; n; n= n->any.next)
|
||||
Rule_print(n);
|
||||
|
||||
Rule_compile_c_header();
|
||||
|
||||
for (; headers; headers= headers->next)
|
||||
fprintf(output, "%s\n", headers->text);
|
||||
|
||||
if (rules)
|
||||
Rule_compile_c(rules);
|
||||
|
||||
if (trailer)
|
||||
fprintf(output, "%s\n", trailer);
|
||||
|
||||
return 0;
|
||||
}
|
933
supportlibs/pegmarkdown/peg-0.1.9/peg.1
Normal file
933
supportlibs/pegmarkdown/peg-0.1.9/peg.1
Normal file
@ -0,0 +1,933 @@
|
||||
.\" Copyright (c) 2007 by Ian Piumarta
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Permission is hereby granted, free of charge, to any person obtaining a
|
||||
.\" copy of this software and associated documentation files (the 'Software'),
|
||||
.\" to deal in the Software without restriction, including without limitation
|
||||
.\" the rights to use, copy, modify, merge, publish, distribute, and/or sell
|
||||
.\" copies of the Software, and to permit persons to whom the Software is
|
||||
.\" furnished to do so, provided that the above copyright notice(s) and this
|
||||
.\" permission notice appear in all copies of the Software. Acknowledgement
|
||||
.\" of the use of this Software in supporting documentation would be
|
||||
.\" appreciated but is not required.
|
||||
.\"
|
||||
.\" THE SOFTWARE IS PROVIDED 'AS IS'. USE ENTIRELY AT YOUR OWN RISK.
|
||||
.\"
|
||||
.\" Last edited: 2012-04-29 16:58:44 by piumarta on emilia
|
||||
.\"
|
||||
.TH PEG 1 "April 2012" "Version 0.1"
|
||||
.SH NAME
|
||||
peg, leg \- parser generators
|
||||
.SH SYNOPSIS
|
||||
.B peg
|
||||
.B [\-hvV \-ooutput]
|
||||
.I [filename ...]
|
||||
.sp 0
|
||||
.B leg
|
||||
.B [\-hvV \-ooutput]
|
||||
.I [filename ...]
|
||||
.SH DESCRIPTION
|
||||
.I peg
|
||||
and
|
||||
.I leg
|
||||
are tools for generating recursive-descent parsers: programs that
|
||||
perform pattern matching on text. They process a Parsing Expression
|
||||
Grammar (PEG) [Ford 2004] to produce a program that recognises legal
|
||||
sentences of that grammar.
|
||||
.I peg
|
||||
processes PEGs written using the original syntax described by Ford;
|
||||
.I leg
|
||||
processes PEGs written using slightly different syntax and conventions
|
||||
that are intended to make it an attractive replacement for parsers
|
||||
built with
|
||||
.IR lex (1)
|
||||
and
|
||||
.IR yacc (1).
|
||||
Unlike
|
||||
.I lex
|
||||
and
|
||||
.IR yacc ,
|
||||
.I peg
|
||||
and
|
||||
.I leg
|
||||
support unlimited backtracking, provide ordered choice as a means for
|
||||
disambiguation, and can combine scanning (lexical analysis) and
|
||||
parsing (syntactic analysis) into a single activity.
|
||||
.PP
|
||||
.I peg
|
||||
reads the specified
|
||||
.IR filename s,
|
||||
or standard input if no
|
||||
.IR filename s
|
||||
are given, for a grammar describing the parser to generate.
|
||||
.I peg
|
||||
then generates a C source file that defines a function
|
||||
.IR yyparse().
|
||||
This C source file can be included in, or compiled and then linked
|
||||
with, a client program. Each time the client program calls
|
||||
.IR yyparse ()
|
||||
the parser consumes input text according to the parsing rules,
|
||||
starting from the first rule in the grammar.
|
||||
.IR yyparse ()
|
||||
returns non-zero if the input could be parsed according to the
|
||||
grammar; it returns zero if the input could not be parsed.
|
||||
.PP
|
||||
The prefix 'yy' or 'YY' is prepended to all externally-visible symbols
|
||||
in the generated parser. This is intended to reduce the risk of
|
||||
namespace pollution in client programs. (The choice of 'yy' is
|
||||
historical; see
|
||||
.IR lex (1)
|
||||
and
|
||||
.IR yacc (1),
|
||||
for example.)
|
||||
.SH OPTIONS
|
||||
.I peg
|
||||
and
|
||||
.I leg
|
||||
provide the following options:
|
||||
.TP
|
||||
.B \-h
|
||||
prints a summary of available options and then exits.
|
||||
.TP
|
||||
.B \-ooutput
|
||||
writes the generated parser to the file
|
||||
.B output
|
||||
instead of the standard output.
|
||||
.TP
|
||||
.B \-v
|
||||
writes verbose information to standard error while working.
|
||||
.TP
|
||||
.B \-V
|
||||
writes version information to standard error then exits.
|
||||
.SH A SIMPLE EXAMPLE
|
||||
The following
|
||||
.I peg
|
||||
input specifies a grammar with a single rule (called 'start') that is
|
||||
satisfied when the input contains the string "username".
|
||||
.nf
|
||||
|
||||
start <- "username"
|
||||
|
||||
.fi
|
||||
(The quotation marks are
|
||||
.I not
|
||||
part of the matched text; they serve to indicate a literal string to
|
||||
be matched.) In other words,
|
||||
.IR yyparse ()
|
||||
in the generated C source will return non-zero only if the next eight
|
||||
characters read from the input spell the word "username". If the
|
||||
input contains anything else,
|
||||
.IR yyparse ()
|
||||
returns zero and no input will have been consumed. (Subsequent calls
|
||||
to
|
||||
.IR yyparse ()
|
||||
will also return zero, since the parser is effectively blocked looking
|
||||
for the string "username".) To ensure progress we can add an
|
||||
alternative clause to the 'start' rule that will match any single
|
||||
character if "username" is not found.
|
||||
.nf
|
||||
|
||||
start <- "username"
|
||||
/ .
|
||||
|
||||
.fi
|
||||
.IR yyparse ()
|
||||
now always returns non-zero (except at the very end of the input). To
|
||||
do something useful we can add actions to the rules. These actions
|
||||
are performed after a complete match is found (starting from the first
|
||||
rule) and are chosen according to the 'path' taken through the grammar
|
||||
to match the input. (Linguists would call this path a 'phrase
|
||||
marker'.)
|
||||
.nf
|
||||
|
||||
start <- "username" { printf("%s\\n", getlogin()); }
|
||||
/ < . > { putchar(yytext[0]); }
|
||||
|
||||
.fi
|
||||
The first line instructs the parser to print the user's login name
|
||||
whenever it sees "username" in the input. If that match fails, the
|
||||
second line tells the parser to echo the next character on the input
|
||||
the standard output. Our parser is now performing useful work: it
|
||||
will copy the input to the output, replacing all occurrences of
|
||||
"username" with the user's account name.
|
||||
.PP
|
||||
Note the angle brackets ('<' and '>') that were added to the second
|
||||
alternative. These have no effect on the meaning of the rule, but
|
||||
serve to delimit the text made available to the following action in
|
||||
the variable
|
||||
.IR yytext .
|
||||
.PP
|
||||
If the above grammar is placed in the file
|
||||
.BR username.peg ,
|
||||
running the command
|
||||
.nf
|
||||
|
||||
peg -o username.c username.peg
|
||||
|
||||
.fi
|
||||
will save the corresponding parser in the file
|
||||
.BR username.c .
|
||||
To create a complete program this parser could be included by a C
|
||||
program as follows.
|
||||
.nf
|
||||
|
||||
#include <stdio.h> /* printf(), putchar() */
|
||||
#include <unistd.h> /* getlogin() */
|
||||
|
||||
#include "username.c" /* yyparse() */
|
||||
|
||||
int main()
|
||||
{
|
||||
while (yyparse()) /* repeat until EOF */
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
.fi
|
||||
.SH PEG GRAMMARS
|
||||
A grammar consists of a set of named rules.
|
||||
.nf
|
||||
|
||||
name <- pattern
|
||||
|
||||
.fi
|
||||
The
|
||||
.B pattern
|
||||
contains one or more of the following elements.
|
||||
.TP
|
||||
.B name
|
||||
The element stands for the entire pattern in the rule with the given
|
||||
.BR name .
|
||||
.TP
|
||||
.BR \(dq characters \(dq
|
||||
A character or string enclosed in double quotes is matched literally.
|
||||
The ANSI C esacpe sequences are recognised within the
|
||||
.IR characters .
|
||||
.TP
|
||||
.BR ' characters '
|
||||
A character or string enclosed in single quotes is matched literally, as above.
|
||||
.TP
|
||||
.BR [ characters ]
|
||||
A set of characters enclosed in square brackets matches any single
|
||||
character from the set, with escape characters recognised as above.
|
||||
If the set begins with an uparrow (^) then the set is negated (the
|
||||
element matches any character
|
||||
.I not
|
||||
in the set). Any pair of characters separated with a dash (-)
|
||||
represents the range of characters from the first to the second,
|
||||
inclusive. A single alphabetic character or underscore is matched by
|
||||
the following set.
|
||||
.nf
|
||||
|
||||
[a-zA-Z_]
|
||||
|
||||
.fi
|
||||
Similarly, the following matches any single non-digit character.
|
||||
.nf
|
||||
|
||||
[^0-9]
|
||||
|
||||
.fi
|
||||
.TP
|
||||
.B .
|
||||
A dot matches any character. Note that the only time this fails is at
|
||||
the end of file, where there is no character to match.
|
||||
.TP
|
||||
.BR ( \ pattern\ )
|
||||
Parentheses are used for grouping (modifying the precendence of the
|
||||
operators described below).
|
||||
.TP
|
||||
.BR { \ action\ }
|
||||
Curly braces surround actions. The action is arbitray C source code
|
||||
to be executed at the end of matching. Any braces within the action
|
||||
must be properly nested. Any input text that was matched before the
|
||||
action and delimited by angle brackets (see below) is made available
|
||||
within the action as the contents of the character array
|
||||
.IR yytext .
|
||||
The length of (number of characters in)
|
||||
.I yytext
|
||||
is available in the variable
|
||||
.IR yyleng .
|
||||
(These variable names are historical; see
|
||||
.IR lex (1).)
|
||||
.TP
|
||||
.B <
|
||||
An opening angle bracket always matches (consuming no input) and
|
||||
causes the parser to begin accumulating matched text. This text will
|
||||
be made available to actions in the variable
|
||||
.IR yytext .
|
||||
.TP
|
||||
.B >
|
||||
A closing angle bracket always matches (consuming no input) and causes
|
||||
the parser to stop accumulating text for
|
||||
.IR yytext .
|
||||
.PP
|
||||
The above
|
||||
.IR element s
|
||||
can be made optional and/or repeatable with the following suffixes:
|
||||
.TP
|
||||
.RB element\ ?
|
||||
The element is optional. If present on the input, it is consumed and
|
||||
the match succeeds. If not present on the input, no text is consumed
|
||||
and the match succeeds anyway.
|
||||
.TP
|
||||
.RB element\ +
|
||||
The element is repeatable. If present on the input, one or more
|
||||
occurrences of
|
||||
.I element
|
||||
are consumed and the match succeeds. If no occurrences of
|
||||
.I element
|
||||
are present on the input, the match fails.
|
||||
.TP
|
||||
.RB element\ *
|
||||
The element is optional and repeatable. If present on the input, one or more
|
||||
occurrences of
|
||||
.I element
|
||||
are consumed and the match succeeds. If no occurrences of
|
||||
.I element
|
||||
are present on the input, the match succeeds anyway.
|
||||
.PP
|
||||
The above elements and suffixes can be converted into predicates (that
|
||||
match arbitray input text and subsequently succeed or fail
|
||||
.I without
|
||||
consuming that input) with the following prefixes:
|
||||
.TP
|
||||
.BR & \ element
|
||||
The predicate succeeds only if
|
||||
.I element
|
||||
can be matched. Input text scanned while matching
|
||||
.I element
|
||||
is not consumed from the input and remains available for subsequent
|
||||
matching.
|
||||
.TP
|
||||
.BR ! \ element
|
||||
The predicate succeeds only if
|
||||
.I element
|
||||
cannot be matched. Input text scanned while matching
|
||||
.I element
|
||||
is not consumed from the input and remains available for subsequent
|
||||
matching. A popular idiom is
|
||||
.nf
|
||||
|
||||
!.
|
||||
|
||||
.fi
|
||||
which matches the end of file, after the last character of the input
|
||||
has already been consumed.
|
||||
.PP
|
||||
A special form of the '&' predicate is provided:
|
||||
.TP
|
||||
.BR & {\ expression\ }
|
||||
In this predicate the simple C
|
||||
.I expression
|
||||
.RB ( not
|
||||
statement) is evaluated immediately when the parser reaches the
|
||||
predicate. If the
|
||||
.I expression
|
||||
yields non-zero (true) the 'match' succeeds and the parser continues
|
||||
with the next element in the pattern. If the
|
||||
.I expression
|
||||
yields zero (false) the 'match' fails and the parser backs up to look
|
||||
for an alternative parse of the input.
|
||||
.PP
|
||||
Several elements (with or without prefixes and suffixes) can be
|
||||
combined into a
|
||||
.I sequence
|
||||
by writing them one after the other. The entire sequence matches only
|
||||
if each individual element within it matches, from left to right.
|
||||
.PP
|
||||
Sequences can be separated into disjoint alternatives by the
|
||||
alternation operator '/'.
|
||||
.TP
|
||||
.RB sequence-1\ / \ sequence-2\ / \ ...\ / \ sequence-N
|
||||
Each sequence is tried in turn until one of them matches, at which
|
||||
time matching for the overall pattern succeeds. If none of the
|
||||
sequences matches then the match of the overall pattern fails.
|
||||
.PP
|
||||
Finally, the pound sign (#) introduces a comment (discarded) that
|
||||
continues until the end of the line.
|
||||
.PP
|
||||
To summarise the above, the parser tries to match the input text
|
||||
against a pattern containing literals, names (representing other
|
||||
rules), and various operators (written as prefixes, suffixes,
|
||||
juxtaposition for sequencing and and infix alternation operator) that
|
||||
modify how the elements within the pattern are matched. Matches are
|
||||
made from left to right, 'descending' into named sub-rules as they are
|
||||
encountered. If the matching process fails, the parser 'back tracks'
|
||||
('rewinding' the input appropriately in the process) to find the
|
||||
nearest alternative 'path' through the grammar. In other words the
|
||||
parser performs a depth-first, left-to-right search for the first
|
||||
successfully-matching path through the rules. If found, the actions
|
||||
along the successful path are executed (in the order they were
|
||||
encountered).
|
||||
.PP
|
||||
Note that predicates are evaluated
|
||||
.I immediately
|
||||
during the search for a successful match, since they contribute to the
|
||||
success or failure of the search. Actions, however, are evaluated
|
||||
only after a successful match has been found.
|
||||
.SH PEG GRAMMAR FOR PEG GRAMMARS
|
||||
The grammar for
|
||||
.I peg
|
||||
grammars is shown below. This will both illustrate and formalise
|
||||
the above description.
|
||||
.nf
|
||||
|
||||
Grammar <- Spacing Definition+ EndOfFile
|
||||
|
||||
Definition <- Identifier LEFTARROW Expression
|
||||
Expression <- Sequence ( SLASH Sequence )*
|
||||
Sequence <- Prefix*
|
||||
Prefix <- AND Action
|
||||
/ ( AND | NOT )? Suffix
|
||||
Suffix <- Primary ( QUERY / STAR / PLUS )?
|
||||
Primary <- Identifier !LEFTARROW
|
||||
/ OPEN Expression CLOSE
|
||||
/ Literal
|
||||
/ Class
|
||||
/ DOT
|
||||
/ Action
|
||||
/ BEGIN
|
||||
/ END
|
||||
|
||||
Identifier <- < IdentStart IdentCont* > Spacing
|
||||
IdentStart <- [a-zA-Z_]
|
||||
IdentCont <- IdentStart / [0-9]
|
||||
Literal <- ['] < ( !['] Char )* > ['] Spacing
|
||||
/ ["] < ( !["] Char )* > ["] Spacing
|
||||
Class <- '[' < ( !']' Range )* > ']' Spacing
|
||||
Range <- Char '-' Char / Char
|
||||
Char <- '\\\\' [abefnrtv'"\\[\\]\\\\]
|
||||
/ '\\\\' [0-3][0-7][0-7]
|
||||
/ '\\\\' [0-7][0-7]?
|
||||
/ '\\\\' '-'
|
||||
/ !'\\\\' .
|
||||
LEFTARROW <- '<-' Spacing
|
||||
SLASH <- '/' Spacing
|
||||
AND <- '&' Spacing
|
||||
NOT <- '!' Spacing
|
||||
QUERY <- '?' Spacing
|
||||
STAR <- '*' Spacing
|
||||
PLUS <- '+' Spacing
|
||||
OPEN <- '(' Spacing
|
||||
CLOSE <- ')' Spacing
|
||||
DOT <- '.' Spacing
|
||||
Spacing <- ( Space / Comment )*
|
||||
Comment <- '#' ( !EndOfLine . )* EndOfLine
|
||||
Space <- ' ' / '\\t' / EndOfLine
|
||||
EndOfLine <- '\\r\\n' / '\\n' / '\\r'
|
||||
EndOfFile <- !.
|
||||
Action <- '{' < [^}]* > '}' Spacing
|
||||
BEGIN <- '<' Spacing
|
||||
END <- '>' Spacing
|
||||
|
||||
.fi
|
||||
.SH LEG GRAMMARS
|
||||
.I leg
|
||||
is a variant of
|
||||
.I peg
|
||||
that adds some features of
|
||||
.IR lex (1)
|
||||
and
|
||||
.IR yacc (1).
|
||||
It differs from
|
||||
.I peg
|
||||
in the following ways.
|
||||
.TP
|
||||
.BI %{\ text... \ %}
|
||||
A declaration section can appear anywhere that a rule definition is
|
||||
expected. The
|
||||
.I text
|
||||
between the delimiters '%{' and '%}' is copied verbatim to the
|
||||
generated C parser code
|
||||
.I before
|
||||
the code that implements the parser itself.
|
||||
.TP
|
||||
.IB name\ = \ pattern
|
||||
The 'assignment' operator replaces the left arrow operator '<-'.
|
||||
.TP
|
||||
.B rule-name
|
||||
Hyphens can appear as letters in the names of rules. Each hyphen is
|
||||
converted into an underscore in the generated C source code. A single
|
||||
single hyphen '-' is a legal rule name.
|
||||
.nf
|
||||
|
||||
- = [ \\t\\n\\r]*
|
||||
number = [0-9]+ -
|
||||
name = [a-zA-Z_][a-zA_Z_0-9]* -
|
||||
l-paren = '(' -
|
||||
r-paren = ')' -
|
||||
|
||||
.fi
|
||||
This example shows how ignored whitespace can be obvious when reading
|
||||
the grammar and yet unobtrusive when placed liberally at the end of
|
||||
every rule associated with a lexical element.
|
||||
.TP
|
||||
.IB seq-1\ | \ seq-2
|
||||
The alternation operator is vertical bar '|' rather than forward
|
||||
slash '/'. The
|
||||
.I peg
|
||||
rule
|
||||
.nf
|
||||
|
||||
name <- sequence-1
|
||||
/ sequence-2
|
||||
/ sequence-3
|
||||
|
||||
.fi
|
||||
is therefore written
|
||||
.nf
|
||||
|
||||
name = sequence-1
|
||||
| sequence-2
|
||||
| sequence-3
|
||||
;
|
||||
|
||||
.fi
|
||||
in
|
||||
.I leg
|
||||
(with the final semicolon being optional, as described next).
|
||||
.TP
|
||||
.IB pattern\ ;
|
||||
A semicolon punctuator can optionally terminate a
|
||||
.IR pattern .
|
||||
.TP
|
||||
.BI %% \ text...
|
||||
A double percent '%%' terminates the rules (and declarations) section of
|
||||
the grammar. All
|
||||
.I text
|
||||
following '%%' is copied verbatim to the generated C parser code
|
||||
.I after
|
||||
the parser implementation code.
|
||||
.TP
|
||||
.BI $$\ = \ value
|
||||
A sub-rule can return a semantic
|
||||
.I value
|
||||
from an action by assigning it to the pseudo-variable '$$'. All
|
||||
semantic values must have the same type (which defaults to 'int').
|
||||
This type can be changed by defining YYSTYPE in a declaration section.
|
||||
.TP
|
||||
.IB identifier : name
|
||||
The semantic value returned (by assigning to '$$') from the sub-rule
|
||||
.I name
|
||||
is associated with the
|
||||
.I identifier
|
||||
and can be referred to in subsequent actions.
|
||||
.PP
|
||||
The desk calclator example below illustrates the use of '$$' and ':'.
|
||||
.SH LEG EXAMPLE: A DESK CALCULATOR
|
||||
The extensions in
|
||||
.I leg
|
||||
described above allow useful parsers and evaluators (including
|
||||
declarations, grammar rules, and supporting C functions such
|
||||
as 'main') to be kept within a single source file. To illustrate this
|
||||
we show a simple desk calculator supporting the four common arithmetic
|
||||
operators and named variables. The intermediate results of arithmetic
|
||||
evaluation will be accumulated on an implicit stack by returning them
|
||||
as semantic values from sub-rules.
|
||||
.nf
|
||||
|
||||
%{
|
||||
#include <stdio.h> /* printf() */
|
||||
#include <stdlib.h> /* atoi() */
|
||||
int vars[26];
|
||||
%}
|
||||
|
||||
Stmt = - e:Expr EOL { printf("%d\\n", e); }
|
||||
| ( !EOL . )* EOL { printf("error\\n"); }
|
||||
|
||||
Expr = i:ID ASSIGN s:Sum { $$ = vars[i] = s; }
|
||||
| s:Sum { $$ = s; }
|
||||
|
||||
Sum = l:Product
|
||||
( PLUS r:Product { l += r; }
|
||||
| MINUS r:Product { l -= r; }
|
||||
)* { $$ = l; }
|
||||
|
||||
Product = l:Value
|
||||
( TIMES r:Value { l *= r; }
|
||||
| DIVIDE r:Value { l /= r; }
|
||||
)* { $$ = l; }
|
||||
|
||||
Value = i:NUMBER { $$ = atoi(yytext); }
|
||||
| i:ID !ASSIGN { $$ = vars[i]; }
|
||||
| OPEN i:Expr CLOSE { $$ = i; }
|
||||
|
||||
NUMBER = < [0-9]+ > - { $$ = atoi(yytext); }
|
||||
ID = < [a-z] > - { $$ = yytext[0] - 'a'; }
|
||||
ASSIGN = '=' -
|
||||
PLUS = '+' -
|
||||
MINUS = '-' -
|
||||
TIMES = '*' -
|
||||
DIVIDE = '/' -
|
||||
OPEN = '(' -
|
||||
CLOSE = ')' -
|
||||
|
||||
- = [ \\t]*
|
||||
EOL = '\\n' | '\\r\\n' | '\\r' | ';'
|
||||
|
||||
%%
|
||||
|
||||
int main()
|
||||
{
|
||||
while (yyparse())
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
|
||||
.fi
|
||||
.SH LEG GRAMMAR FOR LEG GRAMMARS
|
||||
The grammar for
|
||||
.I leg
|
||||
grammars is shown below. This will both illustrate and formalise the
|
||||
above description.
|
||||
.nf
|
||||
|
||||
grammar = -
|
||||
( declaration | definition )+
|
||||
trailer? end-of-file
|
||||
|
||||
declaration = '%{' < ( !'%}' . )* > RPERCENT
|
||||
|
||||
trailer = '%%' < .* >
|
||||
|
||||
definition = identifier EQUAL expression SEMICOLON?
|
||||
|
||||
expression = sequence ( BAR sequence )*
|
||||
|
||||
sequence = prefix+
|
||||
|
||||
prefix = AND action
|
||||
| ( AND | NOT )? suffix
|
||||
|
||||
suffix = primary ( QUERY | STAR | PLUS )?
|
||||
|
||||
primary = identifier COLON identifier !EQUAL
|
||||
| identifier !EQUAL
|
||||
| OPEN expression CLOSE
|
||||
| literal
|
||||
| class
|
||||
| DOT
|
||||
| action
|
||||
| BEGIN
|
||||
| END
|
||||
|
||||
identifier = < [-a-zA-Z_][-a-zA-Z_0-9]* > -
|
||||
|
||||
literal = ['] < ( !['] char )* > ['] -
|
||||
| ["] < ( !["] char )* > ["] -
|
||||
|
||||
class = '[' < ( !']' range )* > ']' -
|
||||
|
||||
range = char '-' char | char
|
||||
|
||||
char = '\\\\' [abefnrtv'"\\[\\]\\\\]
|
||||
| '\\\\' [0-3][0-7][0-7]
|
||||
| '\\\\' [0-7][0-7]?
|
||||
| !'\\\\' .
|
||||
|
||||
action = '{' < [^}]* > '}' -
|
||||
|
||||
EQUAL = '=' -
|
||||
COLON = ':' -
|
||||
SEMICOLON = ';' -
|
||||
BAR = '|' -
|
||||
AND = '&' -
|
||||
NOT = '!' -
|
||||
QUERY = '?' -
|
||||
STAR = '*' -
|
||||
PLUS = '+' -
|
||||
OPEN = '(' -
|
||||
CLOSE = ')' -
|
||||
DOT = '.' -
|
||||
BEGIN = '<' -
|
||||
END = '>' -
|
||||
RPERCENT = '%}' -
|
||||
|
||||
- = ( space | comment )*
|
||||
space = ' ' | '\\t' | end-of-line
|
||||
comment = '#' ( !end-of-line . )* end-of-line
|
||||
end-of-line = '\\r\\n' | '\\n' | '\\r'
|
||||
end-of-file = !.
|
||||
|
||||
.fi
|
||||
.SH CUSTOMISING THE PARSER
|
||||
The following symbols can be redefined in declaration sections to
|
||||
modify the generated parser code.
|
||||
.TP
|
||||
.B YYSTYPE
|
||||
The semantic value type. The pseudo-variable '$$' and the
|
||||
identifiers 'bound' to rule results with the colon operator ':' should
|
||||
all be considered as being declared to have this type. The default
|
||||
value is 'int'.
|
||||
.TP
|
||||
.B YYPARSE
|
||||
The name of the main entry point to the parser. The default value
|
||||
is 'yyparse'.
|
||||
.TP
|
||||
.B YYPARSEFROM
|
||||
The name of an alternative entry point to the parser. This function
|
||||
expects one argument: the function corresponding to the rule from
|
||||
which the search for a match should begin. The default
|
||||
is 'yyparsefrom'. Note that yyparse() is defined as
|
||||
.nf
|
||||
|
||||
int yyparse() { return yyparsefrom(yy_foo); }
|
||||
|
||||
.fi
|
||||
where 'foo' is the name of the first rule in the grammar.
|
||||
.TP
|
||||
.BI YY_INPUT( buf , \ result , \ max_size )
|
||||
This macro is invoked by the parser to obtain more input text.
|
||||
.I buf
|
||||
points to an area of memory that can hold at most
|
||||
.I max_size
|
||||
characters. The macro should copy input text to
|
||||
.I buf
|
||||
and then assign the integer variable
|
||||
.I result
|
||||
to indicate the number of characters copied. If no more input is available,
|
||||
the macro should assign 0 to
|
||||
.IR result .
|
||||
By default, the YY_INPUT macro is defined as follows.
|
||||
.nf
|
||||
|
||||
#define YY_INPUT(buf, result, max_size) \\
|
||||
{ \\
|
||||
int yyc= getchar(); \\
|
||||
result= (EOF == yyc) ? 0 : (*(buf)= yyc, 1); \\
|
||||
}
|
||||
|
||||
.fi
|
||||
.TP
|
||||
.B YY_DEBUG
|
||||
If this symbols is defined then additional code will be included in
|
||||
the parser that prints vast quantities of arcane information to the
|
||||
standard error while the parser is running.
|
||||
.TP
|
||||
.B YY_BEGIN
|
||||
This macro is invoked to mark the start of input text that will be
|
||||
made available in actions as 'yytext'. This corresponds to
|
||||
occurrences of '<' in the grammar. These are converted into
|
||||
predicates that are expected to succeed. The default definition
|
||||
.nf
|
||||
|
||||
#define YY_BEGIN (yybegin= yypos, 1)
|
||||
|
||||
.fi
|
||||
therefore saves the current input position and returns 1 ('true') as
|
||||
the result of the predicate.
|
||||
.TP
|
||||
.B YY_END
|
||||
This macros corresponds to '>' in the grammar. Again, it is a
|
||||
predicate so the default definition saves the input position
|
||||
before 'succeeding'.
|
||||
.nf
|
||||
|
||||
#define YY_END (yyend= yypos, 1)
|
||||
|
||||
.fi
|
||||
.TP
|
||||
.BI YY_PARSE( T )
|
||||
This macro declares the parser entry points (yyparse and yyparsefrom)
|
||||
to be of type
|
||||
.IR T .
|
||||
The default definition
|
||||
.nf
|
||||
|
||||
#define YY_PARSE(T) T
|
||||
|
||||
.fi
|
||||
leaves yyparse() and yyparsefrom() with global visibility. If they
|
||||
should not be externally visible in other source files, this macro can
|
||||
be redefined to declare them 'static'.
|
||||
.nf
|
||||
|
||||
#define YY_PARSE(T) static T
|
||||
|
||||
.fi
|
||||
.TP
|
||||
.BI YY_CTX_LOCAL
|
||||
If this symbol is defined during compilation of a generated parser
|
||||
then global parser state will be kept in a structure of
|
||||
type 'yycontext' which can be declared as a local variable. This
|
||||
allows multiple instances of parsers to coexist and to be thread-safe.
|
||||
The parsing function
|
||||
.IR yyparse ()
|
||||
will be declared to expect a first argument of type 'yycontext *', an
|
||||
instance of the structure holding the global state for the parser.
|
||||
This instance must be allocated and initialised to zero by the client.
|
||||
A trivial but complete example is as follows.
|
||||
.nf
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define YY_CTX_LOCAL
|
||||
|
||||
#include "the-generated-parser.peg.c"
|
||||
|
||||
int main()
|
||||
{
|
||||
yycontext ctx;
|
||||
memset(&ctx, 0, sizeof(yycontext));
|
||||
while (yyparse(&ctx));
|
||||
return 0;
|
||||
}
|
||||
|
||||
.fi
|
||||
Note that if this symbol is undefined then the compiled parser will
|
||||
statically allocate its global state and will be neither reentrant nor
|
||||
thread-safe.
|
||||
.TP
|
||||
.BI YY_CTX_MEMBERS
|
||||
If YY_CTX_LOCAL is defined (see above) then the macro YY_CTX_MEMBERS
|
||||
can be defined to expand to any additional member field declarations
|
||||
that the client would like included in the declaration of
|
||||
the 'yycontext' structure type. These additional members are
|
||||
otherwise ignored by the generated parser. The instance
|
||||
of 'yycontext' associated with the currently-active parser is
|
||||
available in actions through the pointer variable
|
||||
.IR yyctx .
|
||||
.PP
|
||||
The following variables can be reffered to within actions.
|
||||
.TP
|
||||
.B char *yybuf
|
||||
This variable points to the parser's input buffer used to store input
|
||||
text that has not yet been matched.
|
||||
.TP
|
||||
.B int yypos
|
||||
This is the offset (in yybuf) of the next character to be matched and
|
||||
consumed.
|
||||
.TP
|
||||
.B char *yytext
|
||||
The most recent matched text delimited by '<' and '>' is stored in this variable.
|
||||
.TP
|
||||
.B int yyleng
|
||||
This variable indicates the number of characters in 'yytext'.
|
||||
.TP
|
||||
.B yycontext *yyctx
|
||||
This variable points to the instance of 'yycontext' associated with
|
||||
the currently-active parser.
|
||||
.SH DIAGNOSTICS
|
||||
.I peg
|
||||
and
|
||||
.I leg
|
||||
warn about the following conditions while converting a grammar into a parser.
|
||||
.TP
|
||||
.B syntax error
|
||||
The input grammar was malformed in some way. The error message will
|
||||
include the text about to be matched (often backed up a huge amount
|
||||
from the actual location of the error) and the line number of the most
|
||||
recently considered character (which is often the real location of the
|
||||
problem).
|
||||
.TP
|
||||
.B rule 'foo' used but not defined
|
||||
The grammar referred to a rule named 'foo' but no definition for it
|
||||
was given. Attempting to use the generated parser will likely result
|
||||
in errors from the linker due to undefined symbols associated with the
|
||||
missing rule.
|
||||
.TP
|
||||
.B rule 'foo' defined but not used
|
||||
The grammar defined a rule named 'foo' and then ignored it. The code
|
||||
associated with the rule is included in the generated parser which
|
||||
will in all other respects be healthy.
|
||||
.TP
|
||||
.B possible infinite left recursion in rule 'foo'
|
||||
There exists at least one path through the grammar that leads from the
|
||||
rule 'foo' back to (a recursive invocation of) the same rule without
|
||||
consuming any input.
|
||||
.PP
|
||||
Left recursion, especially that found in standards documents, is
|
||||
often 'direct' and implies trivial repetition.
|
||||
.nf
|
||||
|
||||
# (6.7.6)
|
||||
direct-abstract-declarator =
|
||||
LPAREN abstract-declarator RPAREN
|
||||
| direct-abstract-declarator? LBRACKET assign-expr? RBRACKET
|
||||
| direct-abstract-declarator? LBRACKET STAR RBRACKET
|
||||
| direct-abstract-declarator? LPAREN param-type-list? RPAREN
|
||||
|
||||
.fi
|
||||
The recursion can easily be eliminated by converting the parts of the
|
||||
pattern following the recursion into a repeatable suffix.
|
||||
.nf
|
||||
|
||||
# (6.7.6)
|
||||
direct-abstract-declarator =
|
||||
direct-abstract-declarator-head?
|
||||
direct-abstract-declarator-tail*
|
||||
|
||||
direct-abstract-declarator-head =
|
||||
LPAREN abstract-declarator RPAREN
|
||||
|
||||
direct-abstract-declarator-tail =
|
||||
LBRACKET assign-expr? RBRACKET
|
||||
| LBRACKET STAR RBRACKET
|
||||
| LPAREN param-type-list? RPAREN
|
||||
|
||||
.fi
|
||||
.SH BUGS
|
||||
The 'yy' and 'YY' prefixes cannot be changed.
|
||||
.PP
|
||||
Left recursion is detected in the input grammar but is not handled
|
||||
correctly in the generated parser.
|
||||
.PP
|
||||
Diagnostics for errors in the input grammar are obscure and not
|
||||
particularly helpful.
|
||||
.PP
|
||||
Several commonly-used
|
||||
.IR lex (1)
|
||||
features (yywrap(), yyin, etc.) are completely absent.
|
||||
.PP
|
||||
The generated parser foes not contain '#line' directives to direct C
|
||||
compiler errors back to the grammar description when appropriate.
|
||||
.IR lex (1)
|
||||
features (yywrap(), yyin, etc.) are completely absent.
|
||||
.SH SEE ALSO
|
||||
D. Val Schorre,
|
||||
.I META II, a syntax-oriented compiler writing language,
|
||||
19th ACM National Conference, 1964, pp.\ 41.301--41.311. Describes a
|
||||
self-implementing parser generator for analytic grammars with no
|
||||
backtracking.
|
||||
.PP
|
||||
Alexander Birman,
|
||||
.I The TMG Recognition Schema,
|
||||
Ph.D. dissertation, Princeton, 1970. A mathematical treatment of the
|
||||
power and complexity of recursive-descent parsing with backtracking.
|
||||
.PP
|
||||
Bryan Ford,
|
||||
.I Parsing Expression Grammars: A Recognition-Based Syntactic Foundation,
|
||||
ACM SIGPLAN Symposium on Principles of Programming Languages, 2004.
|
||||
Defines PEGs and analyses them in relation to context-free and regular
|
||||
grammars. Introduces the syntax adopted in
|
||||
.IR peg .
|
||||
.PP
|
||||
The standard Unix utilies
|
||||
.IR lex (1)
|
||||
and
|
||||
.IR yacc (1)
|
||||
which influenced the syntax and features of
|
||||
.IR leg .
|
||||
.PP
|
||||
The source code for
|
||||
.I peg
|
||||
and
|
||||
.I leg
|
||||
whose grammar parsers are written using themselves.
|
||||
.PP
|
||||
The latest version of this software and documentation:
|
||||
.nf
|
||||
|
||||
http://piumarta.com/software/peg
|
||||
|
||||
.fi
|
||||
.SH AUTHOR
|
||||
.IR peg ,
|
||||
.I leg
|
||||
and this manual page were written by Ian Piumarta (first-name at
|
||||
last-name dot com) while investigating the viablility of regular- and
|
||||
parsing-expression grammars for efficiently extracting type and
|
||||
signature information from C header files.
|
||||
.PP
|
||||
Please send bug reports and suggestions for improvements to the author
|
||||
at the above address.
|
173
supportlibs/pegmarkdown/peg-0.1.9/peg.c
Normal file
173
supportlibs/pegmarkdown/peg-0.1.9/peg.c
Normal file
@ -0,0 +1,173 @@
|
||||
/* Copyright (c) 2007 by Ian Piumarta
|
||||
* All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the 'Software'),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, provided that the above copyright notice(s) and this
|
||||
* permission notice appear in all copies of the Software. Acknowledgement
|
||||
* of the use of this Software in supporting documentation would be
|
||||
* appreciated but is not required.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED 'AS IS'. USE ENTIRELY AT YOUR OWN RISK.
|
||||
*
|
||||
* Last edited: 2012-04-29 15:49:09 by piumarta on emilia
|
||||
*/
|
||||
|
||||
#include "tree.h"
|
||||
#include "version.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <libgen.h>
|
||||
#include <assert.h>
|
||||
|
||||
FILE *input= 0;
|
||||
|
||||
int verboseFlag= 0;
|
||||
|
||||
static int lineNumber= 0;
|
||||
static char *fileName= 0;
|
||||
|
||||
void yyerror(char *message);
|
||||
|
||||
#define YY_INPUT(buf, result, max) \
|
||||
{ \
|
||||
int c= getc(input); \
|
||||
if ('\n' == c || '\r' == c) ++lineNumber; \
|
||||
result= (EOF == c) ? 0 : (*(buf)= c, 1); \
|
||||
}
|
||||
|
||||
#define YY_LOCAL(T) static T
|
||||
#define YY_RULE(T) static T
|
||||
|
||||
#include "peg.peg-c"
|
||||
|
||||
void yyerror(char *message)
|
||||
{
|
||||
fprintf(stderr, "%s:%d: %s", fileName, lineNumber, message);
|
||||
if (yyctx->text[0]) fprintf(stderr, " near token '%s'", yyctx->text);
|
||||
if (yyctx->pos < yyctx->limit || !feof(input))
|
||||
{
|
||||
yyctx->buf[yyctx->limit]= '\0';
|
||||
fprintf(stderr, " before text \"");
|
||||
while (yyctx->pos < yyctx->limit)
|
||||
{
|
||||
if ('\n' == yyctx->buf[yyctx->pos] || '\r' == yyctx->buf[yyctx->pos]) break;
|
||||
fputc(yyctx->buf[yyctx->pos++], stderr);
|
||||
}
|
||||
if (yyctx->pos == yyctx->limit)
|
||||
{
|
||||
int c;
|
||||
while (EOF != (c= fgetc(input)) && '\n' != c && '\r' != c)
|
||||
fputc(c, stderr);
|
||||
}
|
||||
fputc('\"', stderr);
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static void version(char *name)
|
||||
{
|
||||
printf("%s version %d.%d.%d\n", name, PEG_MAJOR, PEG_MINOR, PEG_LEVEL);
|
||||
}
|
||||
|
||||
static void usage(char *name)
|
||||
{
|
||||
version(name);
|
||||
fprintf(stderr, "usage: %s [<option>...] [<file>...]\n", name);
|
||||
fprintf(stderr, "where <option> can be\n");
|
||||
fprintf(stderr, " -h print this help information\n");
|
||||
fprintf(stderr, " -o <ofile> write output to <ofile>\n");
|
||||
fprintf(stderr, " -v be verbose\n");
|
||||
fprintf(stderr, " -V print version number and exit\n");
|
||||
fprintf(stderr, "if no <file> is given, input is read from stdin\n");
|
||||
fprintf(stderr, "if no <ofile> is given, output is written to stdout\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
Node *n;
|
||||
int c;
|
||||
|
||||
output= stdout;
|
||||
input= stdin;
|
||||
lineNumber= 1;
|
||||
fileName= "<stdin>";
|
||||
|
||||
while (-1 != (c= getopt(argc, argv, "Vho:v")))
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case 'V':
|
||||
version(basename(argv[0]));
|
||||
exit(0);
|
||||
|
||||
case 'h':
|
||||
usage(basename(argv[0]));
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
if (!(output= fopen(optarg, "w")))
|
||||
{
|
||||
perror(optarg);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
verboseFlag= 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "for usage try: %s -h\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc)
|
||||
{
|
||||
for (; argc; --argc, ++argv)
|
||||
{
|
||||
if (!strcmp(*argv, "-"))
|
||||
{
|
||||
input= stdin;
|
||||
fileName= "<stdin>";
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(input= fopen(*argv, "r")))
|
||||
{
|
||||
perror(*argv);
|
||||
exit(1);
|
||||
}
|
||||
fileName= *argv;
|
||||
}
|
||||
lineNumber= 1;
|
||||
if (!yyparse())
|
||||
yyerror("syntax error");
|
||||
if (input != stdin)
|
||||
fclose(input);
|
||||
}
|
||||
}
|
||||
else
|
||||
if (!yyparse())
|
||||
yyerror("syntax error");
|
||||
|
||||
if (verboseFlag)
|
||||
for (n= rules; n; n= n->any.next)
|
||||
Rule_print(n);
|
||||
|
||||
Rule_compile_c_header();
|
||||
if (rules) Rule_compile_c(rules);
|
||||
|
||||
return 0;
|
||||
}
|
77
supportlibs/pegmarkdown/peg-0.1.9/peg.peg
Normal file
77
supportlibs/pegmarkdown/peg-0.1.9/peg.peg
Normal file
@ -0,0 +1,77 @@
|
||||
# PE Grammar for PE Grammars
|
||||
#
|
||||
# Adapted from [1] by Ian Piumarta <first-name at last-name point com>.
|
||||
#
|
||||
# Local modifications (marked '#ikp') to support:
|
||||
# C text in '{ ... }' copied verbatim to output as 'semantic action'
|
||||
# input consumed between '<' and '>' is 'char yytext[]' in semantic actions
|
||||
#
|
||||
# Best viewed using 140 columns monospaced with tabs every 8.
|
||||
#
|
||||
# [1] Bryan Ford. "Parsing Expression Grammars: A Recognition-Based Syntactic
|
||||
# Foundation." Symposium on Principles of Programming Languages,
|
||||
# January 14--16, 2004, Venice, Italy.
|
||||
#
|
||||
# Last edited: 2007-05-15 10:32:44 by piumarta on emilia
|
||||
|
||||
# Hierarchical syntax
|
||||
|
||||
Grammar <- Spacing Definition+ EndOfFile
|
||||
|
||||
Definition <- Identifier { if (push(beginRule(findRule(yytext)))->rule.expression) fprintf(stderr, "rule '%s' redefined\n", yytext); }
|
||||
LEFTARROW Expression { Node *e= pop(); Rule_setExpression(pop(), e); } &{ YYACCEPT }
|
||||
Expression <- Sequence (SLASH Sequence { Node *f= pop(); push(Alternate_append(pop(), f)); }
|
||||
)*
|
||||
Sequence <- Prefix (Prefix { Node *f= pop(); push(Sequence_append(pop(), f)); } #ikp expanded from 'Seq <- Prefix*'
|
||||
)*
|
||||
/ { push(makePredicate("1")); } #ikp added
|
||||
Prefix <- AND Action { push(makePredicate(yytext)); } #ikp added
|
||||
/ AND Suffix { push(makePeekFor(pop())); } #ikp expanded from 'Prefix <- (AND/NOT)? Suffix'
|
||||
/ NOT Suffix { push(makePeekNot(pop())); }
|
||||
/ Suffix
|
||||
Suffix <- Primary (QUESTION { push(makeQuery(pop())); }
|
||||
/ STAR { push(makeStar (pop())); }
|
||||
/ PLUS { push(makePlus (pop())); }
|
||||
)?
|
||||
Primary <- Identifier !LEFTARROW { push(makeName(findRule(yytext))); }
|
||||
/ OPEN Expression CLOSE
|
||||
/ Literal { push(makeString(yytext)); }
|
||||
/ Class { push(makeClass(yytext)); }
|
||||
/ DOT { push(makeDot()); }
|
||||
/ Action { push(makeAction(yytext)); } #ikp added
|
||||
/ BEGIN { push(makePredicate("YY_BEGIN")); } #ikp added
|
||||
/ END { push(makePredicate("YY_END")); } #ikp added
|
||||
|
||||
# Lexical syntax
|
||||
|
||||
Identifier <- < IdentStart IdentCont* > Spacing #ikp inserted < ... >
|
||||
IdentStart <- [a-zA-Z_]
|
||||
IdentCont <- IdentStart / [0-9]
|
||||
Literal <- ['] < (!['] Char )* > ['] Spacing #ikp inserted < ... >
|
||||
/ ["] < (!["] Char )* > ["] Spacing #ikp inserted < ... >
|
||||
Class <- '[' < (!']' Range)* > ']' Spacing #ikp inserted < ... >
|
||||
Range <- Char '-' Char / Char
|
||||
Char <- '\\' [abefnrtv'"\[\]\\] #ikp added missing ANSI escapes: abefv
|
||||
/ '\\' [0-3][0-7][0-7]
|
||||
/ '\\' [0-7][0-7]?
|
||||
/ '\\' '-' #ikp added
|
||||
/ !'\\' .
|
||||
LEFTARROW <- '<-' Spacing
|
||||
SLASH <- '/' Spacing
|
||||
AND <- '&' Spacing
|
||||
NOT <- '!' Spacing
|
||||
QUESTION <- '?' Spacing
|
||||
STAR <- '*' Spacing
|
||||
PLUS <- '+' Spacing
|
||||
OPEN <- '(' Spacing
|
||||
CLOSE <- ')' Spacing
|
||||
DOT <- '.' Spacing
|
||||
Spacing <- (Space / Comment)*
|
||||
Comment <- '#' (!EndOfLine .)* EndOfLine
|
||||
Space <- ' ' / '\t' / EndOfLine
|
||||
EndOfLine <- '\r\n' / '\n' / '\r'
|
||||
EndOfFile <- !.
|
||||
|
||||
Action <- '{' < [^}]* > '}' Spacing #ikp added
|
||||
BEGIN <- '<' Spacing #ikp added
|
||||
END <- '>' Spacing #ikp added
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user