Compare commits
105 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7f22cac676 | |||
| fc8039010f | |||
| bdcd2d8a69 | |||
| cd55f40353 | |||
| 4df49785d2 | |||
| bed96f76ad | |||
| 6e0cba6f77 | |||
| 0b83cde16b | |||
| d947bc4973 | |||
| 3c094cabae | |||
| 7dada0fe9a | |||
| 417e4b9a10 | |||
| 4ff297358f | |||
| df917df6a3 | |||
| 63f5a1ff82 | |||
| 260e1b0a46 | |||
| 783fa83c5d | |||
| 3310439a20 | |||
| cb0e3d2394 | |||
| d05d2da9b9 | |||
| 35f20bc78c | |||
| 6185cfba6d | |||
| 2173098c41 | |||
| 46977d9c7a | |||
| 463734dfab | |||
| f8f6d8976b | |||
| 15287c0e85 | |||
| 28d8f5e73a | |||
| bf5850c112 | |||
| 1931abfa5c | |||
| 460b0cae9b | |||
| 867540f2a4 | |||
| 921c71b7da | |||
| 1d96a33c96 | |||
| a1b9ee2db6 | |||
| d8413c8708 | |||
| 5346b81a51 | |||
| 3d349544bb | |||
| 42cd9cbab3 | |||
| 9ec7bf0755 | |||
| c26815c188 | |||
| 898639006e | |||
| 0e28f93ea7 | |||
| 4526658ffd | |||
| 35265cdefb | |||
| 7965019b35 | |||
| eab37e7fcf | |||
| 287bfb4cc1 | |||
| 93a75c914a | |||
| 00cb392778 | |||
| 36691b0cd6 | |||
| 2b98e93e3e | |||
| bca82faaf5 | |||
| 6877343ffb | |||
| 8b6f007a48 | |||
| 0ec416124b | |||
| 7a694e23a8 | |||
| b93e867ece | |||
| 75072250a1 | |||
| 1a13778b29 | |||
| 830451c347 | |||
| 44fb8e4801 | |||
| 030776f2ba | |||
| 82c45ea1af | |||
| 93262659a6 | |||
| 5187b09104 | |||
| 6ee11016e6 | |||
| 5c558ac91e | |||
| a39398e285 | |||
| 84810efd40 | |||
| c9fce86f78 | |||
| 8ded5daa69 | |||
| 3071cb7933 | |||
| 20b2c067b2 | |||
| 6afa337652 | |||
| c56b264b09 | |||
| 5ff86d7090 | |||
| ae03663ae9 | |||
| 47eba24b08 | |||
| a6e38f5006 | |||
| 9f226d5888 | |||
| 4fe9c024d7 | |||
| e144b9a4a4 | |||
| 70852152db | |||
| 8dabaa211e | |||
| 8f5e205db9 | |||
| 7223e4f106 | |||
| 84c389e651 | |||
| 9fe95a8570 | |||
| 54fea66afb | |||
| 4ab9b37c8a | |||
| a52a3695e5 | |||
| 660dc5e84d | |||
| c3823c58ed | |||
| 10d7a42aea | |||
| 084d4e6407 | |||
| 27d7b53cf0 | |||
| 9a110d5ba4 | |||
| e48e3565f2 | |||
| 9eaa7021e6 | |||
| eb6a08b475 | |||
| 99123324ac | |||
| 506db84cd5 | |||
| f8eba10e5e | |||
| fe219b3e7e |
@@ -0,0 +1 @@
|
||||
*.pbxproj -crlf
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
# Xcode
|
||||
build/*
|
||||
*.pbxuser
|
||||
!default.pbxuser
|
||||
*.mode1v3
|
||||
!default.mode1v3
|
||||
*.mode2v3
|
||||
!default.mode2v3
|
||||
*.perspectivev3
|
||||
!default.perspectivev3
|
||||
*.xcworkspace
|
||||
!default.xcworkspace
|
||||
xcuserdata
|
||||
profile
|
||||
*.moved-aside
|
||||
|
||||
## Ignore incredibly annoying .DS_Store files
|
||||
.DS_Store
|
||||
@@ -1,3 +0,0 @@
|
||||
[submodule "mayday"]
|
||||
path = mayday
|
||||
url = git://github.com/jemmons/mayday.git
|
||||
@@ -0,0 +1,20 @@
|
||||
//
|
||||
// TCLayoutManager.h
|
||||
// MarkdownLive
|
||||
//
|
||||
// Created by Akihiro Noguchi on 7/05/11.
|
||||
// Copyright 2011 Aki. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
|
||||
@interface EditPaneLayoutManager : NSLayoutManager {
|
||||
NSFont *font;
|
||||
}
|
||||
|
||||
@property (nonatomic, strong) NSFont *font;
|
||||
|
||||
- (CGFloat)lineHeight;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,54 @@
|
||||
//
|
||||
// TCLayoutManager.m
|
||||
// MarkdownLive
|
||||
//
|
||||
// Created by Akihiro Noguchi on 7/05/11.
|
||||
// Copyright 2011 Aki. All rights reserved.
|
||||
//
|
||||
|
||||
#import "EditPaneLayoutManager.h"
|
||||
#import "EditPaneTypesetter.h"
|
||||
|
||||
|
||||
@implementation EditPaneLayoutManager
|
||||
|
||||
@synthesize font;
|
||||
|
||||
- (id)init {
|
||||
if ((self = [super init])) {
|
||||
EditPaneTypesetter *typeSetter = [[EditPaneTypesetter alloc] init];
|
||||
[self setTypesetter:typeSetter];
|
||||
[self setUsesFontLeading:NO];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
- (CGFloat)lineHeight {
|
||||
return floor([self defaultLineHeightForFont:font] + 1.5);
|
||||
}
|
||||
|
||||
- (void)setLineFragmentRect:(NSRect)inFragmentRect forGlyphRange:(NSRange)inGlyphRange
|
||||
usedRect:(NSRect)inUsedRect {
|
||||
inFragmentRect.size.height = [self lineHeight];
|
||||
inUsedRect.size.height = [self lineHeight];
|
||||
|
||||
(void)[super setLineFragmentRect:(NSRect)inFragmentRect
|
||||
forGlyphRange:(NSRange)inGlyphRange
|
||||
usedRect:(NSRect)inUsedRect];
|
||||
}
|
||||
|
||||
- (void)setExtraLineFragmentRect:(NSRect)inFragmentRect usedRect:(NSRect)inUsedRect
|
||||
textContainer:(NSTextContainer *)inTextContainer {
|
||||
inFragmentRect.size.height = [self lineHeight];
|
||||
[super setExtraLineFragmentRect:inFragmentRect usedRect:inUsedRect
|
||||
textContainer:inTextContainer];
|
||||
}
|
||||
|
||||
- (NSPoint)locationForGlyphAtIndex:(NSUInteger)inGlyphIndex {
|
||||
NSPoint outPoint = [super locationForGlyphAtIndex:inGlyphIndex];
|
||||
outPoint.y = [font pointSize];
|
||||
return outPoint;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,22 @@
|
||||
//
|
||||
// EditPaneTextView.h
|
||||
// MarkdownLive
|
||||
//
|
||||
// Created by Akihiro Noguchi on 9/05/11.
|
||||
// Copyright 2011 Aki. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
extern NSString * const kEditPaneTextViewChangedNotification;
|
||||
|
||||
@class EditPaneLayoutManager;
|
||||
|
||||
@interface EditPaneTextView : NSTextView {
|
||||
__weak EditPaneLayoutManager *layoutMan;
|
||||
}
|
||||
|
||||
- (void)updateColors;
|
||||
- (void)updateFont;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,128 @@
|
||||
//
|
||||
// EditPaneTextView.m
|
||||
// MarkdownLive
|
||||
//
|
||||
// Created by Akihiro Noguchi on 9/05/11.
|
||||
// Copyright 2011 Aki. All rights reserved.
|
||||
//
|
||||
|
||||
#import "EditPaneTextView.h"
|
||||
#import "EditPaneLayoutManager.h"
|
||||
#import "PreferencesManager.h"
|
||||
#import "PreferencesController.h"
|
||||
|
||||
NSString * const kEditPaneTextViewChangedNotification = @"EditPaneTextViewChangedNotification";
|
||||
NSString * const kEditPaneColorChangedNotification = @"EditPaneColorChangedNotification";
|
||||
|
||||
@implementation EditPaneTextView
|
||||
|
||||
- (void)awakeFromNib {
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(updateFont)
|
||||
name:kEditPaneFontNameChangedNotification
|
||||
object:nil];
|
||||
|
||||
NSUserDefaultsController *defaultsController = [NSUserDefaultsController sharedUserDefaultsController];
|
||||
|
||||
[defaultsController addObserver:self
|
||||
forKeyPath:[NSString stringWithFormat:@"values.%@", kEditPaneForegroundColor]
|
||||
options:0
|
||||
context:(__bridge void *)kEditPaneColorChangedNotification];
|
||||
[defaultsController addObserver:self
|
||||
forKeyPath:[NSString stringWithFormat:@"values.%@", kEditPaneBackgroundColor]
|
||||
options:0
|
||||
context:(__bridge void *)kEditPaneColorChangedNotification];
|
||||
[defaultsController addObserver:self
|
||||
forKeyPath:[NSString stringWithFormat:@"values.%@", kEditPaneSelectionColor]
|
||||
options:0
|
||||
context:(__bridge void *)kEditPaneColorChangedNotification];
|
||||
[defaultsController addObserver:self
|
||||
forKeyPath:[NSString stringWithFormat:@"values.%@", kEditPaneCaretColor]
|
||||
options:0
|
||||
context:(__bridge void *)kEditPaneColorChangedNotification];
|
||||
|
||||
[self setUsesFontPanel:NO];
|
||||
|
||||
NSTextContainer *textContainer = [[NSTextContainer alloc] init];
|
||||
[textContainer setContainerSize:[[self textContainer] containerSize]];
|
||||
[textContainer setWidthTracksTextView:YES];
|
||||
[self replaceTextContainer:textContainer];
|
||||
|
||||
EditPaneLayoutManager *lManager = [[EditPaneLayoutManager alloc] init];
|
||||
[textContainer replaceLayoutManager:lManager];
|
||||
layoutMan = lManager;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
|
||||
NSUserDefaultsController *defaultsController = [NSUserDefaultsController sharedUserDefaultsController];
|
||||
|
||||
[defaultsController removeObserver:self
|
||||
forKeyPath:[NSString stringWithFormat:@"values.%@", kEditPaneForegroundColor]
|
||||
context:(__bridge void *)kEditPaneColorChangedNotification];
|
||||
[defaultsController removeObserver:self
|
||||
forKeyPath:[NSString stringWithFormat:@"values.%@", kEditPaneBackgroundColor]
|
||||
context:(__bridge void *)kEditPaneColorChangedNotification];
|
||||
[defaultsController removeObserver:self
|
||||
forKeyPath:[NSString stringWithFormat:@"values.%@", kEditPaneSelectionColor]
|
||||
context:(__bridge void *)kEditPaneColorChangedNotification];
|
||||
[defaultsController removeObserver:self
|
||||
forKeyPath:[NSString stringWithFormat:@"values.%@", kEditPaneCaretColor]
|
||||
context:(__bridge void *)kEditPaneColorChangedNotification];
|
||||
}
|
||||
|
||||
- (void)keyDown:(NSEvent *)aEvent {
|
||||
[super keyDown:aEvent];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kEditPaneTextViewChangedNotification
|
||||
object:self];
|
||||
}
|
||||
|
||||
- (void)setMarkedText:(id)aString
|
||||
selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange {
|
||||
id resultString;
|
||||
if ([aString isKindOfClass:[NSAttributedString class]]) {
|
||||
resultString = [aString mutableCopy];
|
||||
selectedRange = NSMakeRange(0, [resultString length]);
|
||||
NSDictionary *attrs = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
[NSNumber numberWithInt:NSUnderlineStyleSingle], NSUnderlineStyleAttributeName,
|
||||
[PreferencesManager editPaneForegroundColor], NSUnderlineColorAttributeName,
|
||||
nil];
|
||||
[resultString setAttributes:attrs range:selectedRange];
|
||||
} else {
|
||||
resultString = aString;
|
||||
}
|
||||
|
||||
[super setMarkedText:resultString
|
||||
selectedRange:selectedRange replacementRange:replacementRange];
|
||||
}
|
||||
|
||||
- (void)updateColors {
|
||||
[[self enclosingScrollView] setBackgroundColor:[PreferencesManager editPaneBackgroundColor]];
|
||||
[self setTextColor:[PreferencesManager editPaneForegroundColor]];
|
||||
[self setInsertionPointColor:[PreferencesManager editPaneCaretColor]];
|
||||
NSDictionary *selectedAttr = [NSDictionary dictionaryWithObject:[PreferencesManager editPaneSelectionColor]
|
||||
forKey:NSBackgroundColorAttributeName];
|
||||
[self setSelectedTextAttributes:selectedAttr];
|
||||
}
|
||||
|
||||
- (void)updateFont {
|
||||
layoutMan.font = [PreferencesManager editPaneFont];
|
||||
[self setFont:layoutMan.font];
|
||||
}
|
||||
|
||||
- (void)observeValueForKeyPath:(NSString *)keyPath
|
||||
ofObject:(id)object
|
||||
change:(NSDictionary *)change
|
||||
context:(void *)context {
|
||||
|
||||
#pragma unused(keyPath)
|
||||
#pragma unused(object)
|
||||
#pragma unused(change)
|
||||
|
||||
if ([(__bridge NSString *)context isEqualToString:kEditPaneColorChangedNotification]) {
|
||||
[self updateColors];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,16 @@
|
||||
//
|
||||
// TCTypeSetter.h
|
||||
// MarkdownLive
|
||||
//
|
||||
// Created by Akihiro Noguchi on 7/05/11.
|
||||
// Copyright 2011 Aki. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
|
||||
@interface EditPaneTypesetter : NSATSTypesetter {
|
||||
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,32 @@
|
||||
//
|
||||
// TCTypeSetter.m
|
||||
// MarkdownLive
|
||||
//
|
||||
// Created by Akihiro Noguchi on 7/05/11.
|
||||
// Copyright 2011 Aki. All rights reserved.
|
||||
//
|
||||
|
||||
#import "EditPaneTypesetter.h"
|
||||
#import "EditPaneLayoutManager.h"
|
||||
|
||||
|
||||
@implementation EditPaneTypesetter
|
||||
|
||||
- (id)init {
|
||||
if ((self = [super init])) {
|
||||
[self setUsesFontLeading:YES];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (CGFloat)lineSpacingAfterGlyphAtIndex:(NSUInteger)inGlyphIndex
|
||||
withProposedLineFragmentRect:(NSRect)inRect {
|
||||
|
||||
#pragma unused(inGlyphIndex)
|
||||
|
||||
EditPaneLayoutManager *theManager = (EditPaneLayoutManager *)[self layoutManager];
|
||||
CGFloat theDefaultLineHeight = [theManager defaultLineHeightForFont:theManager.font];
|
||||
return floor(theDefaultLineHeight - inRect.size.height + 1.5);
|
||||
}
|
||||
|
||||
@end
|
||||
+1106
-1957
File diff suppressed because it is too large
Load Diff
+279
-1126
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,15 @@
|
||||
//
|
||||
// MLAppDelegate.m
|
||||
// MarkdownLive
|
||||
//
|
||||
// Created by David Beck on 9/23/11.
|
||||
// Copyright 2011 David Beck. Some rights reserved: <http://opensource.org/licenses/mit-license.php>
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface MLAppDelegate : NSObject <NSApplicationDelegate>
|
||||
|
||||
@property (nonatomic, strong) IBOutlet NSMenuItem *viewMenu;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,22 @@
|
||||
//
|
||||
// MLAppDelegate.m
|
||||
// MarkdownLive
|
||||
//
|
||||
// Created by David Beck on 9/23/11.
|
||||
// Copyright 2011 David Beck. Some rights reserved: <http://opensource.org/licenses/mit-license.php>
|
||||
//
|
||||
|
||||
#import "MLAppDelegate.h"
|
||||
|
||||
@implementation MLAppDelegate
|
||||
|
||||
@synthesize viewMenu = _viewMenu;
|
||||
|
||||
- (void)applicationDidFinishLaunching:(NSNotification *)notification
|
||||
{
|
||||
if ([NSWindow instancesRespondToSelector:@selector(toggleFullScreen:)]) {
|
||||
[[NSApp mainMenu] insertItem:self.viewMenu atIndex:3];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -10,6 +10,10 @@
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>markdown</string>
|
||||
<string>md</string>
|
||||
<string>text</string>
|
||||
<string>txt</string>
|
||||
<string></string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string></string>
|
||||
@@ -40,9 +44,9 @@
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.6</string>
|
||||
<string>1.7.1</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.6</string>
|
||||
<string>1.7.1</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>${MACOSX_DEPLOYMENT_TARGET}</string>
|
||||
<key>NSMainNibFile</key>
|
||||
|
||||
@@ -3,28 +3,96 @@
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 45;
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
11EF12E0142D24BB0086C77F /* MLAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 11EF12DF142D24BB0086C77F /* MLAppDelegate.m */; };
|
||||
1DDD582C0DA1D0D100B32029 /* MyDocument.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1DDD58280DA1D0D100B32029 /* MyDocument.xib */; };
|
||||
1DDD582D0DA1D0D100B32029 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1DDD582A0DA1D0D100B32029 /* MainMenu.xib */; };
|
||||
3D6A8BBC15F0D914002C8B62 /* NSTextView+EditPlainTextWithUndo.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D6A8BBB15F0D914002C8B62 /* NSTextView+EditPlainTextWithUndo.m */; };
|
||||
3D6A8BE115F0F33C002C8B62 /* Ordered List Template.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 3D6A8BDC15F0F33C002C8B62 /* Ordered List Template.pdf */; };
|
||||
3D6A8BE215F0F33C002C8B62 /* Quote Template.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 3D6A8BDD15F0F33C002C8B62 /* Quote Template.pdf */; };
|
||||
3D6A8BE315F0F33C002C8B62 /* Unordered List Template.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 3D6A8BDE15F0F33C002C8B62 /* Unordered List Template.pdf */; };
|
||||
3D8BA23315F160FD000555C7 /* Image Template.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 3D8BA23115F160FD000555C7 /* Image Template.pdf */; };
|
||||
3D8BA23415F160FD000555C7 /* Link Template.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 3D8BA23215F160FD000555C7 /* Link Template.pdf */; };
|
||||
795F6C87105D70A300D1F90A /* MarkdownLiveApp.icns in Resources */ = {isa = PBXBuildFile; fileRef = 795F6C86105D70A300D1F90A /* MarkdownLiveApp.icns */; };
|
||||
795F6CCD105D741100D1F90A /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 795F6CCC105D741100D1F90A /* WebKit.framework */; };
|
||||
79B3D5441060376F00A8D174 /* MDMarkdownParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 79B3D5431060376F00A8D174 /* MDMarkdownParser.m */; };
|
||||
8D15AC2C0486D014006FF6A4 /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 2A37F4B9FDCFA73011CA2CEA /* Credits.rtf */; };
|
||||
8D15AC2F0486D014006FF6A4 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165FFE840EACC02AAC07 /* InfoPlist.strings */; };
|
||||
8D15AC310486D014006FF6A4 /* MyDocument.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A37F4ACFDCFA73011CA2CEA /* MyDocument.m */; settings = {ATTRIBUTES = (); }; };
|
||||
8D15AC320486D014006FF6A4 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 2A37F4B0FDCFA73011CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; };
|
||||
8D15AC340486D014006FF6A4 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A7FEA54F5311CA2CBB /* Cocoa.framework */; };
|
||||
ABE8DDF913CA38B5005852B5 /* styles.css in Resources */ = {isa = PBXBuildFile; fileRef = 226936E612E7CDC500171322 /* styles.css */; };
|
||||
ABECD8C713C8B90E00B77CFD /* mkdio.c in Sources */ = {isa = PBXBuildFile; fileRef = 795F6C4E105D6EC400D1F90A /* mkdio.c */; };
|
||||
ABECD8C813C8B92900B77CFD /* markdown.c in Sources */ = {isa = PBXBuildFile; fileRef = 795F6C50105D6ECE00D1F90A /* markdown.c */; };
|
||||
ABECD8C913C8B92900B77CFD /* generate.c in Sources */ = {isa = PBXBuildFile; fileRef = 795F6C52105D6ED800D1F90A /* generate.c */; };
|
||||
ABECD8CA13C8B92900B77CFD /* resource.c in Sources */ = {isa = PBXBuildFile; fileRef = 795F6C54105D6EE100D1F90A /* resource.c */; };
|
||||
ABECD8CB13C8B92900B77CFD /* xml.c in Sources */ = {isa = PBXBuildFile; fileRef = 795F6C61105D6F6E00D1F90A /* xml.c */; };
|
||||
ABECD8CC13C8B92900B77CFD /* Csio.c in Sources */ = {isa = PBXBuildFile; fileRef = 795F6C65105D6F8500D1F90A /* Csio.c */; };
|
||||
ABECD8CD13C8B92900B77CFD /* emmatch.c in Sources */ = {isa = PBXBuildFile; fileRef = 2269367E12E7C53000171322 /* emmatch.c */; };
|
||||
ABECD8CE13C8B92900B77CFD /* html5.c in Sources */ = {isa = PBXBuildFile; fileRef = 2269369A12E7C6AB00171322 /* html5.c */; };
|
||||
ABECD8CF13C8B92900B77CFD /* tags.c in Sources */ = {isa = PBXBuildFile; fileRef = 2269369E12E7C6BE00171322 /* tags.c */; };
|
||||
ABECD8D013C8B92900B77CFD /* setup.c in Sources */ = {isa = PBXBuildFile; fileRef = 226936C912E7CA2800171322 /* setup.c */; };
|
||||
ABECD8D113C8B94A00B77CFD /* discountWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 795F6DB5105D75D300D1F90A /* discountWrapper.m */; };
|
||||
ABECD8D213C8B94A00B77CFD /* markdownWrapper.c in Sources */ = {isa = PBXBuildFile; fileRef = 795F6DB6105D75D300D1F90A /* markdownWrapper.c */; };
|
||||
ABECD8D313C8B94A00B77CFD /* mkdioWrapper.c in Sources */ = {isa = PBXBuildFile; fileRef = 795F6DB8105D75D300D1F90A /* mkdioWrapper.c */; };
|
||||
ABECD8DE13C8B9C400B77CFD /* ORCDiscount.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = ABECD8C213C8B8CA00B77CFD /* ORCDiscount.framework */; };
|
||||
ABECD8ED13C8BA1A00B77CFD /* discountWrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 795F6DB4105D75D300D1F90A /* discountWrapper.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
ABECD8EF13C8BA2100B77CFD /* markdownWrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 795F6DB7105D75D300D1F90A /* markdownWrapper.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
ABECD8F113C8BA2400B77CFD /* mkdioWrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 795F6DB9105D75D300D1F90A /* mkdioWrapper.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
ABECD95C13C8D14C00B77CFD /* ORCDiscount.h in Headers */ = {isa = PBXBuildFile; fileRef = ABECD95B13C8D14C00B77CFD /* ORCDiscount.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
ABECD96B13C8D2D200B77CFD /* markdown.h in Headers */ = {isa = PBXBuildFile; fileRef = 22ECEED912E7C2E8003B50DC /* markdown.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
ABECD98D13C8D6A900B77CFD /* ORCDiscount.m in Sources */ = {isa = PBXBuildFile; fileRef = ABECD98C13C8D6A900B77CFD /* ORCDiscount.m */; };
|
||||
ABECD9ED13C8DC2B00B77CFD /* ORCDiscount.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ABECD8C213C8B8CA00B77CFD /* ORCDiscount.framework */; };
|
||||
ABF75D7313CDEBBB00B5E7AB /* EditPaneLayoutManager.m in Sources */ = {isa = PBXBuildFile; fileRef = ABF75D6E13CDEBBA00B5E7AB /* EditPaneLayoutManager.m */; };
|
||||
ABF75D7413CDEBBB00B5E7AB /* EditPaneTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = ABF75D6F13CDEBBA00B5E7AB /* EditPaneTextView.m */; };
|
||||
ABF75D7513CDEBBB00B5E7AB /* EditPaneTypesetter.m in Sources */ = {isa = PBXBuildFile; fileRef = ABF75D7013CDEBBA00B5E7AB /* EditPaneTypesetter.m */; };
|
||||
ABF75D7613CDEBBB00B5E7AB /* PreferencesController.m in Sources */ = {isa = PBXBuildFile; fileRef = ABF75D7113CDEBBA00B5E7AB /* PreferencesController.m */; };
|
||||
ABF75D7713CDEBBB00B5E7AB /* PreferencesManager.m in Sources */ = {isa = PBXBuildFile; fileRef = ABF75D7213CDEBBA00B5E7AB /* PreferencesManager.m */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
ABECD8D713C8B98D00B77CFD /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 2A37F4A9FDCFA73011CA2CEA /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = ABECD8C113C8B8CA00B77CFD;
|
||||
remoteInfo = Discount;
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
ABECD8EA13C8B9E700B77CFD /* Copy Frameworks */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = "";
|
||||
dstSubfolderSpec = 10;
|
||||
files = (
|
||||
ABECD8DE13C8B9C400B77CFD /* ORCDiscount.framework in Copy Frameworks */,
|
||||
);
|
||||
name = "Copy Frameworks";
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
089C1660FE840EACC02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
1058C7A7FEA54F5311CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
|
||||
11EF12DE142D24BB0086C77F /* MLAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MLAppDelegate.h; sourceTree = "<group>"; };
|
||||
11EF12DF142D24BB0086C77F /* MLAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MLAppDelegate.m; sourceTree = "<group>"; };
|
||||
13E42FBA07B3F13500E4EEF1 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = "<absolute>"; };
|
||||
1DDD58290DA1D0D100B32029 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/MyDocument.xib; sourceTree = "<group>"; };
|
||||
1DDD582B0DA1D0D100B32029 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/MainMenu.xib; sourceTree = "<group>"; };
|
||||
2269367E12E7C53000171322 /* emmatch.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = emmatch.c; sourceTree = "<group>"; };
|
||||
2269369A12E7C6AB00171322 /* html5.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = html5.c; sourceTree = "<group>"; };
|
||||
2269369E12E7C6BE00171322 /* tags.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tags.c; sourceTree = "<group>"; };
|
||||
2269369F12E7C6BE00171322 /* tags.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tags.h; sourceTree = "<group>"; };
|
||||
226936B912E7C8B600171322 /* mkdio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mkdio.h; sourceTree = "<group>"; };
|
||||
226936C912E7CA2800171322 /* setup.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = setup.c; sourceTree = "<group>"; };
|
||||
226936E612E7CDC500171322 /* styles.css */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.css; path = styles.css; sourceTree = "<group>"; };
|
||||
22ECEEC612E7C258003B50DC /* config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = config.h; sourceTree = "<group>"; };
|
||||
22ECEED912E7C2E8003B50DC /* markdown.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = markdown.h; sourceTree = "<group>"; };
|
||||
2564AD2C0F5327BB00F57823 /* MarkdownLive_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MarkdownLive_Prefix.pch; sourceTree = "<group>"; };
|
||||
2A37F4ACFDCFA73011CA2CEA /* MyDocument.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MyDocument.m; sourceTree = "<group>"; };
|
||||
2A37F4AEFDCFA73011CA2CEA /* MyDocument.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MyDocument.h; sourceTree = "<group>"; };
|
||||
@@ -32,12 +100,44 @@
|
||||
2A37F4BAFDCFA73011CA2CEA /* English */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = English; path = English.lproj/Credits.rtf; sourceTree = "<group>"; };
|
||||
2A37F4C4FDCFA73011CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = "<absolute>"; };
|
||||
2A37F4C5FDCFA73011CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
|
||||
3D6A8BBA15F0D914002C8B62 /* NSTextView+EditPlainTextWithUndo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSTextView+EditPlainTextWithUndo.h"; sourceTree = "<group>"; };
|
||||
3D6A8BBB15F0D914002C8B62 /* NSTextView+EditPlainTextWithUndo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSTextView+EditPlainTextWithUndo.m"; sourceTree = "<group>"; };
|
||||
3D6A8BDC15F0F33C002C8B62 /* Ordered List Template.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = "Ordered List Template.pdf"; sourceTree = "<group>"; };
|
||||
3D6A8BDD15F0F33C002C8B62 /* Quote Template.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = "Quote Template.pdf"; sourceTree = "<group>"; };
|
||||
3D6A8BDE15F0F33C002C8B62 /* Unordered List Template.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = "Unordered List Template.pdf"; sourceTree = "<group>"; };
|
||||
3D8BA23115F160FD000555C7 /* Image Template.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = "Image Template.pdf"; sourceTree = "<group>"; };
|
||||
3D8BA23215F160FD000555C7 /* Link Template.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = "Link Template.pdf"; sourceTree = "<group>"; };
|
||||
3DD161871431FCED0003F6C7 /* PreferencesController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PreferencesController.h; sourceTree = "<group>"; };
|
||||
3DD161881431FCF40003F6C7 /* EditPaneTypesetter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EditPaneTypesetter.h; sourceTree = "<group>"; };
|
||||
3DD161891431FCFC0003F6C7 /* EditPaneTextView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EditPaneTextView.h; sourceTree = "<group>"; };
|
||||
3DD1618A1431FD030003F6C7 /* EditPaneLayoutManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EditPaneLayoutManager.h; sourceTree = "<group>"; };
|
||||
3DD1618B1431FD0B0003F6C7 /* PreferencesManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PreferencesManager.h; sourceTree = "<group>"; };
|
||||
795F6C4E105D6EC400D1F90A /* mkdio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mkdio.c; sourceTree = "<group>"; };
|
||||
795F6C50105D6ECE00D1F90A /* markdown.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = markdown.c; sourceTree = "<group>"; };
|
||||
795F6C52105D6ED800D1F90A /* generate.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = generate.c; sourceTree = "<group>"; };
|
||||
795F6C54105D6EE100D1F90A /* resource.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = resource.c; sourceTree = "<group>"; };
|
||||
795F6C61105D6F6E00D1F90A /* xml.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xml.c; sourceTree = "<group>"; };
|
||||
795F6C65105D6F8500D1F90A /* Csio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = Csio.c; sourceTree = "<group>"; };
|
||||
795F6C86105D70A300D1F90A /* MarkdownLiveApp.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = MarkdownLiveApp.icns; sourceTree = "<group>"; };
|
||||
795F6CCC105D741100D1F90A /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = /System/Library/Frameworks/WebKit.framework; sourceTree = "<absolute>"; };
|
||||
79B3D5421060376F00A8D174 /* MDMarkdownParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MDMarkdownParser.h; path = mayday/MDMarkdownParser.h; sourceTree = "<group>"; };
|
||||
79B3D5431060376F00A8D174 /* MDMarkdownParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MDMarkdownParser.m; path = mayday/MDMarkdownParser.m; sourceTree = "<group>"; };
|
||||
795F6DB4105D75D300D1F90A /* discountWrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = discountWrapper.h; sourceTree = "<group>"; };
|
||||
795F6DB5105D75D300D1F90A /* discountWrapper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = discountWrapper.m; sourceTree = "<group>"; };
|
||||
795F6DB6105D75D300D1F90A /* markdownWrapper.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = markdownWrapper.c; sourceTree = "<group>"; };
|
||||
795F6DB7105D75D300D1F90A /* markdownWrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = markdownWrapper.h; sourceTree = "<group>"; };
|
||||
795F6DB8105D75D300D1F90A /* mkdioWrapper.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mkdioWrapper.c; sourceTree = "<group>"; };
|
||||
795F6DB9105D75D300D1F90A /* mkdioWrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mkdioWrapper.h; sourceTree = "<group>"; };
|
||||
8D15AC360486D014006FF6A4 /* MarkdownLive-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "MarkdownLive-Info.plist"; sourceTree = "<group>"; };
|
||||
8D15AC370486D014006FF6A4 /* MarkdownLive.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MarkdownLive.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
ABCE3DDF13C8DFFF00DF3CD0 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README.md; sourceTree = "<group>"; };
|
||||
ABECD8C213C8B8CA00B77CFD /* ORCDiscount.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ORCDiscount.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
ABECD8C313C8B8CA00B77CFD /* ORCDiscount-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "ORCDiscount-Info.plist"; sourceTree = "<group>"; };
|
||||
ABECD95B13C8D14C00B77CFD /* ORCDiscount.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ORCDiscount.h; path = ORCDiscount/ORCDiscount.h; sourceTree = "<group>"; };
|
||||
ABECD98C13C8D6A900B77CFD /* ORCDiscount.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ORCDiscount.m; path = ORCDiscount/ORCDiscount.m; sourceTree = "<group>"; };
|
||||
ABF75D6E13CDEBBA00B5E7AB /* EditPaneLayoutManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EditPaneLayoutManager.m; sourceTree = "<group>"; };
|
||||
ABF75D6F13CDEBBA00B5E7AB /* EditPaneTextView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EditPaneTextView.m; sourceTree = "<group>"; };
|
||||
ABF75D7013CDEBBA00B5E7AB /* EditPaneTypesetter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EditPaneTypesetter.m; sourceTree = "<group>"; };
|
||||
ABF75D7113CDEBBA00B5E7AB /* PreferencesController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PreferencesController.m; sourceTree = "<group>"; };
|
||||
ABF75D7213CDEBBA00B5E7AB /* PreferencesManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PreferencesManager.m; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@@ -45,11 +145,19 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
ABECD9ED13C8DC2B00B77CFD /* ORCDiscount.framework in Frameworks */,
|
||||
8D15AC340486D014006FF6A4 /* Cocoa.framework in Frameworks */,
|
||||
795F6CCD105D741100D1F90A /* WebKit.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
ABECD8C013C8B8CA00B77CFD /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
@@ -76,6 +184,7 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8D15AC370486D014006FF6A4 /* MarkdownLive.app */,
|
||||
ABECD8C213C8B8CA00B77CFD /* ORCDiscount.framework */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
@@ -83,11 +192,17 @@
|
||||
2A37F4AAFDCFA73011CA2CEA /* MarkdownLive */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
ABECD96113C8D1C200B77CFD /* ORCDiscount */,
|
||||
2A37F4ABFDCFA73011CA2CEA /* Classes */,
|
||||
3D6A8BBD15F0D919002C8B62 /* Categories */,
|
||||
795F6C4D105D6EA500D1F90A /* discount */,
|
||||
795F6DB3105D75D300D1F90A /* discount_wrappers */,
|
||||
2A37F4AFFDCFA73011CA2CEA /* Other Sources */,
|
||||
2A37F4B8FDCFA73011CA2CEA /* Resources */,
|
||||
2A37F4C3FDCFA73011CA2CEA /* Frameworks */,
|
||||
19C28FB0FE9D524F11CA2CBB /* Products */,
|
||||
ABECD8C313C8B8CA00B77CFD /* ORCDiscount-Info.plist */,
|
||||
ABCE3DDF13C8DFFF00DF3CD0 /* README.md */,
|
||||
);
|
||||
name = MarkdownLive;
|
||||
sourceTree = "<group>";
|
||||
@@ -95,10 +210,20 @@
|
||||
2A37F4ABFDCFA73011CA2CEA /* Classes */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
11EF12DE142D24BB0086C77F /* MLAppDelegate.h */,
|
||||
11EF12DF142D24BB0086C77F /* MLAppDelegate.m */,
|
||||
3DD1618A1431FD030003F6C7 /* EditPaneLayoutManager.h */,
|
||||
ABF75D6E13CDEBBA00B5E7AB /* EditPaneLayoutManager.m */,
|
||||
3DD161891431FCFC0003F6C7 /* EditPaneTextView.h */,
|
||||
ABF75D6F13CDEBBA00B5E7AB /* EditPaneTextView.m */,
|
||||
3DD161881431FCF40003F6C7 /* EditPaneTypesetter.h */,
|
||||
ABF75D7013CDEBBA00B5E7AB /* EditPaneTypesetter.m */,
|
||||
3DD161871431FCED0003F6C7 /* PreferencesController.h */,
|
||||
ABF75D7113CDEBBA00B5E7AB /* PreferencesController.m */,
|
||||
3DD1618B1431FD0B0003F6C7 /* PreferencesManager.h */,
|
||||
ABF75D7213CDEBBA00B5E7AB /* PreferencesManager.m */,
|
||||
2A37F4AEFDCFA73011CA2CEA /* MyDocument.h */,
|
||||
2A37F4ACFDCFA73011CA2CEA /* MyDocument.m */,
|
||||
79B3D5421060376F00A8D174 /* MDMarkdownParser.h */,
|
||||
79B3D5431060376F00A8D174 /* MDMarkdownParser.m */,
|
||||
);
|
||||
name = Classes;
|
||||
sourceTree = "<group>";
|
||||
@@ -115,6 +240,8 @@
|
||||
2A37F4B8FDCFA73011CA2CEA /* Resources */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
3D6A8BD915F0F33C002C8B62 /* Images */,
|
||||
226936E612E7CDC500171322 /* styles.css */,
|
||||
795F6C86105D70A300D1F90A /* MarkdownLiveApp.icns */,
|
||||
2A37F4B9FDCFA73011CA2CEA /* Credits.rtf */,
|
||||
8D15AC360486D014006FF6A4 /* MarkdownLive-Info.plist */,
|
||||
@@ -134,8 +261,87 @@
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
3D6A8BBD15F0D919002C8B62 /* Categories */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
3D6A8BBA15F0D914002C8B62 /* NSTextView+EditPlainTextWithUndo.h */,
|
||||
3D6A8BBB15F0D914002C8B62 /* NSTextView+EditPlainTextWithUndo.m */,
|
||||
);
|
||||
name = Categories;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
3D6A8BD915F0F33C002C8B62 /* Images */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
3D8BA23115F160FD000555C7 /* Image Template.pdf */,
|
||||
3D8BA23215F160FD000555C7 /* Link Template.pdf */,
|
||||
3D6A8BDC15F0F33C002C8B62 /* Ordered List Template.pdf */,
|
||||
3D6A8BDD15F0F33C002C8B62 /* Quote Template.pdf */,
|
||||
3D6A8BDE15F0F33C002C8B62 /* Unordered List Template.pdf */,
|
||||
);
|
||||
path = Images;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
795F6C4D105D6EA500D1F90A /* discount */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
795F6C4E105D6EC400D1F90A /* mkdio.c */,
|
||||
22ECEED912E7C2E8003B50DC /* markdown.h */,
|
||||
795F6C50105D6ECE00D1F90A /* markdown.c */,
|
||||
795F6C52105D6ED800D1F90A /* generate.c */,
|
||||
795F6C54105D6EE100D1F90A /* resource.c */,
|
||||
795F6C61105D6F6E00D1F90A /* xml.c */,
|
||||
795F6C65105D6F8500D1F90A /* Csio.c */,
|
||||
2269367E12E7C53000171322 /* emmatch.c */,
|
||||
2269369A12E7C6AB00171322 /* html5.c */,
|
||||
2269369F12E7C6BE00171322 /* tags.h */,
|
||||
2269369E12E7C6BE00171322 /* tags.c */,
|
||||
226936C912E7CA2800171322 /* setup.c */,
|
||||
226936B912E7C8B600171322 /* mkdio.h */,
|
||||
22ECEEC612E7C258003B50DC /* config.h */,
|
||||
);
|
||||
path = discount;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
795F6DB3105D75D300D1F90A /* discount_wrappers */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
795F6DB4105D75D300D1F90A /* discountWrapper.h */,
|
||||
795F6DB5105D75D300D1F90A /* discountWrapper.m */,
|
||||
795F6DB6105D75D300D1F90A /* markdownWrapper.c */,
|
||||
795F6DB7105D75D300D1F90A /* markdownWrapper.h */,
|
||||
795F6DB8105D75D300D1F90A /* mkdioWrapper.c */,
|
||||
795F6DB9105D75D300D1F90A /* mkdioWrapper.h */,
|
||||
);
|
||||
path = discount_wrappers;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
ABECD96113C8D1C200B77CFD /* ORCDiscount */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
ABECD95B13C8D14C00B77CFD /* ORCDiscount.h */,
|
||||
ABECD98C13C8D6A900B77CFD /* ORCDiscount.m */,
|
||||
);
|
||||
name = ORCDiscount;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXHeadersBuildPhase section */
|
||||
ABECD8BD13C8B8CA00B77CFD /* Headers */ = {
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
ABECD96B13C8D2D200B77CFD /* markdown.h in Headers */,
|
||||
ABECD8F113C8BA2400B77CFD /* mkdioWrapper.h in Headers */,
|
||||
ABECD8EF13C8BA2100B77CFD /* markdownWrapper.h in Headers */,
|
||||
ABECD8ED13C8BA1A00B77CFD /* discountWrapper.h in Headers */,
|
||||
ABECD95C13C8D14C00B77CFD /* ORCDiscount.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXHeadersBuildPhase section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
8D15AC270486D014006FF6A4 /* MarkdownLive */ = {
|
||||
isa = PBXNativeTarget;
|
||||
@@ -143,11 +349,13 @@
|
||||
buildPhases = (
|
||||
8D15AC2B0486D014006FF6A4 /* Resources */,
|
||||
8D15AC300486D014006FF6A4 /* Sources */,
|
||||
ABECD8EA13C8B9E700B77CFD /* Copy Frameworks */,
|
||||
8D15AC330486D014006FF6A4 /* Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
ABECD8D813C8B98D00B77CFD /* PBXTargetDependency */,
|
||||
);
|
||||
name = MarkdownLive;
|
||||
productInstallPath = "$(HOME)/Applications";
|
||||
@@ -155,19 +363,48 @@
|
||||
productReference = 8D15AC370486D014006FF6A4 /* MarkdownLive.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
ABECD8C113C8B8CA00B77CFD /* ORCDiscount */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = ABECD8C613C8B8CA00B77CFD /* Build configuration list for PBXNativeTarget "ORCDiscount" */;
|
||||
buildPhases = (
|
||||
ABECD8BD13C8B8CA00B77CFD /* Headers */,
|
||||
ABECD8BE13C8B8CA00B77CFD /* Resources */,
|
||||
ABECD8BF13C8B8CA00B77CFD /* Sources */,
|
||||
ABECD8C013C8B8CA00B77CFD /* Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = ORCDiscount;
|
||||
productName = Discount;
|
||||
productReference = ABECD8C213C8B8CA00B77CFD /* ORCDiscount.framework */;
|
||||
productType = "com.apple.product-type.framework";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
2A37F4A9FDCFA73011CA2CEA /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0600;
|
||||
};
|
||||
buildConfigurationList = C05733CB08A9546B00998B17 /* Build configuration list for PBXProject "MarkdownLive" */;
|
||||
compatibilityVersion = "Xcode 3.1";
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 1;
|
||||
knownRegions = (
|
||||
English,
|
||||
Japanese,
|
||||
French,
|
||||
German,
|
||||
);
|
||||
mainGroup = 2A37F4AAFDCFA73011CA2CEA /* MarkdownLive */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
8D15AC270486D014006FF6A4 /* MarkdownLive */,
|
||||
ABECD8C113C8B8CA00B77CFD /* ORCDiscount */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
@@ -182,6 +419,19 @@
|
||||
1DDD582C0DA1D0D100B32029 /* MyDocument.xib in Resources */,
|
||||
1DDD582D0DA1D0D100B32029 /* MainMenu.xib in Resources */,
|
||||
795F6C87105D70A300D1F90A /* MarkdownLiveApp.icns in Resources */,
|
||||
3D6A8BE115F0F33C002C8B62 /* Ordered List Template.pdf in Resources */,
|
||||
3D6A8BE215F0F33C002C8B62 /* Quote Template.pdf in Resources */,
|
||||
3D6A8BE315F0F33C002C8B62 /* Unordered List Template.pdf in Resources */,
|
||||
3D8BA23315F160FD000555C7 /* Image Template.pdf in Resources */,
|
||||
3D8BA23415F160FD000555C7 /* Link Template.pdf in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
ABECD8BE13C8B8CA00B77CFD /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
ABE8DDF913CA38B5005852B5 /* styles.css in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -194,12 +444,47 @@
|
||||
files = (
|
||||
8D15AC310486D014006FF6A4 /* MyDocument.m in Sources */,
|
||||
8D15AC320486D014006FF6A4 /* main.m in Sources */,
|
||||
79B3D5441060376F00A8D174 /* MDMarkdownParser.m in Sources */,
|
||||
ABF75D7313CDEBBB00B5E7AB /* EditPaneLayoutManager.m in Sources */,
|
||||
ABF75D7413CDEBBB00B5E7AB /* EditPaneTextView.m in Sources */,
|
||||
ABF75D7513CDEBBB00B5E7AB /* EditPaneTypesetter.m in Sources */,
|
||||
ABF75D7613CDEBBB00B5E7AB /* PreferencesController.m in Sources */,
|
||||
ABF75D7713CDEBBB00B5E7AB /* PreferencesManager.m in Sources */,
|
||||
11EF12E0142D24BB0086C77F /* MLAppDelegate.m in Sources */,
|
||||
3D6A8BBC15F0D914002C8B62 /* NSTextView+EditPlainTextWithUndo.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
ABECD8BF13C8B8CA00B77CFD /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
ABECD8C713C8B90E00B77CFD /* mkdio.c in Sources */,
|
||||
ABECD8C813C8B92900B77CFD /* markdown.c in Sources */,
|
||||
ABECD8C913C8B92900B77CFD /* generate.c in Sources */,
|
||||
ABECD8CA13C8B92900B77CFD /* resource.c in Sources */,
|
||||
ABECD8CB13C8B92900B77CFD /* xml.c in Sources */,
|
||||
ABECD8CC13C8B92900B77CFD /* Csio.c in Sources */,
|
||||
ABECD8CD13C8B92900B77CFD /* emmatch.c in Sources */,
|
||||
ABECD8CE13C8B92900B77CFD /* html5.c in Sources */,
|
||||
ABECD8CF13C8B92900B77CFD /* tags.c in Sources */,
|
||||
ABECD8D013C8B92900B77CFD /* setup.c in Sources */,
|
||||
ABECD8D113C8B94A00B77CFD /* discountWrapper.m in Sources */,
|
||||
ABECD8D213C8B94A00B77CFD /* markdownWrapper.c in Sources */,
|
||||
ABECD8D313C8B94A00B77CFD /* mkdioWrapper.c in Sources */,
|
||||
ABECD98D13C8D6A900B77CFD /* ORCDiscount.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
ABECD8D813C8B98D00B77CFD /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = ABECD8C113C8B8CA00B77CFD /* ORCDiscount */;
|
||||
targetProxy = ABECD8D713C8B98D00B77CFD /* PBXContainerItemProxy */;
|
||||
};
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
089C165FFE840EACC02AAC07 /* InfoPlist.strings */ = {
|
||||
isa = PBXVariantGroup;
|
||||
@@ -236,14 +521,72 @@
|
||||
/* End PBXVariantGroup section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
ABECD8C413C8B8CA00B77CFD /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
ARCHS = "$(ARCHS_STANDARD_64_BIT)";
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
FRAMEWORK_VERSION = A;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = NO;
|
||||
GCC_PREFIX_HEADER = "";
|
||||
INFOPLIST_FILE = "ORCDiscount-Info.plist";
|
||||
INSTALL_PATH = "@executable_path/../Frameworks";
|
||||
OTHER_LDFLAGS = (
|
||||
"-framework",
|
||||
Foundation,
|
||||
"-framework",
|
||||
AppKit,
|
||||
);
|
||||
PRODUCT_NAME = ORCDiscount;
|
||||
RUN_CLANG_STATIC_ANALYZER = NO;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
ABECD8C513C8B8CA00B77CFD /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
ARCHS = "$(ARCHS_STANDARD_64_BIT)";
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
COPY_PHASE_STRIP = YES;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
FRAMEWORK_VERSION = A;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = NO;
|
||||
GCC_PREFIX_HEADER = "";
|
||||
INFOPLIST_FILE = "ORCDiscount-Info.plist";
|
||||
INSTALL_PATH = "@executable_path/../Frameworks";
|
||||
OTHER_LDFLAGS = (
|
||||
"-framework",
|
||||
Foundation,
|
||||
"-framework",
|
||||
AppKit,
|
||||
);
|
||||
PRODUCT_NAME = ORCDiscount;
|
||||
RUN_CLANG_STATIC_ANALYZER = YES;
|
||||
ZERO_LINK = NO;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
C05733C808A9546B00998B17 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
ARCHS = "$(ARCHS_STANDARD_64_BIT)";
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
FRAMEWORK_SEARCH_PATHS = "\"$(SRCROOT)\"/**";
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_ENABLE_FIX_AND_CONTINUE = YES;
|
||||
GCC_MODEL_TUNING = G5;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = MarkdownLive_Prefix.pch;
|
||||
@@ -257,8 +600,11 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
ARCHS = "$(ARCHS_STANDARD_64_BIT)";
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
GCC_MODEL_TUNING = G5;
|
||||
FRAMEWORK_SEARCH_PATHS = "\"$(SRCROOT)\"/**";
|
||||
GCC_PRECOMPILE_PREFIX_HEADER = YES;
|
||||
GCC_PREFIX_HEADER = MarkdownLive_Prefix.pch;
|
||||
INFOPLIST_FILE = "MarkdownLive-Info.plist";
|
||||
@@ -271,13 +617,24 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_CHECK_SWITCH_STATEMENTS = YES;
|
||||
GCC_WARN_MULTIPLE_DEFINITION_TYPES_FOR_SELECTOR = NO;
|
||||
GCC_WARN_PEDANTIC = NO;
|
||||
GCC_WARN_SHADOW = NO;
|
||||
GCC_WARN_SIGN_COMPARE = NO;
|
||||
GCC_WARN_STRICT_SELECTOR_MATCH = NO;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNKNOWN_PRAGMAS = YES;
|
||||
GCC_WARN_UNUSED_PARAMETER = NO;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.7;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
PREBINDING = NO;
|
||||
SDKROOT = macosx10.6;
|
||||
SDKROOT = macosx;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
@@ -285,17 +642,41 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEPLOYMENT_POSTPROCESSING = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_CHECK_SWITCH_STATEMENTS = YES;
|
||||
GCC_WARN_MULTIPLE_DEFINITION_TYPES_FOR_SELECTOR = NO;
|
||||
GCC_WARN_PEDANTIC = NO;
|
||||
GCC_WARN_SHADOW = NO;
|
||||
GCC_WARN_SIGN_COMPARE = NO;
|
||||
GCC_WARN_STRICT_SELECTOR_MATCH = NO;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNKNOWN_PRAGMAS = YES;
|
||||
GCC_WARN_UNUSED_PARAMETER = NO;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
PREBINDING = NO;
|
||||
SDKROOT = macosx10.6;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.7;
|
||||
SDKROOT = macosx;
|
||||
SEPARATE_STRIP = YES;
|
||||
STRIP_INSTALLED_PRODUCT = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
ABECD8C613C8B8CA00B77CFD /* Build configuration list for PBXNativeTarget "ORCDiscount" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
ABECD8C413C8B8CA00B77CFD /* Debug */,
|
||||
ABECD8C513C8B8CA00B77CFD /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
C05733C708A9546B00998B17 /* Build configuration list for PBXNativeTarget "MarkdownLive" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
|
||||
+25
-2
@@ -1,11 +1,21 @@
|
||||
/*******************************************************************************
|
||||
MyDocument.h - <http://github.com/rentzsch/MarkdownLive>
|
||||
Copyright (c) 2006-2011 Jonathan 'Wolf' Rentzsch: <http://rentzsch.com>
|
||||
Some rights reserved: <http://opensource.org/licenses/mit-license.php>
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <WebKit/WebKit.h>
|
||||
|
||||
@class EditPaneTextView;
|
||||
@class EditPaneLayoutManager;
|
||||
|
||||
@interface MyDocument : NSDocument {
|
||||
IBOutlet NSTextView *markdownSourceTextView;
|
||||
IBOutlet EditPaneTextView *markdownSourceTextView;
|
||||
IBOutlet WebView *htmlPreviewWebView;
|
||||
|
||||
NSMutableAttributedString *markdownSource;
|
||||
NSTextStorage *markdownSource;
|
||||
|
||||
NSTimeInterval whenToUpdatePreview;
|
||||
NSTimer *htmlPreviewTimer;
|
||||
@@ -17,4 +27,17 @@
|
||||
|
||||
- (IBAction)copyGeneratedHTMLAction:(id)sender;
|
||||
|
||||
- (IBAction)boldItalic:(id)sender;
|
||||
- (IBAction)bold:(id)sender;
|
||||
- (IBAction)italic:(id)sender;
|
||||
- (IBAction)header1:(id)sender;
|
||||
- (IBAction)header2:(id)sender;
|
||||
- (IBAction)header3:(id)sender;
|
||||
- (IBAction)blockQuote:(id)sender;
|
||||
- (IBAction)codeSection:(id)sender;
|
||||
- (IBAction)unorderedList:(id)sender;
|
||||
- (IBAction)numberedList:(id)sender;
|
||||
- (IBAction)link:(id)sender;
|
||||
- (IBAction)image:(id)sender;
|
||||
|
||||
@end
|
||||
|
||||
+438
-51
@@ -1,66 +1,148 @@
|
||||
/*******************************************************************************
|
||||
MyDocument.m - <http://github.com/rentzsch/MarkdownLive>
|
||||
Copyright (c) 2006-2011 Jonathan 'Wolf' Rentzsch: <http://rentzsch.com>
|
||||
Some rights reserved: <http://opensource.org/licenses/mit-license.php>
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#import "ORCDiscount.h"
|
||||
#import "MyDocument.h"
|
||||
#import "MDMarkdownParser.h"
|
||||
#import "EditPaneTextView.h"
|
||||
#import "NSTextView+EditPlainTextWithUndo.h"
|
||||
#include "discountWrapper.h"
|
||||
|
||||
NSString * const kNumberedListTemplate = @"%lu. ";
|
||||
|
||||
NSString *kMarkdownDocumentType = @"MarkdownDocumentType";
|
||||
|
||||
@interface NSResponder (scrollToEndOfDocument)
|
||||
- (IBAction)scrollToEndOfDocument:(id)sender; // For some reason this isn't declared anywhere in AppKit.
|
||||
|
||||
@interface MyDocument ()
|
||||
|
||||
- (void)_surroundSelectionWithString:(NSString *)string;
|
||||
- (void)_surroundSelectionWithPrefixString:(NSString *)prefixString
|
||||
suffixString:(NSString *)suffixString
|
||||
selectionOffset:(NSInteger)selectionOffset;
|
||||
- (void)_addStringBeforeSelectedLines:(NSString *)string
|
||||
skippingEmptyLines:(BOOL)skipEmptyLines;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
// class extension
|
||||
@interface MyDocument ()
|
||||
|
||||
- (void)updateContent;
|
||||
- (void)htmlPreviewTimer:(NSTimer*)timer_;
|
||||
|
||||
@end
|
||||
|
||||
@implementation MyDocument
|
||||
|
||||
- (NSString*)markdown2html:(NSString*)markdown_ {
|
||||
if (!markdown_)
|
||||
return @"";
|
||||
|
||||
MDMarkdownParser *parser = [[[MDMarkdownParser alloc] init] autorelease];
|
||||
return [parser cleanWhitespaceOnlyLinesInString:[parser detabString:markdown_]];
|
||||
}
|
||||
|
||||
- (id)init {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
markdownSource = [[NSMutableAttributedString alloc] initWithString:@""
|
||||
attributes:[NSDictionary dictionaryWithObject:[NSFont fontWithName:@"Monaco" size:9.0]
|
||||
forKey:NSFontAttributeName]];
|
||||
self = [super init];
|
||||
if (self) {
|
||||
markdownSource = [[NSTextStorage alloc] init];
|
||||
whenToUpdatePreview = [[NSDate distantFuture] timeIntervalSinceReferenceDate];
|
||||
htmlPreviewTimer = [NSTimer scheduledTimerWithTimeInterval:0.1
|
||||
target:self
|
||||
selector:@selector(htmlPreviewTimer:)
|
||||
userInfo:nil
|
||||
repeats:YES];
|
||||
}
|
||||
return self;
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(textDidChange:)
|
||||
name:kEditPaneTextViewChangedNotification
|
||||
object:markdownSourceTextView];
|
||||
|
||||
// print attributes
|
||||
[[self printInfo] setHorizontalPagination:NSFitPagination];
|
||||
[[self printInfo] setHorizontallyCentered:NO];
|
||||
[[self printInfo] setVerticallyCentered:NO];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
[htmlPreviewTimer invalidate]; htmlPreviewTimer = nil;
|
||||
[markdownSource release]; markdownSource = nil;
|
||||
[super dealloc];
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
}
|
||||
|
||||
- (void)windowWillClose:(NSNotification *)notification {
|
||||
[htmlPreviewTimer invalidate];
|
||||
}
|
||||
|
||||
- (NSString *)windowNibName {
|
||||
return @"MyDocument";
|
||||
return @"MyDocument";
|
||||
}
|
||||
|
||||
- (void)windowControllerDidLoadNib:(NSWindowController*)controller_ {
|
||||
static BOOL engagedAutosave = NO;
|
||||
if (!engagedAutosave) {
|
||||
engagedAutosave = YES;
|
||||
[[NSDocumentController sharedDocumentController] setAutosavingDelay:5.0];
|
||||
}
|
||||
[super windowControllerDidLoadNib:controller_];
|
||||
- (void)windowControllerDidLoadNib:(NSWindowController *)controller_ {
|
||||
static BOOL engagedAutosave = NO;
|
||||
if (!engagedAutosave) {
|
||||
engagedAutosave = YES;
|
||||
[[NSDocumentController sharedDocumentController] setAutosavingDelay:5.0];
|
||||
}
|
||||
|
||||
[[markdownSourceTextView layoutManager] replaceTextStorage:markdownSource];
|
||||
[self updateContent];
|
||||
|
||||
// If you use IB to set an NSTextView's font, the font doesn't stick,
|
||||
// even if you've turned off the text view's richText setting.
|
||||
[markdownSourceTextView updateFont];
|
||||
[markdownSourceTextView updateColors];
|
||||
|
||||
if ([controller_.window respondsToSelector:@selector(toggleFullScreen:)]) {
|
||||
controller_.window.collectionBehavior &= !NSWindowCollectionBehaviorFullScreenAuxiliary;
|
||||
controller_.window.collectionBehavior |= NSWindowCollectionBehaviorFullScreenPrimary;
|
||||
}
|
||||
|
||||
[super windowControllerDidLoadNib:controller_];
|
||||
}
|
||||
|
||||
- (BOOL)writeToURL:(NSURL*)absoluteURL_ ofType:(NSString*)typeName_ error:(NSError**)error_ {
|
||||
BOOL result = NO;
|
||||
- (BOOL)writeToURL:(NSURL*)absoluteURL_
|
||||
ofType:(NSString*)typeName_
|
||||
forSaveOperation:(NSSaveOperationType)saveOperation_
|
||||
originalContentsURL:(NSURL*)absoluteOriginalContentsURL_
|
||||
error:(NSError **)error_
|
||||
{
|
||||
BOOL result = NO;
|
||||
if ([typeName_ isEqualToString:kMarkdownDocumentType]) {
|
||||
[markdownSourceTextView breakUndoCoalescing];
|
||||
result = [[markdownSource string] writeToURL:absoluteURL_
|
||||
atomically:YES
|
||||
encoding:NSUTF8StringEncoding
|
||||
error:error_];
|
||||
|
||||
}
|
||||
|
||||
if (result && saveOperation_ != NSAutosaveOperation) {
|
||||
NSURL *markdownFileURL = [self fileURL];
|
||||
NSURL *htmlFileURL = [[markdownFileURL URLByDeletingPathExtension] URLByAppendingPathExtension:@"html"];
|
||||
if ([[NSFileManager defaultManager] fileExistsAtPath:[htmlFileURL path]]) {
|
||||
NSXMLDocument *doc = [[NSXMLDocument alloc] initWithContentsOfURL:htmlFileURL
|
||||
options:NSXMLNodePreserveAll|NSXMLDocumentTidyXML
|
||||
error:nil];
|
||||
if (doc) {
|
||||
NSArray *nodes = [doc nodesForXPath:@"//*[@id=\"markdownlive\"]" error:nil];
|
||||
if ([nodes count] == 1) {
|
||||
NSXMLElement *node = [nodes objectAtIndex:0];
|
||||
NSXMLDocument *markdownDoc = [[NSXMLDocument alloc] initWithXMLString:[ORCDiscount markdown2HTML:[markdownSource string]]
|
||||
options:NSXMLDocumentTidyHTML
|
||||
error:nil];
|
||||
NSArray *markdownNodes = [markdownDoc nodesForXPath:@"/html/body/*" error:nil];
|
||||
[markdownNodes makeObjectsPerformSelector:@selector(detach)];
|
||||
[node setChildren:markdownNodes];
|
||||
NSString *htmlFileContent = [doc XMLStringWithOptions:NSXMLNodePrettyPrint];
|
||||
if ([htmlFileContent hasPrefix:@"<?xml"]) {
|
||||
NSUInteger index = [htmlFileContent rangeOfString:@"\n"].location;
|
||||
htmlFileContent = [htmlFileContent substringFromIndex:index+1];
|
||||
}
|
||||
[htmlFileContent writeToURL:htmlFileURL
|
||||
atomically:YES
|
||||
encoding:NSUTF8StringEncoding
|
||||
error:nil];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -74,10 +156,7 @@ NSString *kMarkdownDocumentType = @"MarkdownDocumentType";
|
||||
error:&error];
|
||||
if (!error) {
|
||||
NSAssert(markdownSourceString, nil);
|
||||
[markdownSource release];
|
||||
markdownSource = [[NSMutableAttributedString alloc] initWithString:markdownSourceString
|
||||
attributes:[NSDictionary dictionaryWithObject:[NSFont fontWithName:@"Monaco" size:9.0]
|
||||
forKey:NSFontAttributeName]];
|
||||
markdownSource = [[NSTextStorage alloc] initWithString:markdownSourceString];
|
||||
NSAssert(markdownSource, nil);
|
||||
whenToUpdatePreview = [NSDate timeIntervalSinceReferenceDate] + 0.5;
|
||||
result = YES;
|
||||
@@ -88,43 +167,351 @@ NSString *kMarkdownDocumentType = @"MarkdownDocumentType";
|
||||
return result;
|
||||
}
|
||||
|
||||
- (NSView *)printableView {
|
||||
NSRect frame = [[self printInfo] imageablePageBounds];
|
||||
frame.size.height = 0;
|
||||
NSTextView *printView = [[NSTextView alloc] initWithFrame:frame];
|
||||
[printView setVerticallyResizable:YES];
|
||||
[printView setHorizontallyResizable:NO];
|
||||
|
||||
// force black text color
|
||||
NSMutableAttributedString *printStr = [markdownSource mutableCopy];
|
||||
NSDictionary *printAttr = [NSDictionary dictionaryWithObject:[NSColor blackColor]
|
||||
forKey:NSForegroundColorAttributeName];
|
||||
[printStr setAttributes:printAttr
|
||||
range:NSMakeRange(0, [printStr length])];
|
||||
|
||||
[[printView textStorage] beginEditing];
|
||||
[[printView textStorage] appendAttributedString:printStr];
|
||||
[[printView textStorage] endEditing];
|
||||
|
||||
[printView sizeToFit];
|
||||
|
||||
return printView;
|
||||
}
|
||||
|
||||
- (NSPrintOperation *)printOperationWithSettings:(NSDictionary *)printSettings error:(NSError **)outError {
|
||||
|
||||
#pragma unused(printSettings)
|
||||
#pragma unused(outError)
|
||||
|
||||
return [NSPrintOperation printOperationWithView:[self printableView]
|
||||
printInfo:[self printInfo]];
|
||||
}
|
||||
|
||||
- (void)textDidChange:(NSNotification*)notification_ {
|
||||
|
||||
#pragma unused(notification_)
|
||||
|
||||
whenToUpdatePreview = [NSDate timeIntervalSinceReferenceDate] + 0.5;
|
||||
}
|
||||
|
||||
- (void)updateContent {
|
||||
NSView *docView = [[[htmlPreviewWebView mainFrame] frameView] documentView];
|
||||
NSView *parent = [docView superview];
|
||||
if (parent) {
|
||||
NSAssert([parent isKindOfClass:[NSClipView class]], @"");
|
||||
savedOrigin = [parent bounds].origin;
|
||||
// This line from Darin from http://lists.apple.com/archives/webkitsdk-dev/2003/Dec/msg00004.html :
|
||||
savedAtBottom = [docView isFlipped]
|
||||
? NSMaxY([docView bounds]) <= NSMaxY([docView visibleRect])
|
||||
: [docView bounds].origin.y >= [docView visibleRect].origin.y;
|
||||
hasSavedOrigin = YES;
|
||||
}
|
||||
|
||||
NSURL *css = [ORCDiscount cssURL];
|
||||
NSString *html = [ORCDiscount HTMLPage:[ORCDiscount markdown2HTML:[markdownSource string]] withCSSFromURL:css];
|
||||
[[htmlPreviewWebView mainFrame] loadHTMLString:html baseURL:[self fileURL]];
|
||||
}
|
||||
|
||||
- (void)updateContentOnUndo {
|
||||
NSUndoManager *undoManager = [self undoManager];
|
||||
|
||||
[undoManager registerUndoWithTarget:self
|
||||
selector:@selector(updateContentOnUndo)
|
||||
object:nil];
|
||||
|
||||
if ([undoManager isUndoing]) {
|
||||
[self updateContent];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)updateContentIncludingOnRedo {
|
||||
NSUndoManager *undoManager = [self undoManager];
|
||||
|
||||
[undoManager registerUndoWithTarget:self
|
||||
selector:@selector(updateContentIncludingOnRedo)
|
||||
object:nil];
|
||||
|
||||
if ([undoManager isUndoing] == NO) {
|
||||
[self updateContent];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)htmlPreviewTimer:(NSTimer*)timer_ {
|
||||
|
||||
#pragma unused(timer_)
|
||||
|
||||
if ([NSDate timeIntervalSinceReferenceDate] >= whenToUpdatePreview) {
|
||||
whenToUpdatePreview = [[NSDate distantFuture] timeIntervalSinceReferenceDate];
|
||||
|
||||
NSView *docView = [[[htmlPreviewWebView mainFrame] frameView] documentView];
|
||||
NSView *parent = [docView superview];
|
||||
if (parent) {
|
||||
NSAssert([parent isKindOfClass:[NSClipView class]], nil);
|
||||
savedOrigin = [parent bounds].origin;
|
||||
// This line from Darin from http://lists.apple.com/archives/webkitsdk-dev/2003/Dec/msg00004.html :
|
||||
savedAtBottom = [docView isFlipped]
|
||||
? NSMaxY([docView bounds]) <= NSMaxY([docView visibleRect])
|
||||
: [docView bounds].origin.y >= [docView visibleRect].origin.y;
|
||||
hasSavedOrigin = YES;
|
||||
}
|
||||
[[htmlPreviewWebView mainFrame] loadHTMLString:[self markdown2html:[markdownSource string]]
|
||||
baseURL:[self fileName] ? [NSURL fileURLWithPath:[self fileName]] : nil];
|
||||
[self updateContent];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)webView:(WebView*)sender_ didFinishLoadForFrame:(WebFrame*)frame_ {
|
||||
|
||||
#pragma unused(sender_)
|
||||
|
||||
if ([htmlPreviewWebView mainFrame] == frame_ && hasSavedOrigin) {
|
||||
hasSavedOrigin = NO;
|
||||
if (savedAtBottom)
|
||||
[[frame_ frameView] scrollToEndOfDocument:nil];
|
||||
[[[frame_ frameView] documentView] scrollPoint:NSMakePoint(savedOrigin.x, CGFLOAT_MAX)];
|
||||
else
|
||||
[[[frame_ frameView] documentView] scrollPoint:savedOrigin];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)webView:(WebView *)webView decidePolicyForNavigationAction:(NSDictionary *)actionInformation
|
||||
request:(NSURLRequest *)request
|
||||
frame:(WebFrame *)frame decisionListener:(id < WebPolicyDecisionListener >)listener {
|
||||
|
||||
#pragma unused(webView)
|
||||
#pragma unused(request)
|
||||
#pragma unused(frame)
|
||||
|
||||
WebNavigationType actionKey = [[actionInformation objectForKey:WebActionNavigationTypeKey] intValue];
|
||||
if (actionKey == WebNavigationTypeOther) {
|
||||
[listener use];
|
||||
} else {
|
||||
NSURL *url = [actionInformation objectForKey:WebActionOriginalURLKey];
|
||||
|
||||
NSURL *stdUrl = [url URLByStandardizingPath];
|
||||
NSURL *docUrl = [[self fileURL] URLByStandardizingPath];
|
||||
if ([[url scheme] isEqualToString:@"applewebdata"] ||
|
||||
([stdUrl isFileURL] && [stdUrl isEqualTo:docUrl])) {
|
||||
[listener use];
|
||||
} else {
|
||||
[[NSWorkspace sharedWorkspace] openURL:url];
|
||||
[listener ignore];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (IBAction)copyGeneratedHTMLAction:(id)sender {
|
||||
|
||||
#pragma unused(sender)
|
||||
|
||||
[[NSPasteboard generalPasteboard] declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:nil];
|
||||
[[NSPasteboard generalPasteboard] setString:[self markdown2html:[markdownSource string]] forType:NSStringPboardType];
|
||||
[[NSPasteboard generalPasteboard] setString:[ORCDiscount markdown2HTML:[markdownSource string]] forType:NSStringPboardType];
|
||||
}
|
||||
|
||||
- (void)_surroundSelectionWithString:(NSString *)string {
|
||||
[self _surroundSelectionWithPrefixString:string
|
||||
suffixString:string
|
||||
selectionOffset:0];
|
||||
}
|
||||
|
||||
- (void)_surroundSelectionWithPrefixString:(NSString *)prefixString
|
||||
suffixString:(NSString *)suffixString
|
||||
selectionOffset:(NSInteger)selectionOffset {
|
||||
[self updateContentOnUndo];
|
||||
|
||||
NSMutableArray *newSelection = [[NSMutableArray alloc] init];
|
||||
|
||||
NSUInteger prefixStringLength = prefixString.length;
|
||||
NSUInteger suffixStringLength = suffixString.length;
|
||||
NSUInteger insertedStringLength = prefixStringLength + suffixStringLength;
|
||||
|
||||
NSUInteger insertedCharacters = 0;
|
||||
NSArray *selectedRanges = [markdownSourceTextView selectedRanges];
|
||||
BOOL multipleSelections = (selectedRanges.count != 1);
|
||||
|
||||
for (NSValue *rangeInfo in selectedRanges) {
|
||||
NSRange range = [rangeInfo rangeValue];
|
||||
range.location += insertedCharacters;
|
||||
|
||||
[markdownSourceTextView insertText:suffixString atIndex:NSMaxRange(range)];
|
||||
[markdownSourceTextView insertText:prefixString atIndex:range.location];
|
||||
|
||||
insertedCharacters += insertedStringLength;
|
||||
|
||||
if (multipleSelections || selectionOffset == 0) {
|
||||
range.location += prefixStringLength;
|
||||
} else {
|
||||
// We use the selectionOffset only if there is a single selection.
|
||||
if (selectionOffset < 0) {
|
||||
// Negative offsets are relative to the end of the resulting range.
|
||||
range.location += range.length + insertedStringLength + selectionOffset;
|
||||
} else {
|
||||
// Positive offsets are relative to the start of the resulting range.
|
||||
range.location += selectionOffset;
|
||||
}
|
||||
range.length = 0;
|
||||
}
|
||||
[newSelection addObject:[NSValue valueWithRange:range]];
|
||||
}
|
||||
|
||||
[markdownSourceTextView setSelectedRangesWithUndo:newSelection];
|
||||
|
||||
[self updateContentIncludingOnRedo];
|
||||
}
|
||||
|
||||
- (void)_addStringBeforeSelectedLines:(NSString *)string
|
||||
skippingEmptyLines:(BOOL)skipEmptyLines {
|
||||
[self updateContentOnUndo];
|
||||
|
||||
NSMutableString *mutableString = markdownSourceTextView.textStorage.mutableString;
|
||||
NSMutableArray *newSelection = [[NSMutableArray alloc] init];
|
||||
NSUInteger stringLength = string.length;
|
||||
|
||||
NSUInteger insertedCharacters = 0;
|
||||
|
||||
for (NSValue *rangeInfo in [markdownSourceTextView selectedRanges]) {
|
||||
NSRange range = [rangeInfo rangeValue];
|
||||
range.location += insertedCharacters;
|
||||
|
||||
NSUInteger rangeEnd = NSMaxRange(range);
|
||||
NSUInteger currentIndex = range.location;
|
||||
|
||||
NSUInteger insertionCounter = 0;
|
||||
|
||||
while (currentIndex < (rangeEnd + insertedCharacters)
|
||||
&& currentIndex < mutableString.length) {
|
||||
NSUInteger startIndex, lineEndIndex, contentsEndIndex;
|
||||
|
||||
[mutableString getLineStart:&startIndex
|
||||
end:&lineEndIndex
|
||||
contentsEnd:&contentsEndIndex
|
||||
forRange:NSMakeRange(currentIndex, 0)];
|
||||
|
||||
BOOL lineHasContent = (startIndex < contentsEndIndex);
|
||||
|
||||
if ((skipEmptyLines == NO) || lineHasContent) {
|
||||
// Prefix line with string.
|
||||
if (string == kNumberedListTemplate) {
|
||||
NSString *currentString = [NSString stringWithFormat:string, (unsigned long)(insertionCounter + 1)];
|
||||
[markdownSourceTextView insertText:currentString atIndex:startIndex];
|
||||
|
||||
stringLength = currentString.length;
|
||||
}
|
||||
else {
|
||||
[markdownSourceTextView insertText:string atIndex:startIndex];
|
||||
}
|
||||
|
||||
insertedCharacters += stringLength;
|
||||
|
||||
currentIndex = stringLength + lineEndIndex;
|
||||
|
||||
insertionCounter++;
|
||||
}
|
||||
else {
|
||||
// startIndex == contentsEndIndex => the line is empty. Do nothing and go to next line.
|
||||
currentIndex = lineEndIndex;
|
||||
}
|
||||
}
|
||||
|
||||
if (insertionCounter == 1) {
|
||||
// If this was within a single line, we keep the previously selected characters selected.
|
||||
range.location += stringLength;
|
||||
range.length += insertedCharacters - stringLength;
|
||||
}
|
||||
else {
|
||||
// If this selection went across multiple lines, we extend the selection to all the lines that were touched.
|
||||
range.length += insertedCharacters;
|
||||
}
|
||||
|
||||
[newSelection addObject:[NSValue valueWithRange:range]];
|
||||
}
|
||||
|
||||
[markdownSourceTextView setSelectedRangesWithUndo:newSelection];
|
||||
|
||||
[self updateContentIncludingOnRedo];
|
||||
}
|
||||
|
||||
- (IBAction)boldItalic:(NSSegmentedControl *)sender {
|
||||
//NSLog(@"sender: %ld", sender.selectedSegment);
|
||||
|
||||
switch (sender.selectedSegment) {
|
||||
case 0: { //bold
|
||||
[self bold:sender];
|
||||
|
||||
break;
|
||||
}
|
||||
case 1: { //italic
|
||||
[self italic:sender];
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)_undoBold:(NSString *)string
|
||||
{
|
||||
NSLog(@"string: %@", string);
|
||||
}
|
||||
|
||||
- (IBAction)bold:(id)sender
|
||||
{
|
||||
[self _surroundSelectionWithString:@"**"];
|
||||
}
|
||||
|
||||
- (IBAction)italic:(id)sender
|
||||
{
|
||||
[self _surroundSelectionWithString:@"*"];
|
||||
}
|
||||
|
||||
- (IBAction)header1:(id)sender
|
||||
{
|
||||
[self _addStringBeforeSelectedLines:@"# "
|
||||
skippingEmptyLines:YES];
|
||||
}
|
||||
|
||||
- (IBAction)header2:(id)sender
|
||||
{
|
||||
[self _addStringBeforeSelectedLines:@"## "
|
||||
skippingEmptyLines:YES];
|
||||
}
|
||||
|
||||
- (IBAction)header3:(id)sender
|
||||
{
|
||||
[self _addStringBeforeSelectedLines:@"### "
|
||||
skippingEmptyLines:YES];
|
||||
}
|
||||
|
||||
- (IBAction)blockQuote:(id)sender
|
||||
{
|
||||
[self _addStringBeforeSelectedLines:@"> "
|
||||
skippingEmptyLines:NO];
|
||||
}
|
||||
|
||||
- (IBAction)codeSection:(id)sender
|
||||
{
|
||||
[self _addStringBeforeSelectedLines:@" "
|
||||
skippingEmptyLines:NO];
|
||||
}
|
||||
|
||||
- (IBAction)unorderedList:(id)sender
|
||||
{
|
||||
[self _addStringBeforeSelectedLines:@"* "
|
||||
skippingEmptyLines:YES];
|
||||
}
|
||||
|
||||
- (IBAction)numberedList:(id)sender
|
||||
{
|
||||
[self _addStringBeforeSelectedLines:kNumberedListTemplate
|
||||
skippingEmptyLines:YES];
|
||||
}
|
||||
|
||||
- (IBAction)link:(id)sender
|
||||
{
|
||||
[self _surroundSelectionWithPrefixString:@"[" suffixString:@"]()"
|
||||
selectionOffset:-1];
|
||||
}
|
||||
|
||||
- (IBAction)image:(id)sender
|
||||
{
|
||||
[self _surroundSelectionWithPrefixString:@"![" suffixString:@"]()"
|
||||
selectionOffset:-1];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
//
|
||||
// NSTextView+EditPlainTextWithUndo.h
|
||||
// MarkdownLive
|
||||
//
|
||||
// Created by Jan Weiß on 31.08.12. Some rights reserved: <http://opensource.org/licenses/mit-license.php>
|
||||
//
|
||||
|
||||
// Based on DrewThaler’s post at http://www.cocoadev.com/index.pl?UndoSupportForNSTextStorage
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
|
||||
@interface NSTextView (EditPlainTextWithUndo)
|
||||
|
||||
- (void)setSelectedRangeWithUndo:(NSRange)range;
|
||||
- (void)setSelectedRangesWithUndo:(NSArray *)ranges;
|
||||
|
||||
- (BOOL)setText:(NSString *)string;
|
||||
- (BOOL)replaceCharactersInRange:(NSRange)range withText:(NSString *)string;
|
||||
- (BOOL)insertText:(NSString *)string atIndex:(NSUInteger)index;
|
||||
- (BOOL)insertText:(NSString *)string atIndex:(NSUInteger)index checkIndex:(BOOL)checkIndex;
|
||||
- (BOOL)insertText:(NSString *)string;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,102 @@
|
||||
//
|
||||
// NSTextView+EditPlainTextWithUndo.m
|
||||
// MarkdownLive
|
||||
//
|
||||
// Created by Jan Weiß on 31.08.12. Some rights reserved: <http://opensource.org/licenses/mit-license.php>
|
||||
//
|
||||
|
||||
// Based on DrewThaler’s post at http://www.cocoadev.com/index.pl?UndoSupportForNSTextStorage
|
||||
|
||||
#import "NSTextView+EditPlainTextWithUndo.h"
|
||||
|
||||
|
||||
@implementation NSTextView (EditPlainTextWithUndo)
|
||||
|
||||
- (void)setSelectedRangeWithUndo:(NSRange)range;
|
||||
{
|
||||
[self setSelectedRange:range];
|
||||
[[self.undoManager prepareWithInvocationTarget:self] setSelectedRangeWithUndo:range];
|
||||
}
|
||||
|
||||
- (void)setSelectedRangesWithUndo:(NSArray *)ranges;
|
||||
{
|
||||
[self setSelectedRanges:ranges];
|
||||
[[self.undoManager prepareWithInvocationTarget:self] setSelectedRangesWithUndo:ranges];
|
||||
}
|
||||
|
||||
- (BOOL)setText:(NSString *)string;
|
||||
{
|
||||
[[self.undoManager prepareWithInvocationTarget:self] setSelectedRangeWithUndo:self.selectedRange];
|
||||
|
||||
NSTextStorage *textStorage = [self textStorage];
|
||||
|
||||
if ([self shouldChangeTextInRange:NSMakeRange(0, [textStorage length])
|
||||
replacementString:string]) {
|
||||
|
||||
[textStorage.mutableString setString:string];
|
||||
|
||||
[self didChangeText];
|
||||
|
||||
[self setSelectedRangeWithUndo:NSMakeRange(0, 0)];
|
||||
|
||||
return YES;
|
||||
}
|
||||
else {
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)replaceCharactersInRange:(NSRange)range withText:(NSString *)string;
|
||||
{
|
||||
NSString *selectedText = [[self string] substringWithRange:range];
|
||||
NSString *stringForDelegate = string;
|
||||
|
||||
// If only attributes are changing, pass nil.
|
||||
if ([string isEqualToString:selectedText]) {
|
||||
stringForDelegate = nil;
|
||||
}
|
||||
|
||||
[[self.undoManager prepareWithInvocationTarget:self] setSelectedRangeWithUndo:self.selectedRange];
|
||||
|
||||
// Call delegate methods to force undo recording
|
||||
if ([self shouldChangeTextInRange:range
|
||||
replacementString:stringForDelegate]) {
|
||||
|
||||
[self.textStorage.mutableString replaceCharactersInRange:range
|
||||
withString:string];
|
||||
|
||||
[self didChangeText];
|
||||
|
||||
[self setSelectedRangeWithUndo:NSMakeRange(range.location + [string length], 0)];
|
||||
|
||||
return YES;
|
||||
}
|
||||
else {
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)insertText:(NSString *)string atIndex:(NSUInteger)index;
|
||||
{
|
||||
NSRange range = NSMakeRange(index, 0);
|
||||
return [self replaceCharactersInRange:range withText:string];
|
||||
}
|
||||
|
||||
- (BOOL)insertText:(NSString *)attributedString atIndex:(NSUInteger)index checkIndex:(BOOL)checkIndex;
|
||||
{
|
||||
NSUInteger textLength = [self.textStorage length];
|
||||
|
||||
if (checkIndex && (index == NSNotFound || !(index <= textLength))) {
|
||||
index = textLength; // AFTER the last character in textStorage
|
||||
}
|
||||
|
||||
return [self insertText:attributedString atIndex:index];
|
||||
}
|
||||
|
||||
- (BOOL)insertText:(NSString *)attributedString;
|
||||
{
|
||||
NSRange range = [self selectedRange];
|
||||
return [self replaceCharactersInRange:range withText:attributedString];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.yourcompany.${PRODUCT_NAME:rfc1034identifier}</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* ORCDiscount.h
|
||||
* MarkdownLive
|
||||
*
|
||||
* Created by Jonathan on 09/07/2011.
|
||||
* Copyright 2011 mugginsoft.com.
|
||||
* Some rights reserved: <http://opensource.org/licenses/mit-license.php>
|
||||
*
|
||||
*/
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@interface ORCDiscount : NSObject {
|
||||
}
|
||||
|
||||
+ (NSString *)markdown2HTML:(NSString *)markdown;
|
||||
+ (NSString *)HTMLPage:(NSString *)markdownHTML withCSSHTML:(NSString *)cssHTML;
|
||||
+ (NSString *)HTMLPage:(NSString *)markdownHTML withCSSFromURL:(NSURL *)cssURL;
|
||||
+ (NSURL *)cssURL;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,49 @@
|
||||
//
|
||||
// ORCDiscount.m
|
||||
// MarkdownLive
|
||||
//
|
||||
// Created by Jonathan on 09/07/2011.
|
||||
// Copyright 2011 mugginsoft.com.
|
||||
// Some rights reserved: <http://opensource.org/licenses/mit-license.php>
|
||||
//
|
||||
|
||||
|
||||
#import "ORCDiscount.h"
|
||||
#import "discountWrapper.h"
|
||||
|
||||
@implementation ORCDiscount
|
||||
|
||||
+ (NSString *)markdown2HTML:(NSString *)markdown_ {
|
||||
if (!markdown_) {
|
||||
return @"";
|
||||
}
|
||||
|
||||
return discountToHTML(markdown_);
|
||||
}
|
||||
|
||||
+ (NSString *)HTMLPage:(NSString *)markdownHTML withCSSHTML:(NSString *)cssHTML
|
||||
{
|
||||
return [NSString stringWithFormat:
|
||||
@"<!DOCTYPE html>\n<html>\n<head>\n<title>%@</title>\n%@</head>\n<body>%@</body>\n</html>",
|
||||
@"Markdown Preview",
|
||||
cssHTML,
|
||||
markdownHTML
|
||||
];
|
||||
}
|
||||
|
||||
+ (NSString *)HTMLPage:(NSString *)markdownHTML withCSSFromURL:(NSURL *)cssURL
|
||||
{
|
||||
NSString *cssHTML = [NSString stringWithFormat:
|
||||
@"<link rel=\"stylesheet\" type=\"text/css\" href=\"%@\">\n",
|
||||
[cssURL absoluteString]
|
||||
];
|
||||
return [self HTMLPage:markdownHTML withCSSHTML:cssHTML];
|
||||
}
|
||||
|
||||
+ (NSURL *)cssURL
|
||||
{
|
||||
return [[NSBundle bundleForClass:self] URLForResource:@"styles" withExtension:@"css"];
|
||||
}
|
||||
@end
|
||||
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
//
|
||||
// PreferencesController.h
|
||||
// MarkdownLive
|
||||
//
|
||||
// Created by Akihiro Noguchi on 7/05/11.
|
||||
// Copyright 2011 Aki. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
extern NSString * const kEditPaneFontNameChangedNotification;
|
||||
|
||||
@interface PreferencesController : NSObject {
|
||||
IBOutlet NSWindow *prefWindow;
|
||||
IBOutlet NSTextField *fontPreviewField;
|
||||
}
|
||||
|
||||
- (IBAction)resetEditPanePreferences:(id)sender;
|
||||
- (IBAction)showFonts:(id)sender;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,77 @@
|
||||
//
|
||||
// PreferencesController.m
|
||||
// MarkdownLive
|
||||
//
|
||||
// Created by Akihiro Noguchi on 7/05/11.
|
||||
// Copyright 2011 Aki. All rights reserved.
|
||||
//
|
||||
|
||||
#import "PreferencesController.h"
|
||||
#import "PreferencesManager.h"
|
||||
|
||||
NSString * const kEditPaneFontNameChangedNotification = @"EditPaneFontNameChangedNotification";
|
||||
|
||||
NSString * const kFontDisplayFormat = @"%@ %g pt.";
|
||||
|
||||
@interface PreferencesController (Private)
|
||||
|
||||
- (void)updateFontDisplay;
|
||||
|
||||
@end
|
||||
|
||||
@implementation PreferencesController
|
||||
|
||||
- (void)awakeFromNib {
|
||||
[self updateFontDisplay];
|
||||
}
|
||||
|
||||
- (IBAction)showFonts:(id)sender {
|
||||
NSFontManager *fontMan = [NSFontManager sharedFontManager];
|
||||
NSFont *currentFont = [PreferencesManager editPaneFont];
|
||||
[prefWindow makeFirstResponder:prefWindow];
|
||||
[fontMan setSelectedFont:currentFont isMultiple:NO];
|
||||
[fontMan orderFrontFontPanel:sender];
|
||||
}
|
||||
|
||||
- (void)updateFontDisplay {
|
||||
NSString *fontName = [PreferencesManager editPaneFontName];
|
||||
float fontSize = [PreferencesManager editPaneFontSize];
|
||||
[fontPreviewField setStringValue:[NSString stringWithFormat:kFontDisplayFormat, fontName, fontSize]];
|
||||
}
|
||||
|
||||
- (IBAction)resetEditPanePreferences:(id)sender {
|
||||
|
||||
#pragma unused(sender)
|
||||
|
||||
[PreferencesManager resetEditPanePreferences];
|
||||
[self updateFontDisplay];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kEditPaneFontNameChangedNotification
|
||||
object:nil];
|
||||
}
|
||||
|
||||
- (void)changeFont:(id)sender {
|
||||
NSFont *newFont = [sender convertFont:[NSFont systemFontOfSize:0]];
|
||||
NSString *fontName = [newFont fontName];
|
||||
float fontSize = [newFont pointSize];
|
||||
|
||||
if (newFont && fontName) {
|
||||
[PreferencesManager setEditPaneFontName:fontName];
|
||||
[PreferencesManager setEditPaneFontSize:fontSize];
|
||||
[fontPreviewField setStringValue:[NSString stringWithFormat:kFontDisplayFormat, fontName, fontSize]];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kEditPaneFontNameChangedNotification
|
||||
object:nil];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSUInteger)validModesForFontPanel:(NSFontPanel *)fontPanel {
|
||||
|
||||
#pragma unused(fontPanel)
|
||||
|
||||
return (NSFontPanelFaceModeMask |
|
||||
NSFontPanelSizeModeMask |
|
||||
NSFontPanelCollectionModeMask);
|
||||
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,37 @@
|
||||
//
|
||||
// PreferencesManager.h
|
||||
// MarkdownLive
|
||||
//
|
||||
// Created by Akihiro Noguchi on 7/05/11.
|
||||
// Copyright 2011 Aki. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
extern NSString * const kEditPaneFontName;
|
||||
extern NSString * const kEditPaneFontSize;
|
||||
extern NSString * const kEditPaneForegroundColor;
|
||||
extern NSString * const kEditPaneBackgroundColor;
|
||||
extern NSString * const kEditPaneSelectionColor;
|
||||
extern NSString * const kEditPaneCaretColor;
|
||||
|
||||
@interface PreferencesManager : NSObject {
|
||||
|
||||
}
|
||||
|
||||
+ (void)resetEditPanePreferences;
|
||||
+ (NSString *)editPaneFontName;
|
||||
+ (void)setEditPaneFontName:(NSString *)value;
|
||||
+ (float)editPaneFontSize;
|
||||
+ (void)setEditPaneFontSize:(float)value;
|
||||
+ (NSFont *)editPaneFont;
|
||||
+ (NSColor *)editPaneForegroundColor;
|
||||
+ (void)setEditPaneForegroundColor:(NSColor *)value;
|
||||
+ (NSColor *)editPaneBackgroundColor;
|
||||
+ (void)setEditPaneBackgroundColor:(NSColor *)value;
|
||||
+ (NSColor *)editPaneSelectionColor;
|
||||
+ (void)setEditPaneSelectionColor:(NSColor *)value;
|
||||
+ (NSColor *)editPaneCaretColor;
|
||||
+ (void)setEditPaneCaretColor:(NSColor *)value;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,129 @@
|
||||
//
|
||||
// PreferencesManager.m
|
||||
// MarkdownLive
|
||||
//
|
||||
// Created by Akihiro Noguchi on 7/05/11.
|
||||
// Copyright 2011 Aki. All rights reserved.
|
||||
//
|
||||
|
||||
#import "PreferencesManager.h"
|
||||
|
||||
NSString * const kEditPaneFontName = @"EditPaneFontName";
|
||||
NSString * const kEditPaneFontSize = @"EditPaneFontSize";
|
||||
NSString * const kEditPaneForegroundColor = @"EditPaneForegroundColor";
|
||||
NSString * const kEditPaneBackgroundColor = @"EditPaneBackgroundColor";
|
||||
NSString * const kEditPaneSelectionColor = @"EditPaneSelectionColor";
|
||||
NSString * const kEditPaneCaretColor = @"EditPaneCaretColor";
|
||||
|
||||
@interface PreferencesManager (Private)
|
||||
|
||||
+ (NSColor *)colorForKey:(NSString *)key;
|
||||
+ (void)setColor:(NSColor *)col forKey:(NSString *)key;
|
||||
+ (NSDictionary *)editPaneDefaults;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation PreferencesManager
|
||||
|
||||
+ (void)initialize {
|
||||
NSMutableDictionary *defVals = [NSMutableDictionary dictionary];
|
||||
[defVals addEntriesFromDictionary:[PreferencesManager editPaneDefaults]];
|
||||
[[NSUserDefaults standardUserDefaults] registerDefaults:defVals];
|
||||
}
|
||||
|
||||
+ (NSDictionary *)editPaneDefaults {
|
||||
return [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
@"Monaco", kEditPaneFontName,
|
||||
[NSNumber numberWithFloat:9.0f], kEditPaneFontSize,
|
||||
[NSArchiver archivedDataWithRootObject:[NSColor blackColor]], kEditPaneForegroundColor,
|
||||
[NSArchiver archivedDataWithRootObject:[NSColor whiteColor]], kEditPaneBackgroundColor,
|
||||
[NSArchiver archivedDataWithRootObject:[NSColor selectedTextBackgroundColor]], kEditPaneSelectionColor,
|
||||
[NSArchiver archivedDataWithRootObject:[NSColor blackColor]], kEditPaneCaretColor,
|
||||
nil];
|
||||
}
|
||||
|
||||
+ (void)resetEditPanePreferences {
|
||||
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
|
||||
NSDictionary *defs = [PreferencesManager editPaneDefaults];
|
||||
for (NSString *key in defs) {
|
||||
[prefs setObject:[defs objectForKey:key] forKey:key];
|
||||
}
|
||||
}
|
||||
|
||||
+ (NSString *)editPaneFontName {
|
||||
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
|
||||
return [prefs stringForKey:kEditPaneFontName];
|
||||
}
|
||||
|
||||
+ (void)setEditPaneFontName:(NSString *)value {
|
||||
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
|
||||
[prefs setObject:value forKey:kEditPaneFontName];
|
||||
}
|
||||
|
||||
+ (float)editPaneFontSize {
|
||||
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
|
||||
return [prefs floatForKey:kEditPaneFontSize];
|
||||
}
|
||||
|
||||
+ (void)setEditPaneFontSize:(float)value {
|
||||
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
|
||||
[prefs setFloat:value forKey:kEditPaneFontSize];
|
||||
}
|
||||
|
||||
+ (NSFont *)editPaneFont {
|
||||
return [NSFont fontWithName:[PreferencesManager editPaneFontName]
|
||||
size:[PreferencesManager editPaneFontSize]];
|
||||
}
|
||||
|
||||
+ (NSColor *)colorForKey:(NSString *)key {
|
||||
if (key) {
|
||||
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
|
||||
NSData *data = [prefs dataForKey:key];
|
||||
if (data) {
|
||||
return (NSColor *)[NSUnarchiver unarchiveObjectWithData:data];
|
||||
}
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
+ (void)setColor:(NSColor *)col forKey:(NSString *)key {
|
||||
if (col && key) {
|
||||
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
|
||||
[prefs setValue:[NSArchiver archivedDataWithRootObject:col] forKey:key];
|
||||
}
|
||||
}
|
||||
|
||||
+ (NSColor *)editPaneForegroundColor {
|
||||
return [PreferencesManager colorForKey:kEditPaneForegroundColor];
|
||||
}
|
||||
|
||||
+ (void)setEditPaneForegroundColor:(NSColor *)value {
|
||||
[PreferencesManager setColor:value forKey:kEditPaneForegroundColor];
|
||||
}
|
||||
|
||||
+ (NSColor *)editPaneBackgroundColor {
|
||||
return [PreferencesManager colorForKey:kEditPaneBackgroundColor];
|
||||
}
|
||||
|
||||
+ (void)setEditPaneBackgroundColor:(NSColor *)value {
|
||||
[PreferencesManager setColor:value forKey:kEditPaneBackgroundColor];
|
||||
}
|
||||
|
||||
+ (NSColor *)editPaneSelectionColor {
|
||||
return [PreferencesManager colorForKey:kEditPaneSelectionColor];
|
||||
}
|
||||
|
||||
+ (void)setEditPaneSelectionColor:(NSColor *)value {
|
||||
[PreferencesManager setColor:value forKey:kEditPaneSelectionColor];
|
||||
}
|
||||
|
||||
+ (NSColor *)editPaneCaretColor {
|
||||
return [PreferencesManager colorForKey:kEditPaneCaretColor];
|
||||
}
|
||||
|
||||
+ (void)setEditPaneCaretColor:(NSColor *)value {
|
||||
[PreferencesManager setColor:value forKey:kEditPaneCaretColor];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,8 @@
|
||||
## MarkdownLive
|
||||
|
||||
A Cocoa markdown preview editor using [Discount][discount].
|
||||
|
||||
Implements the ORCDiscount framework.
|
||||
|
||||
|
||||
[discount]: https://github.com/Orc/discount
|
||||
@@ -0,0 +1,19 @@
|
||||
# [Discount][] instructions #
|
||||
|
||||
This folder holds the files generated by discount's `configure.sh` script that are used by MarkdownLive.
|
||||
|
||||
## Upgrading discount ##
|
||||
|
||||
Discount is included as a [fake submodule][]. To upgrade or test other versions of discount, delete the files in the `discount` directory and clone a new local repository into it:
|
||||
|
||||
rm -rf discount/
|
||||
git clone git://github.com/Orc/discount.git discount
|
||||
|
||||
## Config files ##
|
||||
|
||||
When discount is changed, regenerate the config files. The included `update.sh` script should do this automatically.
|
||||
|
||||
If you want to update the files by hand, remove the "configuration for markdown, generated" comments at the head of `config.h` to avoid adding needless patches to the git history.
|
||||
|
||||
[discount]:https://github.com/Orc/discount
|
||||
[fake submodule]:http://debuggable.com/posts/git-fake-submodules:4b563ee4-f3cc-4061-967e-0e48cbdd56cb
|
||||
Executable
+34
@@ -0,0 +1,34 @@
|
||||
#!/bin/bash
|
||||
|
||||
status_msg () {
|
||||
echo -e "\033[1m$1\033[0m"
|
||||
}
|
||||
|
||||
error_msg () {
|
||||
echo -e "\033[31m$1\033[0m" >&2
|
||||
tput sgr0
|
||||
}
|
||||
|
||||
status_msg "Running configure.sh..."
|
||||
|
||||
cd `dirname $0`/../discount/
|
||||
./configure.sh
|
||||
make blocktags
|
||||
|
||||
status_msg "Copying important files..."
|
||||
|
||||
if head -n 1 config.h | grep -q "^/\*$"; then
|
||||
# remove generated comments in config.h
|
||||
sed -i '1,/^ *\*\/ *$/ { d; }' <config.h
|
||||
else
|
||||
cp config.h ../discount-config/config.h && echo 'config.h'
|
||||
error_msg "Can't locate config.h comments!"
|
||||
error_msg "Check the diff before committing (and fix this script if you can)"
|
||||
fi
|
||||
cp mkdio.h ../discount-config/mkdio.h && echo 'mkdio.h'
|
||||
|
||||
status_msg "Clean files from working directory..."
|
||||
|
||||
git clean -df -e blocktags -e 'config.h' -e 'mkdio.h'
|
||||
|
||||
status_msg "Done!"
|
||||
@@ -0,0 +1,30 @@
|
||||
->Copyright (C) 2007 David Loren Parsons.
|
||||
All rights reserved.<-
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of works must retain the original copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the original copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither my name (David L Parsons) nor the names of contributors to
|
||||
this code may be used to endorse or promote products derived
|
||||
from this work without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
Discount is primarily my work, but it has only reached the point
|
||||
where it is via contributions, critiques, and bug reports from a
|
||||
host of other people, some of which are listed before. If your
|
||||
name isn't on this list, please remind me
|
||||
-david parsons (orc@pell.portland.or.us)
|
||||
|
||||
|
||||
Josh Wood -- Plan9 support.
|
||||
Mike Schiraldi -- Reddit style automatic links, MANY MANY MANY
|
||||
bug reports about boundary conditions and
|
||||
places where I didn't get it right.
|
||||
Jjgod Jiang -- Table of contents support.
|
||||
Petite Abeille -- Many bug reports about places where I didn't
|
||||
get it right.
|
||||
Tim Channon -- inspiration for the `mkd_xhtmlpage()` function
|
||||
Christian Herenz-- Many bug reports regarding my implementation of
|
||||
`[]()` and `![]()`
|
||||
A.S.Bradbury -- Portability bug reports for 64 bit systems.
|
||||
Joyent -- Loan of a solaris box so I could get discount
|
||||
working under solaris.
|
||||
Ryan Tomayko -- Portability requests (and the rdiscount ruby
|
||||
binding.)
|
||||
yidabu -- feedback on the documentation, bug reports
|
||||
against utf-8 support.
|
||||
Pierre Joye -- bug reports, php discount binding.
|
||||
Masayoshi Sekimura- perl discount binding.
|
||||
Jeremy Hinegardner- bug reports about list handling.
|
||||
Andrew White -- bug reports about the format of generated urls.
|
||||
Steve Huff -- bug reports about Makefile portability (for Fink)
|
||||
Ignacio Burgue?o-- bug reports about `>%class%`
|
||||
Henrik Nyh -- bug reports about embedded html handling.
|
||||
John J. Foerch -- bug reports about incorrect `–` and `—`
|
||||
translations.
|
||||
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include "cstring.h"
|
||||
#include "markdown.h"
|
||||
#include "amalloc.h"
|
||||
|
||||
|
||||
/* putc() into a cstring
|
||||
*/
|
||||
void
|
||||
Csputc(int c, Cstring *iot)
|
||||
{
|
||||
EXPAND(*iot) = c;
|
||||
}
|
||||
|
||||
|
||||
/* printf() into a cstring
|
||||
*/
|
||||
int
|
||||
Csprintf(Cstring *iot, char *fmt, ...)
|
||||
{
|
||||
va_list ptr;
|
||||
int siz=100;
|
||||
|
||||
do {
|
||||
RESERVE(*iot, siz);
|
||||
va_start(ptr, fmt);
|
||||
siz = vsnprintf(T(*iot)+S(*iot), ALLOCATED(*iot)-S(*iot), fmt, ptr);
|
||||
va_end(ptr);
|
||||
} while ( siz > (ALLOCATED(*iot)-S(*iot)) );
|
||||
|
||||
S(*iot) += siz;
|
||||
return siz;
|
||||
}
|
||||
|
||||
|
||||
/* write() into a cstring
|
||||
*/
|
||||
int
|
||||
Cswrite(Cstring *iot, char *bfr, int size)
|
||||
{
|
||||
RESERVE(*iot, size);
|
||||
memcpy(T(*iot)+S(*iot), bfr, size);
|
||||
S(*iot) += size;
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
/* reparse() into a cstring
|
||||
*/
|
||||
void
|
||||
Csreparse(Cstring *iot, char *buf, int size, int flags)
|
||||
{
|
||||
MMIOT f;
|
||||
___mkd_initmmiot(&f, 0);
|
||||
___mkd_reparse(buf, size, 0, &f, 0);
|
||||
___mkd_emblock(&f);
|
||||
SUFFIX(*iot, T(f.out), S(f.out));
|
||||
___mkd_freemmiot(&f, 0);
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
|
||||
HOW TO BUILD AND INSTALL DISCOUNT
|
||||
|
||||
1) Unpacking the distribution
|
||||
|
||||
The DISCOUNT sources are distributed in tarballs. After extracting from
|
||||
the tarball, you should end up with all the source and build files in the
|
||||
directory
|
||||
discount-(version)
|
||||
|
||||
2) Installing the distribution
|
||||
|
||||
DISCOUNT uses configure.sh to set itself up for compilation. To run
|
||||
configure, just do ``./configure.sh'' and it will check your system for
|
||||
build dependencies and build makefiles for you. If configure.sh finishes
|
||||
without complaint, you can then do a ``make'' to compile everything and a
|
||||
``make install'' to install the binaries.
|
||||
|
||||
Configure.sh has a few options that can be set:
|
||||
|
||||
--src=DIR where the source lives (.)
|
||||
--prefix=DIR where to install the final product (/usr/local)
|
||||
--execdir=DIR where to put executables (prefix/bin)
|
||||
--sbindir=DIR where to put static executables (prefix/sbin)
|
||||
--confdir=DIR where to put configuration information (/etc)
|
||||
--libdir=DIR where to put libraries (prefix/lib)
|
||||
--libexecdir=DIR where to put private executables
|
||||
--mandir=DIR where to put manpages
|
||||
--enable-dl-tag Use the DL tag extension
|
||||
--enable-pandoc-header Use pandoc-style header blocks
|
||||
--enable-superscript A^B expands to A<sup>B</sup>
|
||||
--enable-amalloc Use a debugging memory allocator (to detect leaks)
|
||||
--relaxed-emphasis Don't treat _ in the middle of a word as emphasis
|
||||
--with-tabstops=N Set tabstops to N characters (default is 4)
|
||||
|
||||
3) Installing sample programs and manpages
|
||||
|
||||
The standard ``make install'' rule just installs the binaries. If you
|
||||
want to install the sample programs, they are installed with
|
||||
``make install.samples''; to install manpages, ``make install.man''.
|
||||
A shortcut to install everything is ``make install.everything''
|
||||
@@ -0,0 +1,141 @@
|
||||
CC=@CC@ -I.
|
||||
LFLAGS=-L.
|
||||
CFLAGS=@CFLAGS@
|
||||
AR=@AR@
|
||||
RANLIB=@RANLIB@
|
||||
|
||||
BINDIR=@exedir@
|
||||
MANDIR=@mandir@
|
||||
LIBDIR=@libdir@
|
||||
INCDIR=@prefix@/include
|
||||
|
||||
PGMS=markdown
|
||||
SAMPLE_PGMS=mkd2html makepage
|
||||
@THEME@SAMPLE_PGMS+= theme
|
||||
MKDLIB=libmarkdown
|
||||
OBJS=mkdio.o markdown.o dumptree.o generate.o \
|
||||
resource.o docheader.o version.o toc.o css.o \
|
||||
xml.o Csio.o xmlpage.o basename.o emmatch.o \
|
||||
github_flavoured.o setup.o tags.o html5.o flags.o @AMALLOC@
|
||||
TESTFRAMEWORK=echo cols
|
||||
|
||||
MAN3PAGES=mkd-callbacks.3 mkd-functions.3 markdown.3 mkd-line.3
|
||||
|
||||
all: $(PGMS) $(SAMPLE_PGMS) $(TESTFRAMEWORK)
|
||||
|
||||
install: $(PGMS) $(DESTDIR)$(BINDIR) $(DESTDIR)$(LIBDIR) $(DESTDIR)$(INCDIR)
|
||||
@INSTALL_PROGRAM@ $(PGMS) $(DESTDIR)$(BINDIR)
|
||||
./librarian.sh install libmarkdown VERSION $(DESTDIR)$(LIBDIR)
|
||||
@INSTALL_DATA@ mkdio.h $(DESTDIR)$(INCDIR)
|
||||
|
||||
install.everything: install install.samples install.man
|
||||
|
||||
install.samples: $(SAMPLE_PGMS) install $(DESTDIR)$(BINDIR)
|
||||
@INSTALL_DIR@ $(DESTDIR)$(MANDIR)/man1
|
||||
for x in $(SAMPLE_PGMS); do \
|
||||
@INSTALL_PROGRAM@ $$x $(DESTDIR)$(BINDIR)/$(SAMPLE_PFX)$$x; \
|
||||
@INSTALL_DATA@ $$x.1 $(DESTDIR)$(MANDIR)/man1/$(SAMPLE_PFX)$$x.1; \
|
||||
done
|
||||
|
||||
install.man:
|
||||
@INSTALL_DIR@ $(DESTDIR)$(MANDIR)/man3
|
||||
@INSTALL_DATA@ $(MAN3PAGES) $(DESTDIR)$(MANDIR)/man3
|
||||
for x in mkd_line mkd_generateline; do \
|
||||
( echo '.\"' ; echo ".so man3/mkd-line.3" ) > $(DESTDIR)$(MANDIR)/man3/$$x.3;\
|
||||
done
|
||||
for x in mkd_in mkd_string; do \
|
||||
( echo '.\"' ; echo ".so man3/markdown.3" ) > $(DESTDIR)$(MANDIR)/man3/$$x.3;\
|
||||
done
|
||||
for x in mkd_compile mkd_css mkd_generatecss mkd_generatehtml mkd_cleanup mkd_doc_title mkd_doc_author mkd_doc_date; do \
|
||||
( echo '.\"' ; echo ".so man3/mkd-functions.3" ) > $(DESTDIR)$(MANDIR)/man3/$$x.3; \
|
||||
done
|
||||
@INSTALL_DIR@ $(DESTDIR)$(MANDIR)/man7
|
||||
@INSTALL_DATA@ markdown.7 mkd-extensions.7 $(DESTDIR)$(MANDIR)/man7
|
||||
@INSTALL_DIR@ $(DESTDIR)$(MANDIR)/man1
|
||||
@INSTALL_DATA@ markdown.1 $(DESTDIR)$(MANDIR)/man1
|
||||
|
||||
install.everything: install install.man
|
||||
|
||||
$(DESTDIR)$(BINDIR):
|
||||
@INSTALL_DIR@ $(DESTDIR)$(BINDIR)
|
||||
|
||||
$(DESTDIR)$(INCDIR):
|
||||
@INSTALL_DIR@ $(DESTDIR)$(INCDIR)
|
||||
|
||||
$(DESTDIR)$(LIBDIR):
|
||||
@INSTALL_DIR@ $(DESTDIR)$(LIBDIR)
|
||||
|
||||
version.o: version.c VERSION
|
||||
$(CC) $(CFLAGS) -DVERSION=\"`cat VERSION`\" -c version.c
|
||||
|
||||
VERSION:
|
||||
@true
|
||||
|
||||
tags.o: tags.c blocktags
|
||||
|
||||
blocktags: mktags
|
||||
./mktags > blocktags
|
||||
|
||||
# example programs
|
||||
@THEME@theme: theme.o $(MKDLIB) mkdio.h
|
||||
@THEME@ $(CC) $(CFLAGS) $(LFLAGS) -o theme theme.o pgm_options.o -lmarkdown @LIBS@
|
||||
|
||||
|
||||
mkd2html: mkd2html.o $(MKDLIB) mkdio.h
|
||||
$(CC) $(CFLAGS) $(LFLAGS) -o mkd2html mkd2html.o -lmarkdown @LIBS@
|
||||
|
||||
markdown: main.o pgm_options.o $(MKDLIB)
|
||||
$(CC) $(CFLAGS) $(LFLAGS) -o markdown main.o pgm_options.o -lmarkdown @LIBS@
|
||||
|
||||
makepage: makepage.c pgm_options.o $(MKDLIB) mkdio.h
|
||||
$(CC) $(CFLAGS) $(LFLAGS) -o makepage makepage.c pgm_options.o -lmarkdown @LIBS@
|
||||
|
||||
pgm_options.o: pgm_options.c mkdio.h config.h
|
||||
$(CC) $(CFLAGS) -I. -c pgm_options.c
|
||||
|
||||
main.o: main.c mkdio.h config.h
|
||||
$(CC) $(CFLAGS) -I. -c main.c
|
||||
|
||||
$(MKDLIB): $(OBJS)
|
||||
./librarian.sh make $(MKDLIB) VERSION $(OBJS)
|
||||
|
||||
verify: echo tools/checkbits.sh
|
||||
@./echo -n "headers ... "; tools/checkbits.sh && echo "GOOD"
|
||||
|
||||
test: $(PGMS) $(TESTFRAMEWORK) verify
|
||||
@for x in tests/*.t; do \
|
||||
@LD_LIBRARY_PATH@=`pwd` sh $$x || exit 1; \
|
||||
done
|
||||
|
||||
cols: tools/cols.c config.h
|
||||
$(CC) -o cols tools/cols.c
|
||||
echo: tools/echo.c config.h
|
||||
$(CC) -o echo tools/echo.c
|
||||
|
||||
clean:
|
||||
rm -f $(PGMS) $(TESTFRAMEWORK) $(SAMPLE_PGMS) *.o
|
||||
rm -f $(MKDLIB) `./librarian.sh files $(MKDLIB) VERSION`
|
||||
|
||||
distclean spotless: clean
|
||||
rm -f @GENERATED_FILES@ @CONFIGURE_FILES@ ./mktags ./blocktags ./librarian.sh
|
||||
|
||||
Csio.o: Csio.c cstring.h amalloc.h config.h markdown.h
|
||||
amalloc.o: amalloc.c
|
||||
basename.o: basename.c config.h cstring.h amalloc.h markdown.h
|
||||
css.o: css.c config.h cstring.h amalloc.h markdown.h
|
||||
docheader.o: docheader.c config.h cstring.h amalloc.h markdown.h
|
||||
dumptree.o: dumptree.c markdown.h cstring.h amalloc.h config.h
|
||||
emmatch.o: emmatch.c config.h cstring.h amalloc.h markdown.h
|
||||
generate.o: generate.c config.h cstring.h amalloc.h markdown.h
|
||||
main.o: main.c config.h amalloc.h
|
||||
pgm_options.o: pgm_options.c pgm_options.h config.h amalloc.h
|
||||
makepage.o: makepage.c
|
||||
markdown.o: markdown.c config.h cstring.h amalloc.h markdown.h
|
||||
mkd2html.o: mkd2html.c config.h mkdio.h cstring.h amalloc.h
|
||||
mkdio.o: mkdio.c config.h cstring.h amalloc.h markdown.h
|
||||
resource.o: resource.c config.h cstring.h amalloc.h markdown.h
|
||||
theme.o: theme.c config.h mkdio.h cstring.h amalloc.h
|
||||
toc.o: toc.c config.h cstring.h amalloc.h markdown.h
|
||||
version.o: version.c config.h
|
||||
xml.o: xml.c config.h cstring.h amalloc.h markdown.h
|
||||
xmlpage.o: xmlpage.c config.h cstring.h amalloc.h markdown.h
|
||||
@@ -0,0 +1,40 @@
|
||||
% Discount on Plan 9
|
||||
% Josh Wood
|
||||
% 2009-06-12
|
||||
|
||||
# *Discount* Markdown compiler on Plan 9
|
||||
|
||||
## Build
|
||||
|
||||
% CONFIG='--enable-all-features' mk config
|
||||
% mk install
|
||||
% markdown -V
|
||||
markdown: discount X.Y.Z DL_TAG HEADER DEBUG SUPERSCRIPT RELAXED DIV
|
||||
|
||||
`--enable-all-features` may be replaced by zero or more of:
|
||||
|
||||
--enable-dl-tag Use the DL tag extension
|
||||
--enable-pandoc-header Use pandoc-style header blocks
|
||||
--enable-superscript A^B becomes A<sup>B</sup>
|
||||
--enable-amalloc Enable memory allocation debugging
|
||||
--relaxed-emphasis underscores aren't special in the middle of words
|
||||
--with-tabstops=N Set tabstops to N characters (default is 4)
|
||||
--enable-div Enable >%id% divisions
|
||||
--enable-alpha-list Enable (a)/(b)/(c) lists
|
||||
--enable-all-features Turn on all stable optional features
|
||||
|
||||
## Notes
|
||||
|
||||
The supplied mkfile merely drives Discount's own configure script and
|
||||
then APE's *psh* environment to build the Discount source, then copies
|
||||
the result(s) to locations appropriate for system-wide use on Plan 9.
|
||||
There are a few other *mk*(1) targets:
|
||||
|
||||
`install.libs`: Discount includes a C library and header.
|
||||
Installation is optional. Plan 9 binaries are statically linked.
|
||||
|
||||
`install.man`: Add manual pages for markdown(1) and (6).
|
||||
|
||||
`install.progs`: Extra programs. *makepage* writes complete XHTML
|
||||
documents, rather than fragments. *mkd2html* is similar, but produces
|
||||
HTML.
|
||||
@@ -0,0 +1,169 @@
|
||||
.TH MARKDOWN 1
|
||||
.SH NAME
|
||||
markdown \- convert Markdown text to HTML
|
||||
.SH SYNOPSIS
|
||||
.B markdown
|
||||
[
|
||||
.B -dTV
|
||||
]
|
||||
[
|
||||
.BI -b " url-base
|
||||
]
|
||||
[
|
||||
.BI -F " bitmap
|
||||
]
|
||||
[
|
||||
.BI -f " flags
|
||||
]
|
||||
[
|
||||
.BI -o " ofile
|
||||
]
|
||||
[
|
||||
.BI -s " text
|
||||
]
|
||||
[
|
||||
.BI -t " text
|
||||
]
|
||||
[
|
||||
.I file
|
||||
]
|
||||
.SH DESCRIPTION
|
||||
The
|
||||
.I markdown
|
||||
utility reads the
|
||||
.IR Markdown (6)-formatted
|
||||
.I file
|
||||
(or standard input) and writes its
|
||||
.SM HTML
|
||||
fragment representation on standard output.
|
||||
.PP
|
||||
The options are:
|
||||
.TF dfdoptions
|
||||
.TP
|
||||
.BI -b " url-base
|
||||
Links in source begining with
|
||||
.B /
|
||||
will be prefixed with
|
||||
.I url-base
|
||||
in the output.
|
||||
.TP
|
||||
.B -d
|
||||
Instead of printing an
|
||||
.SM HTML
|
||||
fragment, print a parse tree.
|
||||
.TP
|
||||
.BI -F " bitmap
|
||||
Set translation flags.
|
||||
.I Bitmap
|
||||
is a bit map of the various configuration options described in
|
||||
.IR markdown (2).
|
||||
.TP
|
||||
.BI -f " flags
|
||||
Set or clear various translation
|
||||
.IR flags ,
|
||||
described below.
|
||||
.I Flags
|
||||
are in a comma-delimited list, with an optional
|
||||
.B +
|
||||
(set) prefix on each flag.
|
||||
.TP
|
||||
.BI -o " ofile
|
||||
Write the generated
|
||||
.SM HTML
|
||||
to
|
||||
.IR ofile .
|
||||
.TP
|
||||
.BI -s " text
|
||||
Use the
|
||||
.IR markdown (2)
|
||||
function to format the
|
||||
.I text
|
||||
on standard input.
|
||||
.TP
|
||||
.B -T
|
||||
Under
|
||||
.B -f
|
||||
.BR toc ,
|
||||
print the table of contents as an unordered list before the usual
|
||||
.SM HTML
|
||||
output.
|
||||
.TP
|
||||
.BI -t " text
|
||||
Use
|
||||
.IR mkd_text
|
||||
(in
|
||||
.IR markdown (2))
|
||||
to format
|
||||
.I text
|
||||
instead of processing standard input with
|
||||
.IR markdown .
|
||||
.TP
|
||||
.B -V
|
||||
Show version number and configuration. If the version includes the string
|
||||
.BR DL_TAG ,
|
||||
.I markdown
|
||||
was configured with definition list support. If the version includes the string
|
||||
.BR HEADER ,
|
||||
.I markdown
|
||||
was configured to support pandoc header blocks.
|
||||
.PD
|
||||
.SS TRANSLATION FLAGS
|
||||
The translation flags understood by
|
||||
.B -f
|
||||
are:
|
||||
.TF \ noheader
|
||||
.TP
|
||||
.B noimage
|
||||
Don't allow image tags.
|
||||
.TP
|
||||
.B nolinks
|
||||
Don't allow links.
|
||||
.TP
|
||||
.B nohtml
|
||||
Don't allow any embedded HTML.
|
||||
.TP
|
||||
.B cdata
|
||||
Generate valid XML output.
|
||||
.TP
|
||||
.B noheader
|
||||
Do not process pandoc headers.
|
||||
.TP
|
||||
.B notables
|
||||
Do not process the syntax extension for tables.
|
||||
.TP
|
||||
.B tabstops
|
||||
Use Markdown-standard 4-space tabstops.
|
||||
.TP
|
||||
.B strict
|
||||
Disable superscript and relaxed emphasis.
|
||||
.TP
|
||||
.B relax
|
||||
Enable superscript and relaxed emphasis (the default).
|
||||
.TP
|
||||
.B toc
|
||||
Enable table of contents support, generated from headings (in
|
||||
.IR markdown (6))
|
||||
in the source.
|
||||
.TP
|
||||
.B 1.0
|
||||
Revert to Markdown 1.0 compatibility.
|
||||
.PD
|
||||
.PP
|
||||
For example,
|
||||
.B -f nolinks,quot
|
||||
tells
|
||||
.I markdown
|
||||
not to allow
|
||||
.B <a>
|
||||
tags, and to expand double quotes.
|
||||
.SH SOURCE
|
||||
.B /sys/src/cmd/discount
|
||||
.SH SEE ALSO
|
||||
.IR markdown (2),
|
||||
.IR markdown (6)
|
||||
.PP
|
||||
http://daringfireball.net/projects/markdown/,
|
||||
``Markdown''.
|
||||
.SH DIAGNOSTICS
|
||||
.I Markdown
|
||||
exits 0 on success and >0 if an error occurs.
|
||||
@@ -0,0 +1,332 @@
|
||||
.TH MARKDOWN 2
|
||||
.SH NAME
|
||||
mkd_in, mkd_string, markdown, mkd_compile, mkd_css, mkd_generatecss,
|
||||
mkd_document, mkd_generatehtml, mkd_xhtmlpage, mkd_toc, mkd_generatetoc,
|
||||
mkd_cleanup, mkd_doc_title, mkd_doc_author, mkd_doc_date, mkd_line,
|
||||
mkd_generateline \- convert Markdown text to HTML
|
||||
.SH SYNOPSIS
|
||||
.ta \w'MMIOT* 'u
|
||||
.B #include <mkdio.h>
|
||||
.PP
|
||||
.B
|
||||
MMIOT* mkd_in(FILE *input, int flags)
|
||||
.PP
|
||||
.B
|
||||
MMIOT* mkd_string(char *buf, int size, int flags)
|
||||
.PP
|
||||
.B
|
||||
int markdown(MMIOT *doc, FILE *output, int flags)
|
||||
.PP
|
||||
.B
|
||||
int mkd_compile(MMIOT *document, int flags)
|
||||
.PP
|
||||
.B
|
||||
int mkd_css(MMIOT *document, char **doc)
|
||||
.PP
|
||||
.B
|
||||
int mkd_generatecss(MMIOT *document, FILE *output)
|
||||
.PP
|
||||
.B
|
||||
int mkd_document(MMIOT *document, char **doc)
|
||||
.PP
|
||||
.B
|
||||
int mkd_generatehtml(MMIOT *document, FILE *output)
|
||||
.PP
|
||||
.B
|
||||
int mkd_xhtmlpage(MMIOT *document, int flags, FILE *output)
|
||||
.PP
|
||||
.B
|
||||
int mkd_toc(MMIOT *document, char **doc)
|
||||
.PP
|
||||
.B
|
||||
int mkd_generatetoc(MMIOT *document, FILE *output)
|
||||
.PP
|
||||
.B
|
||||
void mkd_cleanup(MMIOT*);
|
||||
.PP
|
||||
.B
|
||||
char* mkd_doc_title(MMIOT*)
|
||||
.PP
|
||||
.B
|
||||
char* mkd_doc_author(MMIOT*)
|
||||
.PP
|
||||
.B
|
||||
char* mkd_doc_date(MMIOT*)
|
||||
.PP
|
||||
.B
|
||||
int mkd_line(char *string, int size, char **doc, int flags)
|
||||
.PP
|
||||
.B
|
||||
int mkd_generateline(char *string, int size, FILE *output, int flags)
|
||||
.PD
|
||||
.PP
|
||||
.SH DESCRIPTION
|
||||
These functions convert
|
||||
.IR Markdown (6)
|
||||
text into
|
||||
.SM HTML
|
||||
markup.
|
||||
.PP
|
||||
.I Mkd_in
|
||||
reads the text referenced by pointer to
|
||||
.B FILE
|
||||
.I input
|
||||
and returns a pointer to an
|
||||
.B MMIOT
|
||||
structure of the form expected by
|
||||
.I markdown
|
||||
and the other converters.
|
||||
.I Mkd_string
|
||||
accepts one
|
||||
.I string
|
||||
and returns a pointer to
|
||||
.BR MMIOT .
|
||||
.PP
|
||||
After such preparation,
|
||||
.I markdown
|
||||
converts
|
||||
.I doc
|
||||
and writes the result to
|
||||
.IR output ,
|
||||
while
|
||||
.I mkd_compile
|
||||
transforms
|
||||
.I document
|
||||
in-place.
|
||||
.PP
|
||||
One or more of the following
|
||||
.I flags
|
||||
(combined with
|
||||
.BR OR )
|
||||
control
|
||||
.IR markdown 's
|
||||
processing of
|
||||
.IR doc :
|
||||
.TF MKD_NOIMAGE
|
||||
.TP
|
||||
.B MKD_NOIMAGE
|
||||
Do not process
|
||||
.B ![]
|
||||
and remove
|
||||
.B <img>
|
||||
tags from the output.
|
||||
.TP
|
||||
.B MKD_NOLINKS
|
||||
Do not process
|
||||
.B []
|
||||
and remove
|
||||
.B <a>
|
||||
tags from the output.
|
||||
.TP
|
||||
.B MKD_NOPANTS
|
||||
Suppress Smartypants-style replacement of quotes, dashes, or ellipses.
|
||||
.TP
|
||||
.B MKD_STRICT
|
||||
Disable superscript and relaxed emphasis processing if configured; otherwise a no-op.
|
||||
.TP
|
||||
.B MKD_TAGTEXT
|
||||
Process as inside an
|
||||
.SM HTML
|
||||
tag: no
|
||||
.BR <em> ,
|
||||
no
|
||||
.BR <bold> ,
|
||||
no
|
||||
.SM HTML
|
||||
or
|
||||
.B []
|
||||
expansion.
|
||||
.TP
|
||||
.B MKD_NO_EXT
|
||||
Don't process pseudo-protocols (in
|
||||
.IR markdown (6)).
|
||||
.TP
|
||||
.B MKD_CDATA
|
||||
Generate code for
|
||||
.SM XML
|
||||
.B ![CDATA[...]]
|
||||
element.
|
||||
.TP
|
||||
.B MKD_NOHEADER
|
||||
Don't process Pandoc-style headers.
|
||||
.TP
|
||||
.B MKD_TABSTOP
|
||||
When reading documents, expand tabs to 4 spaces, overriding any compile-time configuration.
|
||||
.TP
|
||||
.B MKD_TOC
|
||||
Label headings for use with the
|
||||
.I mkd_generatetoc
|
||||
and
|
||||
.I mkd_toc
|
||||
functions.
|
||||
.TP
|
||||
.B MKD_1_COMPAT
|
||||
MarkdownTest_1.0 compatibility. Trim trailing spaces from first line of code blocks and disable implicit reference links (in
|
||||
.IR markdown (6)).
|
||||
.TP
|
||||
.B MKD_AUTOLINK
|
||||
Greedy
|
||||
.SM URL
|
||||
generation. When set, any
|
||||
.SM URL
|
||||
is converted to a hyperlink, even those not encased in
|
||||
.BR <> .
|
||||
.TP
|
||||
.B MKD_SAFELINK
|
||||
Don't make hyperlinks from
|
||||
.B [][]
|
||||
links that have unknown
|
||||
.SM URL
|
||||
protocol types.
|
||||
.TP
|
||||
.B MKD_NOTABLES
|
||||
Do not process the syntax extension for tables (in
|
||||
.IR markdown (6)).
|
||||
.TP
|
||||
.B MKD_EMBED
|
||||
All of
|
||||
.BR MKD_NOLINKS ,
|
||||
.BR MKD_NOIMAGE ,
|
||||
and
|
||||
.BR MKD_TAGTEXT .
|
||||
.PD
|
||||
.PP
|
||||
This implementation supports
|
||||
Pandoc-style
|
||||
headers and inline
|
||||
.SM CSS
|
||||
.B <style>
|
||||
blocks, but
|
||||
.I markdown
|
||||
does not access the data provided by these extensions.
|
||||
The following functions do, and allow other manipulations.
|
||||
.PP
|
||||
Given a pointer to
|
||||
.B MMIOT
|
||||
prepared by
|
||||
.I mkd_in
|
||||
or
|
||||
.IR mkd_string ,
|
||||
.I mkd_compile
|
||||
compiles the
|
||||
.I document
|
||||
into
|
||||
.BR <style> ,
|
||||
Pandoc, and
|
||||
.SM HTML
|
||||
sections. It accepts the
|
||||
.I flags
|
||||
described for
|
||||
.IR markdown ,
|
||||
above.
|
||||
.PP
|
||||
Once compiled, the document particulars can be read and written:
|
||||
.PP
|
||||
.I Mkd_css
|
||||
allocates a string and populates it with any
|
||||
.B <style>
|
||||
sections from the document.
|
||||
.I Mkd_generatecss
|
||||
writes any
|
||||
.B <style>
|
||||
sections to
|
||||
.IR output .
|
||||
.PP
|
||||
.I Mkd_document
|
||||
points
|
||||
.I doc
|
||||
to the
|
||||
.B MMIOT
|
||||
.IR document ,
|
||||
returning
|
||||
.IR document 's
|
||||
size.
|
||||
.PP
|
||||
.I Mkd_generatehtml
|
||||
writes the rest of the
|
||||
.I document
|
||||
to the
|
||||
.IR output .
|
||||
.PP
|
||||
.IR Mkd_doc_title ,
|
||||
.IR mkd_doc_author ,
|
||||
and
|
||||
.I mkd_doc_date
|
||||
read the contents of any Pandoc header.
|
||||
.PP
|
||||
.I Mkd_xhtmlpage
|
||||
writes an
|
||||
.SM XHTML
|
||||
page representation of the document.
|
||||
It accepts the
|
||||
.I flags
|
||||
described for
|
||||
.IR markdown ,
|
||||
above.
|
||||
.PP
|
||||
.I Mkd_toc
|
||||
.IR malloc s
|
||||
a buffer into which it writes an outline, in the form of a
|
||||
.B <ul>
|
||||
element populated with
|
||||
.BR <li> s
|
||||
each containing a link to successive headings in the
|
||||
.IR document .
|
||||
It returns the size of that string.
|
||||
.I Mkd_generatetoc
|
||||
is similar,
|
||||
but writes the outline to the
|
||||
.I output
|
||||
referenced by a pointer to
|
||||
.BR FILE .
|
||||
.PP
|
||||
.I Mkd_cleanup
|
||||
deletes a processed
|
||||
.BR MMIOT .
|
||||
.PP
|
||||
The last two functions convert a single line of markdown source, for example a page title or a signature.
|
||||
.I Mkd_line
|
||||
allocates a buffer into which it writes an
|
||||
.SM HTML
|
||||
fragment representation of the
|
||||
.IR string .
|
||||
.I Mkd_generateline
|
||||
writes the result to
|
||||
.IR output .
|
||||
.SH SOURCE
|
||||
.B /sys/src/cmd/discount
|
||||
.SH SEE ALSO
|
||||
.IR markdown (1),
|
||||
.IR markdown (6)
|
||||
.SH DIAGNOSTICS
|
||||
The
|
||||
.I mkd_in
|
||||
and
|
||||
.I mkd_string
|
||||
functions return a pointer to
|
||||
.B MMIOT
|
||||
on success, null on failure.
|
||||
.IR Markdown ,
|
||||
.IR mkd_compile ,
|
||||
.IR mkd_style ,
|
||||
and
|
||||
.I mkd_generatehtml
|
||||
return
|
||||
.B 0
|
||||
on success,
|
||||
.B -1
|
||||
otherwise.
|
||||
.SH BUGS
|
||||
Error handling is minimal at best.
|
||||
.PP
|
||||
The
|
||||
.B MMIOT
|
||||
created by
|
||||
.I mkd_string
|
||||
is deleted by the
|
||||
.I markdown
|
||||
function.
|
||||
.PP
|
||||
This is an
|
||||
.SM APE
|
||||
library.
|
||||
@@ -0,0 +1,543 @@
|
||||
.TH MARKDOWN 6
|
||||
.SH NAME
|
||||
Markdown \- text formatting syntax
|
||||
.SH DESCRIPTION
|
||||
Markdown
|
||||
is a text markup syntax for machine conversion to
|
||||
the more complex
|
||||
.SM HTML
|
||||
or
|
||||
.SM XHTML
|
||||
markup languages.
|
||||
It is intended to be easy to read and to write, with
|
||||
emphasis on readability.
|
||||
A Markdown-formatted document should be publishable as-is,
|
||||
in plain text, without the formatting distracting the reader.
|
||||
.PP
|
||||
The biggest source of inspiration for Markdown's
|
||||
syntax is the format of plain text email. The markup is comprised entirely
|
||||
of punctuation characters, chosen so as to look like what they mean.
|
||||
Asterisks around a word look like
|
||||
.IR *emphasis* .
|
||||
Markdown lists look like lists. Even
|
||||
blockquotes look like quoted passages of text, assuming the reader has
|
||||
used email.
|
||||
.PP
|
||||
.SS Block Elements
|
||||
.TF W
|
||||
.PD
|
||||
.TP
|
||||
Paragraphs and Line Breaks
|
||||
A paragraph is 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 indented with spaces or tabs.
|
||||
.IP
|
||||
Lines may be freely broken for readability; Markdown
|
||||
does not translate source line breaks to
|
||||
.B <br />
|
||||
tags. To request generation of
|
||||
.B <br />
|
||||
in the output, end a line with two or more spaces, then a newline.
|
||||
.TP
|
||||
Headings
|
||||
Headings can be marked in two ways, called
|
||||
.I setext
|
||||
and
|
||||
.IR atx .
|
||||
.IP
|
||||
Setext-style headings are
|
||||
``underlined'' using equal signs (for first-level
|
||||
headings) and dashes (for second-level headings).
|
||||
.IP
|
||||
Atx-style headings use 1-6 hash characters at the start of the line,
|
||||
corresponding to
|
||||
.SM HTML
|
||||
.BR <h^(1-6)^> .
|
||||
Optional closing hashes may follow
|
||||
the heading text.
|
||||
.TP
|
||||
Blockquotes
|
||||
Lines beginning with
|
||||
.B >
|
||||
are output in blockquotes.
|
||||
Blockquotes can be nested
|
||||
by multiple levels of
|
||||
.BR >> .
|
||||
Blockquotes can contain other Markdown elements, including
|
||||
headings, lists, and code blocks.
|
||||
.TP
|
||||
Lists
|
||||
Markdown supports ordered (numbered) and unordered (bulleted) lists.
|
||||
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, then the list item text.
|
||||
A newline terminates each list item.
|
||||
.IP
|
||||
Unordered lists use asterisks, pluses, and hyphens interchangeably as
|
||||
list markers.
|
||||
.IP
|
||||
Ordered lists use integers followed by periods as list markers.
|
||||
The order of the integers is not interpreted,
|
||||
but the list should begin with
|
||||
.BR 1 .
|
||||
.IP
|
||||
If list items are separated by blank lines, Markdown will wrap each list
|
||||
item in
|
||||
.B <p>
|
||||
tags in the
|
||||
.SM HTML
|
||||
output.
|
||||
.IP
|
||||
List items may consist of multiple paragraphs.
|
||||
Each subsequent
|
||||
paragraph within a list item must be indented by either 4 spaces
|
||||
or one tab.
|
||||
To put a blockquote within a list item, the blockquote's
|
||||
.B >
|
||||
marker needs to be indented.
|
||||
To put a code block within a list item, the code block needs
|
||||
to be indented
|
||||
.I twice
|
||||
-- 8 spaces or two tabs.
|
||||
.TP
|
||||
Code Blocks
|
||||
To produce a code block, indent every line of the
|
||||
block by at least 4 spaces or 1 tab.
|
||||
A code block continues until it reaches a line that is not indented.
|
||||
.IP
|
||||
Rather than forming normal paragraphs, the lines
|
||||
of a code block are interpreted literally.
|
||||
Regular Markdown syntax is not processed within code blocks.
|
||||
Markdown wraps a code block in both
|
||||
.B <pre>
|
||||
and
|
||||
.B <code>
|
||||
tags.
|
||||
One level of indentation -- 4
|
||||
spaces or 1 tab -- is removed from each line of the code block in
|
||||
the output.
|
||||
.TP
|
||||
Horizontal Rules
|
||||
Produce a horizontal rule tag
|
||||
.RB ( <hr\ /> )
|
||||
by placing three or
|
||||
more hyphens, asterisks, or underscores on a line by themselves.
|
||||
.SS Span Elements
|
||||
.TF W
|
||||
.PD
|
||||
.TP
|
||||
Links
|
||||
Markdown supports two styles of links:
|
||||
.I inline
|
||||
and
|
||||
.IR reference .
|
||||
In both styles, the link text is delimited by square brackets
|
||||
.RB ( [] ).
|
||||
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 link URL, along with an optional
|
||||
title for the link surrounded in double quotes.
|
||||
For example:
|
||||
.IP
|
||||
.EX
|
||||
An [example](http://example.com/ "Title") inline link.
|
||||
.EE
|
||||
.IP
|
||||
Reference-style links use a second set of square brackets, inside
|
||||
which you place a label of your choosing to identify the link:
|
||||
.IP
|
||||
.EX
|
||||
An [example][id] reference-style link.
|
||||
.EE
|
||||
.IP
|
||||
The label is then assigned a value on its own line, anywhere in the document:
|
||||
.IP
|
||||
.EX
|
||||
[id]: http://example.com/ "Optional Title"
|
||||
.EE
|
||||
.IP
|
||||
Link label names may consist of letters, numbers, spaces, and
|
||||
punctuation.
|
||||
Labels are not case sensitive.
|
||||
An empty label bracket
|
||||
set after a reference-style link implies the link label is equivalent to
|
||||
the link text.
|
||||
A URL value can then be assigned to the link by referencing
|
||||
the link text as the label name.
|
||||
.TP
|
||||
Emphasis
|
||||
Markdown treats asterisks
|
||||
.RB ( * )
|
||||
and underscores
|
||||
.RB ( _ )
|
||||
as indicators of emphasis.
|
||||
Text surrounded with single asterisks or underscores
|
||||
will be wrapped with an
|
||||
.SM HTML
|
||||
.B <em>
|
||||
tag.
|
||||
Double asterisks or underscores generate an
|
||||
.SM HTML
|
||||
.B <strong>
|
||||
tag.
|
||||
.TP
|
||||
Code
|
||||
To indicate a span of code, wrap it with backtick quotes
|
||||
.RB ( ` ).
|
||||
Unlike a code block, a code span indicates code within a
|
||||
normal paragraph.
|
||||
To include a literal backtick character within a code span, you can use
|
||||
multiple backticks as the opening and closing delimiters:
|
||||
.IP
|
||||
.EX
|
||||
``There is a literal backtick (`) here.``
|
||||
.EE
|
||||
.TP
|
||||
Images
|
||||
Markdown image syntax is intended to resemble that
|
||||
for links, allowing for two styles, once again
|
||||
.I inline
|
||||
and
|
||||
.IR reference .
|
||||
The syntax is as for each respective style of link, described above, but
|
||||
prefixed with an exclamation mark character
|
||||
.RB ( ! ).
|
||||
Inline image syntax looks like this:
|
||||
.IP
|
||||
.EX
|
||||

|
||||
.EE
|
||||
.IP
|
||||
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.
|
||||
.IP
|
||||
Reference-style image syntax looks like this:
|
||||
.IP
|
||||
.EX
|
||||
![Alt text][id]
|
||||
.EE
|
||||
.IP
|
||||
Where
|
||||
.I id
|
||||
is a label used as for reference-style URL links, described above.
|
||||
.SS Convenience
|
||||
.TF W
|
||||
.PD
|
||||
.TP
|
||||
Automatic Links
|
||||
There is a shortcut style for creating ``automatic''
|
||||
links for URLs and email addresses.
|
||||
Surround the URL
|
||||
or address with angle brackets.
|
||||
.TP
|
||||
Backslash Escapes
|
||||
Use backslash escapes to generate literal
|
||||
characters which would otherwise have special meaning in Markdown's
|
||||
formatting syntax.
|
||||
.TP
|
||||
Inline HTML
|
||||
For markup that is not covered by Markdown's
|
||||
syntax, simply use the
|
||||
.SM HTML
|
||||
directly.
|
||||
The only restrictions are that block-level
|
||||
.SM HTML
|
||||
elements --
|
||||
.BR <div> ,
|
||||
.BR <table> ,
|
||||
.BR <pre> ,
|
||||
.BR <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 formatting syntax is
|
||||
not processed within block-level
|
||||
.SM HTML
|
||||
tags.
|
||||
.IP
|
||||
Span-level
|
||||
.SM HTML
|
||||
tags -- e.g.
|
||||
.BR <span> ,
|
||||
.BR <cite> ,
|
||||
or
|
||||
.B <del>
|
||||
-- can be
|
||||
used anywhere in a Markdown
|
||||
paragraph, list item, or heading.
|
||||
It is permitted to use
|
||||
.SM HTML
|
||||
tags instead of Markdown formatting; e.g.
|
||||
.SM HTML
|
||||
.B <a>
|
||||
or
|
||||
.B <img>
|
||||
tags instead of Markdown's
|
||||
link or image syntax.
|
||||
Unlike block-level
|
||||
.SM HTML
|
||||
tags, Markdown
|
||||
syntax
|
||||
.I is
|
||||
processed within the elements of span-level tags.
|
||||
.TP
|
||||
Automatic Special Character Escapes
|
||||
To be displayed literally in a user agent, the characters
|
||||
.B <
|
||||
and
|
||||
.B &
|
||||
must appear as escaped entities in
|
||||
.SM HTML
|
||||
source, e.g.
|
||||
.B <
|
||||
and
|
||||
.BR & .
|
||||
Markdown
|
||||
allows natural use of these characters, taking care of
|
||||
the necessary escaping.
|
||||
The ampersand part of a directly-used
|
||||
.SM HTML
|
||||
entity remains unchanged; otherwise it will be translated
|
||||
into
|
||||
.BR & .
|
||||
Inside code spans and blocks, angle brackets and
|
||||
ampersands are always encoded automatically.
|
||||
This makes it easy to use Markdown to write about
|
||||
.SM HTML
|
||||
code.
|
||||
.PP
|
||||
.SS Smarty Pants
|
||||
The
|
||||
.IR markdown (1)
|
||||
utility transforms a few plain text symbols into their typographically-fancier
|
||||
.SM HTML
|
||||
entity equivalents.
|
||||
These are extensions to the standard Markdown syntax.
|
||||
.TF W
|
||||
.PD
|
||||
.TP
|
||||
Punctuation
|
||||
Input single- and double-quotes are transformed
|
||||
into ``curly'' quote entities in the output (e.g.,
|
||||
.B 'text'
|
||||
becomes
|
||||
.BR ‘text’ ).
|
||||
Input double-dashes
|
||||
.RB ( -- )
|
||||
and triple-dashes become en- and em-dashes, respectively,
|
||||
while a series of three dots
|
||||
.RB ( ... )
|
||||
in the input becomes an ellipsis entity
|
||||
.RB ( … )
|
||||
in the
|
||||
.SM HTML
|
||||
output.
|
||||
.TP
|
||||
Symbols
|
||||
Three other transformations replace the common plain-text shorthands
|
||||
.BR (c) ,
|
||||
.BR (r) ,
|
||||
and
|
||||
.BR (tm)
|
||||
from the input with their respective
|
||||
.SM HTML
|
||||
entities. (As in
|
||||
.B (c)
|
||||
becoming
|
||||
.BR © ,
|
||||
the Copyright symbol entity.)
|
||||
.TP
|
||||
Fractions
|
||||
A small set of plain-text shorthands for fractions is recognized.
|
||||
.B 1/4
|
||||
becomes
|
||||
.BR ¼ ,
|
||||
for example. These fraction notations are replaced with their
|
||||
.SM HTML
|
||||
entity equivalents:
|
||||
.BR 1/4 ,
|
||||
.BR 1/2 ,
|
||||
.BR 3/4 .
|
||||
.B 1/4th
|
||||
and
|
||||
.B 3/4ths
|
||||
are replaced with their entity and the indicated ordinal suffix letters.
|
||||
.PP
|
||||
Like the basic Markdown syntax, none of the ``Smarty Pants'' extensions are processed
|
||||
inside code blocks or spans.
|
||||
.PP
|
||||
.SS Discount Extensions
|
||||
.IR Markdown (1)
|
||||
recognizes some extensions to the Markdown format,
|
||||
many of them adopted or adapted from other Markdown
|
||||
interpreters or document formatting systems.
|
||||
.TF W
|
||||
.PD
|
||||
.TP
|
||||
Pandoc Headers
|
||||
If
|
||||
.I markdown
|
||||
was configured with
|
||||
.BR --enable-pandoc-header ,
|
||||
the markdown source can have a 3-line Pandoc header in the format of
|
||||
.IP
|
||||
.EX
|
||||
% Title
|
||||
% Author
|
||||
% Date
|
||||
.EE
|
||||
.IP
|
||||
whose data is available to the
|
||||
.IR mkd_doc_title ,
|
||||
.IR mkd_doc_author ,
|
||||
and
|
||||
.I mkd_doc_date
|
||||
(in
|
||||
.IR markdown (2))
|
||||
functions.
|
||||
.TP
|
||||
Embedded Stylesheets
|
||||
Stylesheets may be defined and modified in a
|
||||
.B <style>
|
||||
block. A style block is parsed like any other block-level
|
||||
.SM HTML;
|
||||
.B <style>
|
||||
starting on column 1, raw
|
||||
.SM HTML
|
||||
(or, in this case,
|
||||
.SM CSS \)
|
||||
following it, and either ending with a
|
||||
.B </style>
|
||||
at the end of the line or at the beginning of a subsequent line.
|
||||
.IP
|
||||
Style blocks apply to the entire document regardless of where they are defined.
|
||||
.TP
|
||||
Image Dimensions
|
||||
Image specification has been extended with an argument describing image dimensions:
|
||||
.BI = height x width.
|
||||
For an image 400 pixels high and 300 wide, the new syntax is:
|
||||
.IP
|
||||
.EX
|
||||

|
||||
.EE
|
||||
.TP
|
||||
Pseudo-Protocols
|
||||
Pseudo-protocols that may replace the common
|
||||
.B http:
|
||||
or
|
||||
.B mailto:
|
||||
have been added to the link syntax described above.
|
||||
.IP
|
||||
.BR abbr :
|
||||
Text following is used as the
|
||||
.B title
|
||||
attribute of an
|
||||
.B abbr
|
||||
tag wrapping the link text. So
|
||||
.B [LT](abbr:Link Text)
|
||||
gives
|
||||
.B <abbr title="Link Text">LT</abbr>.
|
||||
.IP
|
||||
.BR id :
|
||||
The link text is marked up and written to the output, wrapped with
|
||||
.B <a id=text following>
|
||||
and
|
||||
.BR </a> .
|
||||
.IP
|
||||
.BR class :
|
||||
The link text is marked up and written to the output, wrapped with
|
||||
.B <span class=text following>
|
||||
and
|
||||
.BR </span> .
|
||||
.IP
|
||||
.BR raw :
|
||||
Text following is written to the output with no further processing.
|
||||
The link text is discarded.
|
||||
.TP
|
||||
Alphabetic Lists
|
||||
If
|
||||
.I markdown
|
||||
was configured with
|
||||
.BR --enable-alpha-list ,
|
||||
.IP
|
||||
.EX
|
||||
a. this
|
||||
b. is
|
||||
c. an alphabetic
|
||||
d. list
|
||||
.EE
|
||||
.IP
|
||||
yields an
|
||||
.SM HTML
|
||||
.B ol
|
||||
ordered list.
|
||||
.TP
|
||||
Definition Lists
|
||||
If configured with
|
||||
.BR --enable-dl-tag ,
|
||||
markup for definition lists is enabled. A definition list item is defined as
|
||||
.IP
|
||||
.EX
|
||||
=term=
|
||||
definition
|
||||
.EE
|
||||
.TP
|
||||
Tables
|
||||
Tables are specified with a pipe
|
||||
.RB ( | )
|
||||
and dash
|
||||
.RB ( - )
|
||||
marking. The markdown text
|
||||
.IP
|
||||
.EX
|
||||
header0|header1
|
||||
-------|-------
|
||||
textA|textB
|
||||
textC|textD
|
||||
.EE
|
||||
.IP
|
||||
will produce an
|
||||
.SM HTML
|
||||
.B table
|
||||
of two columns and three rows.
|
||||
A header row is designated by ``underlining'' with dashes.
|
||||
Declare a column's alignment by affixing a colon
|
||||
.RB ( : )
|
||||
to the left or right end of the dashes underlining its header.
|
||||
In the output, this
|
||||
yields the corresponding value for the
|
||||
.B align
|
||||
attribute on each
|
||||
.B td
|
||||
cell in the column.
|
||||
A colon at both ends of a column's header dashes indicates center alignment.
|
||||
.TP
|
||||
Relaxed Emphasis
|
||||
If configured with
|
||||
.BR --relaxed-emphasis ,
|
||||
the rules for emphasis are changed so that a single
|
||||
.B _
|
||||
will not count as an emphasis character in the middle of a word.
|
||||
This is useful for documenting some code where
|
||||
.B _
|
||||
appears frequently, and would normally require a backslash escape.
|
||||
.PD
|
||||
.SH SEE ALSO
|
||||
.IR markdown (1),
|
||||
.IR markdown (2)
|
||||
.PP
|
||||
http://daringfireball.net/projects/markdown/syntax/,
|
||||
``Markdown: Syntax''.
|
||||
.PP
|
||||
http://daringfireball.net/projects/smartypants/,
|
||||
``Smarty Pants''.
|
||||
.PP
|
||||
http://michelf.com/projects/php-markdown/extra/#table,
|
||||
``PHP Markdown Extra: Tables''.
|
||||
@@ -0,0 +1,37 @@
|
||||
BIN=/$objtype/bin
|
||||
CC='cc -D_BSD_EXTENSION -D_C99_SNPRINTF_EXTENSION'
|
||||
|
||||
markdown:
|
||||
ape/psh -c 'cd .. && make'
|
||||
|
||||
none:V: markdown
|
||||
|
||||
test: markdown
|
||||
ape/psh -c 'cd ..&& make test'
|
||||
|
||||
install: markdown
|
||||
cp ../markdown $BIN/markdown
|
||||
|
||||
install.progs: install
|
||||
cp ../makepage $BIN/makepage
|
||||
cp ../mkd2html $BIN/mkd2html
|
||||
|
||||
install.libs: install
|
||||
cp ../mkdio.h /sys/include/ape/mkdio.h
|
||||
cp ../libmarkdown.a /$objtype/lib/ape/libmarkdown.a
|
||||
|
||||
install.man: install
|
||||
cp markdown.1 /sys/man/1/markdown
|
||||
cp markdown.2 /sys/man/2/markdown
|
||||
cp markdown.6 /sys/man/6/markdown
|
||||
|
||||
installall:V: install.libs install.man install.progs
|
||||
|
||||
config:
|
||||
ape/psh -c 'cd .. && ./configure.sh $CONFIG'
|
||||
|
||||
clean:
|
||||
ape/psh -c 'cd .. && make clean'
|
||||
|
||||
nuke:
|
||||
ape/psh -c 'cd .. && make distclean'
|
||||
@@ -0,0 +1,16 @@
|
||||
DISCOUNT is a implementation of John Gruber's Markdown markup
|
||||
language. It implements, as far as I can tell, all of the
|
||||
language as described in
|
||||
<http://daringfireball.net/projects/markdown/syntax>
|
||||
and passes the Markdown test suite at
|
||||
<http://daringfireball.net/projects/downloads/MarkdownTest_1.0.zip>
|
||||
|
||||
DISCOUNT is free software written by David Parsons <orc@pell.portland.or.us>;
|
||||
it is released under a BSD-style license that allows you to do
|
||||
as you wish with it as long as you don't attempt to claim it as
|
||||
your own work.
|
||||
|
||||
Most of the programs included in the DISCOUNT distribution have
|
||||
manual pages describing how they work.
|
||||
|
||||
The file INSTALL describes how to build and install discount
|
||||
@@ -0,0 +1 @@
|
||||
2.1.8
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* debugging malloc()/realloc()/calloc()/free() that attempts
|
||||
* to keep track of just what's been allocated today.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define MAGIC 0x1f2e3d4c
|
||||
|
||||
struct alist { int magic, size; struct alist *next, *last; };
|
||||
|
||||
static struct alist list = { 0, 0, 0, 0 };
|
||||
|
||||
static int mallocs=0;
|
||||
static int reallocs=0;
|
||||
static int frees=0;
|
||||
|
||||
void *
|
||||
acalloc(int size, int count)
|
||||
{
|
||||
struct alist *ret = calloc(size + sizeof(struct alist), count);
|
||||
|
||||
if ( ret ) {
|
||||
ret->magic = MAGIC;
|
||||
ret->size = size * count;
|
||||
if ( list.next ) {
|
||||
ret->next = list.next;
|
||||
ret->last = &list;
|
||||
ret->next->last = ret;
|
||||
list.next = ret;
|
||||
}
|
||||
else {
|
||||
ret->last = ret->next = &list;
|
||||
list.next = list.last = ret;
|
||||
}
|
||||
++mallocs;
|
||||
return ret+1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void*
|
||||
amalloc(int size)
|
||||
{
|
||||
return acalloc(size,1);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
afree(void *ptr)
|
||||
{
|
||||
struct alist *p2 = ((struct alist*)ptr)-1;
|
||||
|
||||
if ( p2->magic == MAGIC ) {
|
||||
p2->last->next = p2->next;
|
||||
p2->next->last = p2->last;
|
||||
++frees;
|
||||
free(p2);
|
||||
}
|
||||
else
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
arealloc(void *ptr, int size)
|
||||
{
|
||||
struct alist *p2 = ((struct alist*)ptr)-1;
|
||||
struct alist save;
|
||||
|
||||
if ( p2->magic == MAGIC ) {
|
||||
save.next = p2->next;
|
||||
save.last = p2->last;
|
||||
p2 = realloc(p2, sizeof(*p2) + size);
|
||||
|
||||
if ( p2 ) {
|
||||
p2->size = size;
|
||||
p2->next->last = p2;
|
||||
p2->last->next = p2;
|
||||
++reallocs;
|
||||
return p2+1;
|
||||
}
|
||||
else {
|
||||
save.next->last = save.last;
|
||||
save.last->next = save.next;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return realloc(ptr, size);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
adump()
|
||||
{
|
||||
struct alist *p;
|
||||
|
||||
|
||||
for ( p = list.next; p && (p != &list); p = p->next ) {
|
||||
fprintf(stderr, "allocated: %d byte%s\n", p->size, (p->size==1) ? "" : "s");
|
||||
fprintf(stderr, " [%.*s]\n", p->size, (char*)(p+1));
|
||||
}
|
||||
|
||||
if ( getenv("AMALLOC_STATISTICS") ) {
|
||||
fprintf(stderr, "%d malloc%s\n", mallocs, (mallocs==1)?"":"s");
|
||||
fprintf(stderr, "%d realloc%s\n", reallocs, (reallocs==1)?"":"s");
|
||||
fprintf(stderr, "%d free%s\n", frees, (frees==1)?"":"s");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* debugging malloc()/realloc()/calloc()/free() that attempts
|
||||
* to keep track of just what's been allocated today.
|
||||
*/
|
||||
#ifndef AMALLOC_D
|
||||
#define AMALLOC_D
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef USE_AMALLOC
|
||||
|
||||
extern void *amalloc(int);
|
||||
extern void *acalloc(int,int);
|
||||
extern void *arealloc(void*,int);
|
||||
extern void afree(void*);
|
||||
extern void adump();
|
||||
|
||||
#define malloc amalloc
|
||||
#define calloc acalloc
|
||||
#define realloc arealloc
|
||||
#define free afree
|
||||
|
||||
#else
|
||||
|
||||
#define adump() (void)1
|
||||
|
||||
#endif
|
||||
|
||||
#endif/*AMALLOC_D*/
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* mkdio -- markdown front end input functions
|
||||
*
|
||||
* Copyright (C) 2007 David L Parsons.
|
||||
* The redistribution terms are provided in the COPYRIGHT file that must
|
||||
* be distributed with this source code.
|
||||
*/
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "mkdio.h"
|
||||
#include "cstring.h"
|
||||
#include "amalloc.h"
|
||||
|
||||
static char *
|
||||
e_basename(const char *string, const int size, void *context)
|
||||
{
|
||||
char *ret;
|
||||
char *base = (char*)context;
|
||||
|
||||
if ( base && string && (*string == '/') && (ret=malloc(strlen(base)+size+2)) ) {
|
||||
strcpy(ret, base);
|
||||
strncat(ret, string, size);
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
e_free(char *string, void *context)
|
||||
{
|
||||
if ( string ) free(string);
|
||||
}
|
||||
|
||||
void
|
||||
mkd_basename(MMIOT *document, char *base)
|
||||
{
|
||||
mkd_e_url(document, e_basename);
|
||||
mkd_e_data(document, base);
|
||||
mkd_e_free(document, e_free);
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
static struct kw blocktags[] = {
|
||||
{ "P", 1, 0 },
|
||||
{ "DL", 2, 0 },
|
||||
{ "H1", 2, 0 },
|
||||
{ "H2", 2, 0 },
|
||||
{ "H3", 2, 0 },
|
||||
{ "H4", 2, 0 },
|
||||
{ "H5", 2, 0 },
|
||||
{ "H6", 2, 0 },
|
||||
{ "HR", 2, 1 },
|
||||
{ "OL", 2, 0 },
|
||||
{ "UL", 2, 0 },
|
||||
{ "BDO", 3, 0 },
|
||||
{ "DFN", 3, 0 },
|
||||
{ "DIV", 3, 0 },
|
||||
{ "MAP", 3, 0 },
|
||||
{ "PRE", 3, 0 },
|
||||
{ "WBR", 3, 0 },
|
||||
{ "XMP", 3, 0 },
|
||||
{ "NOBR", 4, 0 },
|
||||
{ "STYLE", 5, 0 },
|
||||
{ "TABLE", 5, 0 },
|
||||
{ "CENTER", 6, 0 },
|
||||
{ "IFRAME", 6, 0 },
|
||||
{ "OBJECT", 6, 0 },
|
||||
{ "SCRIPT", 6, 0 },
|
||||
{ "ADDRESS", 7, 0 },
|
||||
{ "LISTING", 7, 0 },
|
||||
{ "PLAINTEXT", 9, 0 },
|
||||
{ "BLOCKQUOTE", 10, 0 },
|
||||
};
|
||||
|
||||
#define NR_blocktags 29
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* configuration for markdown, generated Wed Apr 8 00:13:17 CDT 2015
|
||||
* by vino@achilleus.local
|
||||
*/
|
||||
#ifndef __AC_MARKDOWN_D
|
||||
#define __AC_MARKDOWN_D 1
|
||||
|
||||
|
||||
#define OS_DARWIN 1
|
||||
#define USE_DISCOUNT_DL 1
|
||||
#define while(x) while( (x) != 0 )
|
||||
#define if(x) if( (x) != 0 )
|
||||
#define DWORD unsigned int
|
||||
#define WORD unsigned short
|
||||
#define BYTE unsigned char
|
||||
#define HAVE_PWD_H 1
|
||||
#define HAVE_GETPWUID 1
|
||||
#define HAVE_SRANDOM 1
|
||||
#define INITRNG(x) srandom((unsigned int)x)
|
||||
#define HAVE_BZERO 1
|
||||
#define HAVE_RANDOM 1
|
||||
#define COINTOSS() (random()&1)
|
||||
#define HAVE_STRCASECMP 1
|
||||
#define HAVE_STRNCASECMP 1
|
||||
#define HAVE_FCHDIR 1
|
||||
#define TABSTOP 4
|
||||
#define PATH_FIND "/usr/bin/find"
|
||||
#define PATH_SED "/usr/bin/sed"
|
||||
|
||||
#endif/* __AC_MARKDOWN_D */
|
||||
Executable
+1734
File diff suppressed because it is too large
Load Diff
Executable
+166
@@ -0,0 +1,166 @@
|
||||
#! /bin/sh
|
||||
|
||||
# local options: ac_help is the help message that describes them
|
||||
# and LOCAL_AC_OPTIONS is the script that interprets them. LOCAL_AC_OPTIONS
|
||||
# is a script that's processed with eval, so you need to be very careful to
|
||||
# make certain that what you quote is what you want to quote.
|
||||
|
||||
# load in the configuration file
|
||||
#
|
||||
ac_help='--enable-amalloc Enable memory allocation debugging
|
||||
--with-tabstops=N Set tabstops to N characters (default is 4)
|
||||
--with-dl=X Use Discount, Extra, or Both types of definition list
|
||||
--with-id-anchor Use id= anchors for table-of-contents links
|
||||
--with-github-tags Allow `_` and `-` in <> tags
|
||||
--with-fenced-code Allow fenced code blocks
|
||||
--with-urlencoded-anchor Use url-encoded chars to multibyte chars in toc links
|
||||
--enable-all-features Turn on all stable optional features
|
||||
--shared Build shared libraries (default is static)'
|
||||
|
||||
LOCAL_AC_OPTIONS='
|
||||
set=`locals $*`;
|
||||
if [ "$set" ]; then
|
||||
eval $set
|
||||
shift 1
|
||||
else
|
||||
ac_error=T;
|
||||
fi'
|
||||
|
||||
locals() {
|
||||
K=`echo $1 | $AC_UPPERCASE`
|
||||
case "$K" in
|
||||
--SHARED)
|
||||
echo TRY_SHARED=T
|
||||
;;
|
||||
--ENABLE-ALL|--ENABLE-ALL-FEATURES)
|
||||
echo WITH_AMALLOC=T
|
||||
;;
|
||||
--ENABLE-*) enable=`echo $K | sed -e 's/--ENABLE-//' | tr '-' '_'`
|
||||
echo WITH_${enable}=T ;;
|
||||
--DEBIAN-GLITCH)
|
||||
echo DEBIAN_GLITCH=T
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
TARGET=markdown
|
||||
. ./configure.inc
|
||||
|
||||
AC_INIT $TARGET
|
||||
|
||||
__DL=`echo "$WITH_DL" | $AC_UPPERCASE`
|
||||
|
||||
case "$__DL" in
|
||||
EXTRA) AC_DEFINE 'USE_EXTRA_DL' 1 ;;
|
||||
DISCOUNT|1|"") AC_DEFINE 'USE_DISCOUNT_DL' 1 ;;
|
||||
BOTH) AC_DEFINE 'USE_EXTRA_DL' 1
|
||||
AC_DEFINE 'USE_DISCOUNT_DL' 1 ;;
|
||||
*) AC_FAIL "Unknown value <$WITH_DL> for --with-dl (want 'discount', 'extra', or 'both')" ;;
|
||||
esac
|
||||
|
||||
test "$WITH_FENCED_CODE" && AC_DEFINE "WITH_FENCED_CODE" 1
|
||||
test "$WITH_ID_ANCHOR" && AC_DEFINE 'WITH_ID_ANCHOR' 1
|
||||
test "$WITH_GITHUB_TAGS" && AC_DEFINE 'WITH_GITHUB_TAGS' 1
|
||||
test "$WITH_URLENCODED_ANCHOR" && AC_DEFINE 'WITH_URLENCODED_ANCHOR' 1
|
||||
test "$DEBIAN_GLITCH" && AC_DEFINE 'DEBIAN_GLITCH' 1
|
||||
|
||||
AC_PROG_CC
|
||||
|
||||
test "$TRY_SHARED" && AC_COMPILER_PIC && AC_CC_SHLIBS
|
||||
|
||||
if [ "IS_BROKEN_CC" ]; then
|
||||
case "$AC_CC $AC_CFLAGS" in
|
||||
*-pedantic*) ;;
|
||||
*) # hack around deficiencies in gcc and clang
|
||||
#
|
||||
AC_DEFINE 'while(x)' 'while( (x) != 0 )'
|
||||
AC_DEFINE 'if(x)' 'if( (x) != 0 )'
|
||||
|
||||
if [ "$IS_CLANG" ]; then
|
||||
AC_CC="$AC_CC -Wno-implicit-int"
|
||||
elif [ "$IS_GCC" ]; then
|
||||
AC_CC="$AC_CC -Wno-return-type -Wno-implicit-int"
|
||||
fi ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
AC_PROG ar || AC_FAIL "$TARGET requires ar"
|
||||
AC_PROG ranlib
|
||||
|
||||
AC_C_VOLATILE
|
||||
AC_C_CONST
|
||||
AC_C_INLINE
|
||||
AC_SCALAR_TYPES sub hdr
|
||||
AC_CHECK_BASENAME
|
||||
|
||||
AC_CHECK_HEADERS sys/types.h pwd.h && AC_CHECK_FUNCS getpwuid
|
||||
|
||||
if AC_CHECK_FUNCS srandom; then
|
||||
AC_DEFINE 'INITRNG(x)' 'srandom((unsigned int)x)'
|
||||
elif AC_CHECK_FUNCS srand; then
|
||||
AC_DEFINE 'INITRNG(x)' 'srand((unsigned int)x)'
|
||||
else
|
||||
AC_DEFINE 'INITRNG(x)' '(void)1'
|
||||
fi
|
||||
|
||||
if AC_CHECK_FUNCS 'bzero((char*)0,0)'; then
|
||||
: # Yay
|
||||
elif AC_CHECK_FUNCS 'memset((char*)0,0,0)'; then
|
||||
AC_DEFINE 'bzero(p,s)' 'memset(p,s,0)'
|
||||
else
|
||||
AC_FAIL "$TARGET requires bzero or memset"
|
||||
fi
|
||||
|
||||
if AC_CHECK_FUNCS random; then
|
||||
AC_DEFINE 'COINTOSS()' '(random()&1)'
|
||||
elif AC_CHECK_FUNCS rand; then
|
||||
AC_DEFINE 'COINTOSS()' '(rand()&1)'
|
||||
else
|
||||
AC_DEFINE 'COINTOSS()' '1'
|
||||
fi
|
||||
|
||||
if AC_CHECK_FUNCS strcasecmp; then
|
||||
:
|
||||
elif AC_CHECK_FUNCS stricmp; then
|
||||
AC_DEFINE strcasecmp stricmp
|
||||
else
|
||||
AC_FAIL "$TARGET requires either strcasecmp() or stricmp()"
|
||||
fi
|
||||
|
||||
if AC_CHECK_FUNCS strncasecmp; then
|
||||
:
|
||||
elif AC_CHECK_FUNCS strnicmp; then
|
||||
AC_DEFINE strncasecmp strnicmp
|
||||
else
|
||||
AC_FAIL "$TARGET requires either strncasecmp() or strnicmp()"
|
||||
fi
|
||||
|
||||
if AC_CHECK_FUNCS fchdir || AC_CHECK_FUNCS getcwd ; then
|
||||
AC_SUB 'THEME' ''
|
||||
else
|
||||
AC_SUB 'THEME' '#'
|
||||
fi
|
||||
|
||||
if [ -z "$WITH_TABSTOPS" ]; then
|
||||
TABSTOP=4
|
||||
elif [ "$WITH_TABSTOPS" -eq 1 ]; then
|
||||
TABSTOP=8
|
||||
else
|
||||
TABSTOP=$WITH_TABSTOPS
|
||||
fi
|
||||
AC_DEFINE 'TABSTOP' $TABSTOP
|
||||
AC_SUB 'TABSTOP' $TABSTOP
|
||||
|
||||
|
||||
if [ "$WITH_AMALLOC" ]; then
|
||||
AC_DEFINE 'USE_AMALLOC' 1
|
||||
AC_SUB 'AMALLOC' 'amalloc.o'
|
||||
else
|
||||
AC_SUB 'AMALLOC' ''
|
||||
fi
|
||||
|
||||
[ "$OS_FREEBSD" -o "$OS_DRAGONFLY" ] || AC_CHECK_HEADERS malloc.h
|
||||
|
||||
[ "$WITH_PANDOC_HEADER" ] && AC_DEFINE 'PANDOC_HEADER' '1'
|
||||
|
||||
AC_OUTPUT Makefile version.c mkdio.h
|
||||
@@ -0,0 +1,85 @@
|
||||
/* markdown: a C implementation of John Gruber's Markdown markup language.
|
||||
*
|
||||
* Copyright (C) 2009 David L Parsons.
|
||||
* The redistribution terms are provided in the COPYRIGHT file that must
|
||||
* be distributed with this source code.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "cstring.h"
|
||||
#include "markdown.h"
|
||||
#include "amalloc.h"
|
||||
|
||||
|
||||
/*
|
||||
* dump out stylesheet sections.
|
||||
*/
|
||||
static void
|
||||
stylesheets(Paragraph *p, Cstring *f)
|
||||
{
|
||||
Line* q;
|
||||
|
||||
for ( ; p ; p = p->next ) {
|
||||
if ( p->typ == STYLE ) {
|
||||
for ( q = p->text; q ; q = q->next ) {
|
||||
Cswrite(f, T(q->text), S(q->text));
|
||||
Csputc('\n', f);
|
||||
}
|
||||
}
|
||||
if ( p->down )
|
||||
stylesheets(p->down, f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* dump any embedded styles to a string
|
||||
*/
|
||||
int
|
||||
mkd_css(Document *d, char **res)
|
||||
{
|
||||
Cstring f;
|
||||
int size;
|
||||
|
||||
if ( res && d && d->compiled ) {
|
||||
*res = 0;
|
||||
CREATE(f);
|
||||
RESERVE(f, 100);
|
||||
stylesheets(d->code, &f);
|
||||
|
||||
if ( (size = S(f)) > 0 ) {
|
||||
EXPAND(f) = 0;
|
||||
/* HACK ALERT! HACK ALERT! HACK ALERT! */
|
||||
*res = T(f);/* we know that a T(Cstring) is a character pointer */
|
||||
/* so we can simply pick it up and carry it away, */
|
||||
/* leaving the husk of the Ctring on the stack */
|
||||
/* END HACK ALERT */
|
||||
}
|
||||
else
|
||||
DELETE(f);
|
||||
return size;
|
||||
}
|
||||
return EOF;
|
||||
}
|
||||
|
||||
|
||||
/* dump any embedded styles to a file
|
||||
*/
|
||||
int
|
||||
mkd_generatecss(Document *d, FILE *f)
|
||||
{
|
||||
char *res;
|
||||
int written = EOF, size = mkd_css(d, &res);
|
||||
|
||||
if ( size > 0 )
|
||||
written = fwrite(res, 1, size, f);
|
||||
if ( res )
|
||||
free(res);
|
||||
return (written == size) ? size : EOF;
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/* two template types: STRING(t) which defines a pascal-style string
|
||||
* of element (t) [STRING(char) is the closest to the pascal string],
|
||||
* and ANCHOR(t) which defines a baseplate that a linked list can be
|
||||
* built up from. [The linked list /must/ contain a ->next pointer
|
||||
* for linking the list together with.]
|
||||
*/
|
||||
#ifndef _CSTRING_D
|
||||
#define _CSTRING_D
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef __WITHOUT_AMALLOC
|
||||
# include "amalloc.h"
|
||||
#endif
|
||||
|
||||
/* expandable Pascal-style string.
|
||||
*/
|
||||
#define STRING(type) struct { type *text; int size, alloc; }
|
||||
|
||||
#define CREATE(x) ( (T(x) = (void*)0), (S(x) = (x).alloc = 0) )
|
||||
#define EXPAND(x) (S(x)++)[(S(x) < (x).alloc) \
|
||||
? (T(x)) \
|
||||
: (T(x) = T(x) ? realloc(T(x), sizeof T(x)[0] * ((x).alloc += 100)) \
|
||||
: malloc(sizeof T(x)[0] * ((x).alloc += 100)) )]
|
||||
|
||||
#define DELETE(x) ALLOCATED(x) ? (free(T(x)), S(x) = (x).alloc = 0) \
|
||||
: ( S(x) = 0 )
|
||||
#define CLIP(t,i,sz) \
|
||||
S(t) -= ( ((i) >= 0) && ((sz) > 0) && (((i)+(sz)) <= S(t)) ) ? \
|
||||
(memmove(&T(t)[i], &T(t)[i+sz], (S(t)-(i+sz)+1)*sizeof(T(t)[0])), \
|
||||
(sz)) : 0
|
||||
|
||||
#define RESERVE(x, sz) T(x) = ((x).alloc > S(x) + (sz) \
|
||||
? T(x) \
|
||||
: T(x) \
|
||||
? realloc(T(x), sizeof T(x)[0] * ((x).alloc = 100+(sz)+S(x))) \
|
||||
: malloc(sizeof T(x)[0] * ((x).alloc = 100+(sz)+S(x))))
|
||||
#define SUFFIX(t,p,sz) \
|
||||
memcpy(((S(t) += (sz)) - (sz)) + \
|
||||
(T(t) = T(t) ? realloc(T(t), sizeof T(t)[0] * ((t).alloc += sz)) \
|
||||
: malloc(sizeof T(t)[0] * ((t).alloc += sz))), \
|
||||
(p), sizeof(T(t)[0])*(sz))
|
||||
|
||||
#define PREFIX(t,p,sz) \
|
||||
RESERVE( (t), (sz) ); \
|
||||
if ( S(t) ) { memmove(T(t)+(sz), T(t), S(t)); } \
|
||||
memcpy( T(t), (p), (sz) ); \
|
||||
S(t) += (sz)
|
||||
|
||||
/* reference-style links (and images) are stored in an array
|
||||
*/
|
||||
#define T(x) (x).text
|
||||
#define S(x) (x).size
|
||||
#define ALLOCATED(x) (x).alloc
|
||||
|
||||
/* abstract anchor type that defines a list base
|
||||
* with a function that attaches an element to
|
||||
* the end of the list.
|
||||
*
|
||||
* the list base field is named .text so that the T()
|
||||
* macro will work with it.
|
||||
*/
|
||||
#define ANCHOR(t) struct { t *text, *end; }
|
||||
#define E(t) ((t).end)
|
||||
|
||||
#define ATTACH(t, p) ( T(t) ? ( (E(t)->next = (p)), (E(t) = (p)) ) \
|
||||
: ( (T(t) = E(t) = (p)) ) )
|
||||
|
||||
typedef STRING(char) Cstring;
|
||||
|
||||
extern void Csputc(int, Cstring *);
|
||||
extern int Csprintf(Cstring *, char *, ...);
|
||||
extern int Cswrite(Cstring *, char *, int);
|
||||
extern void Csreparse(Cstring *, char *, int, int);
|
||||
|
||||
#endif/*_CSTRING_D*/
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* docheader -- get values from the document header
|
||||
*
|
||||
* Copyright (C) 2007 David L Parsons.
|
||||
* The redistribution terms are provided in the COPYRIGHT file that must
|
||||
* be distributed with this source code.
|
||||
*/
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "cstring.h"
|
||||
#include "markdown.h"
|
||||
#include "amalloc.h"
|
||||
|
||||
static char *
|
||||
onlyifset(Line *l)
|
||||
{
|
||||
char *ret = T(l->text) + l->dle;
|
||||
|
||||
return ret[0] ? ret : 0;
|
||||
}
|
||||
|
||||
char *
|
||||
mkd_doc_title(Document *doc)
|
||||
{
|
||||
if ( doc && doc->title )
|
||||
return onlyifset(doc->title);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
mkd_doc_author(Document *doc)
|
||||
{
|
||||
if ( doc && doc->author )
|
||||
return onlyifset(doc->author);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
mkd_doc_date(Document *doc)
|
||||
{
|
||||
if ( doc && doc->date )
|
||||
return onlyifset(doc->date);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
/* markdown: a C implementation of John Gruber's Markdown markup language.
|
||||
*
|
||||
* Copyright (C) 2007 David L Parsons.
|
||||
* The redistribution terms are provided in the COPYRIGHT file that must
|
||||
* be distributed with this source code.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include "markdown.h"
|
||||
#include "cstring.h"
|
||||
#include "amalloc.h"
|
||||
|
||||
struct frame {
|
||||
int indent;
|
||||
char c;
|
||||
};
|
||||
|
||||
typedef STRING(struct frame) Stack;
|
||||
|
||||
static char *
|
||||
Pptype(int typ)
|
||||
{
|
||||
switch (typ) {
|
||||
case WHITESPACE: return "whitespace";
|
||||
case CODE : return "code";
|
||||
case QUOTE : return "quote";
|
||||
case MARKUP : return "markup";
|
||||
case HTML : return "html";
|
||||
case DL : return "dl";
|
||||
case UL : return "ul";
|
||||
case OL : return "ol";
|
||||
case LISTITEM : return "item";
|
||||
case HDR : return "header";
|
||||
case HR : return "hr";
|
||||
case TABLE : return "table";
|
||||
case SOURCE : return "source";
|
||||
case STYLE : return "style";
|
||||
default : return "mystery node!";
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
pushpfx(int indent, char c, Stack *sp)
|
||||
{
|
||||
struct frame *q = &EXPAND(*sp);
|
||||
|
||||
q->indent = indent;
|
||||
q->c = c;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
poppfx(Stack *sp)
|
||||
{
|
||||
S(*sp)--;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
changepfx(Stack *sp, char c)
|
||||
{
|
||||
char ch;
|
||||
|
||||
if ( !S(*sp) ) return;
|
||||
|
||||
ch = T(*sp)[S(*sp)-1].c;
|
||||
|
||||
if ( ch == '+' || ch == '|' )
|
||||
T(*sp)[S(*sp)-1].c = c;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
printpfx(Stack *sp, FILE *f)
|
||||
{
|
||||
int i;
|
||||
char c;
|
||||
|
||||
if ( !S(*sp) ) return;
|
||||
|
||||
c = T(*sp)[S(*sp)-1].c;
|
||||
|
||||
if ( c == '+' || c == '-' ) {
|
||||
fprintf(f, "--%c", c);
|
||||
T(*sp)[S(*sp)-1].c = (c == '-') ? ' ' : '|';
|
||||
}
|
||||
else
|
||||
for ( i=0; i < S(*sp); i++ ) {
|
||||
if ( i )
|
||||
fprintf(f, " ");
|
||||
fprintf(f, "%*s%c", T(*sp)[i].indent + 2, " ", T(*sp)[i].c);
|
||||
if ( T(*sp)[i].c == '`' )
|
||||
T(*sp)[i].c = ' ';
|
||||
}
|
||||
fprintf(f, "--");
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
dumptree(Paragraph *pp, Stack *sp, FILE *f)
|
||||
{
|
||||
int count;
|
||||
Line *p;
|
||||
int d;
|
||||
static char *Begin[] = { 0, "P", "center" };
|
||||
|
||||
while ( pp ) {
|
||||
if ( !pp->next )
|
||||
changepfx(sp, '`');
|
||||
printpfx(sp, f);
|
||||
|
||||
d = fprintf(f, "[%s", Pptype(pp->typ));
|
||||
if ( pp->ident )
|
||||
d += fprintf(f, " %s", pp->ident);
|
||||
if ( pp->align > 1 )
|
||||
d += fprintf(f, ", <%s>", Begin[pp->align]);
|
||||
|
||||
for (count=0, p=pp->text; p; ++count, (p = p->next) )
|
||||
;
|
||||
|
||||
if ( count )
|
||||
d += fprintf(f, ", %d line%s", count, (count==1)?"":"s");
|
||||
|
||||
d += fprintf(f, "]");
|
||||
|
||||
if ( pp->down ) {
|
||||
pushpfx(d, pp->down->next ? '+' : '-', sp);
|
||||
dumptree(pp->down, sp, f);
|
||||
poppfx(sp);
|
||||
}
|
||||
else fputc('\n', f);
|
||||
pp = pp->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
mkd_dump(Document *doc, FILE *out, int flags, char *title)
|
||||
{
|
||||
Stack stack;
|
||||
|
||||
if (mkd_compile(doc, flags) ) {
|
||||
|
||||
CREATE(stack);
|
||||
pushpfx(fprintf(out, "%s", title), doc->code->next ? '+' : '-', &stack);
|
||||
dumptree(doc->code, &stack, out);
|
||||
DELETE(stack);
|
||||
|
||||
mkd_cleanup(doc);
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@@ -0,0 +1,188 @@
|
||||
/* markdown: a C implementation of John Gruber's Markdown markup language.
|
||||
*
|
||||
* Copyright (C) 2010 David L Parsons.
|
||||
* The redistribution terms are provided in the COPYRIGHT file that must
|
||||
* be distributed with this source code.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "cstring.h"
|
||||
#include "markdown.h"
|
||||
#include "amalloc.h"
|
||||
|
||||
|
||||
/* emmatch: the emphasis mangler that's run after a block
|
||||
* of html has been generated.
|
||||
*
|
||||
* It should create MarkdownTest_1.0 (and _1.0.3)
|
||||
* compatible emphasis for non-pathological cases
|
||||
* and it should fail in a standards-compliant way
|
||||
* when someone attempts to feed it junk.
|
||||
*
|
||||
* Emmatching is done after the input has been
|
||||
* processed into a STRING (f->Q) of text and
|
||||
* emphasis blocks. After ___mkd_emblock() finishes,
|
||||
* it truncates f->Q and leaves the rendered paragraph
|
||||
* if f->out.
|
||||
*/
|
||||
|
||||
|
||||
/* empair() -- find the NEAREST matching emphasis token (or
|
||||
* subtoken of a 3+ long emphasis token.
|
||||
*/
|
||||
static int
|
||||
empair(MMIOT *f, int first, int last, int match)
|
||||
{
|
||||
|
||||
int i;
|
||||
block *begin, *p;
|
||||
|
||||
begin = &T(f->Q)[first];
|
||||
|
||||
for (i=first+1; i <= last; i++) {
|
||||
p = &T(f->Q)[i];
|
||||
|
||||
if ( (p->b_type != bTEXT) && (p->b_count <= 0) )
|
||||
continue; /* break? */
|
||||
|
||||
if ( p->b_type == begin->b_type ) {
|
||||
if ( p->b_count == match ) /* exact match */
|
||||
return i;
|
||||
|
||||
if ( p->b_count > 2 ) /* fuzzy match */
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
} /* empair */
|
||||
|
||||
|
||||
/* emfill() -- if an emphasis token has leftover stars or underscores,
|
||||
* convert them back into character and append them to b_text.
|
||||
*/
|
||||
static void
|
||||
emfill(block *p)
|
||||
{
|
||||
int j;
|
||||
|
||||
if ( p->b_type == bTEXT )
|
||||
return;
|
||||
|
||||
for (j=0; j < p->b_count; j++)
|
||||
EXPAND(p->b_text) = p->b_char;
|
||||
p->b_count = 0;
|
||||
} /* emfill */
|
||||
|
||||
|
||||
static void
|
||||
emclose(MMIOT *f, int first, int last)
|
||||
{
|
||||
int j;
|
||||
|
||||
for (j=first+1; j<last-1; j++)
|
||||
emfill(&T(f->Q)[j]);
|
||||
}
|
||||
|
||||
|
||||
static struct emtags {
|
||||
char open[10];
|
||||
char close[10];
|
||||
int size;
|
||||
} emtags[] = { { "<em>" , "</em>", 5 }, { "<strong>", "</strong>", 9 } };
|
||||
|
||||
|
||||
static void emblock(MMIOT*,int,int);
|
||||
|
||||
|
||||
/* emmatch() -- match emphasis for a single emphasis token.
|
||||
*/
|
||||
static void
|
||||
emmatch(MMIOT *f, int first, int last)
|
||||
{
|
||||
block *start = &T(f->Q)[first];
|
||||
int e, e2, match;
|
||||
|
||||
switch (start->b_count) {
|
||||
case 2: if ( e = empair(f,first,last,match=2) )
|
||||
break;
|
||||
case 1: e = empair(f,first,last,match=1);
|
||||
break;
|
||||
case 0: return;
|
||||
default:
|
||||
e = empair(f,first,last,1);
|
||||
e2= empair(f,first,last,2);
|
||||
|
||||
if ( e2 >= e ) {
|
||||
e = e2;
|
||||
match = 2;
|
||||
}
|
||||
else
|
||||
match = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( e ) {
|
||||
/* if we found emphasis to match, match it, recursively call
|
||||
* emblock to match emphasis inside the new html block, add
|
||||
* the emphasis markers for the block, then (tail) recursively
|
||||
* call ourself to match any remaining emphasis on this token.
|
||||
*/
|
||||
block *end = &T(f->Q)[e];
|
||||
|
||||
end->b_count -= match;
|
||||
start->b_count -= match;
|
||||
|
||||
emblock(f, first, e);
|
||||
|
||||
PREFIX(start->b_text, emtags[match-1].open, emtags[match-1].size-1);
|
||||
SUFFIX(end->b_post, emtags[match-1].close, emtags[match-1].size);
|
||||
|
||||
emmatch(f, first, last);
|
||||
}
|
||||
} /* emmatch */
|
||||
|
||||
|
||||
/* emblock() -- walk a blocklist, attempting to match emphasis
|
||||
*/
|
||||
static void
|
||||
emblock(MMIOT *f, int first, int last)
|
||||
{
|
||||
int i;
|
||||
|
||||
for ( i = first; i <= last; i++ )
|
||||
if ( T(f->Q)[i].b_type != bTEXT )
|
||||
emmatch(f, i, last);
|
||||
emclose(f, first, last);
|
||||
} /* emblock */
|
||||
|
||||
|
||||
/* ___mkd_emblock() -- emblock a string of blocks, then concatenate the
|
||||
* resulting text onto f->out.
|
||||
*/
|
||||
void
|
||||
___mkd_emblock(MMIOT *f)
|
||||
{
|
||||
int i;
|
||||
block *p;
|
||||
|
||||
emblock(f, 0, S(f->Q)-1);
|
||||
|
||||
for (i=0; i < S(f->Q); i++) {
|
||||
p = &T(f->Q)[i];
|
||||
emfill(p);
|
||||
|
||||
if ( S(p->b_post) ) { SUFFIX(f->out, T(p->b_post), S(p->b_post));
|
||||
DELETE(p->b_post); }
|
||||
if ( S(p->b_text) ) { SUFFIX(f->out, T(p->b_text), S(p->b_text));
|
||||
DELETE(p->b_text); }
|
||||
}
|
||||
|
||||
S(f->Q) = 0;
|
||||
} /* ___mkd_emblock */
|
||||
@@ -0,0 +1,85 @@
|
||||
#include <stdio.h>
|
||||
#include "markdown.h"
|
||||
|
||||
struct flagnames {
|
||||
DWORD flag;
|
||||
char *name;
|
||||
};
|
||||
|
||||
static struct flagnames flagnames[] = {
|
||||
{ MKD_NOLINKS, "!LINKS" },
|
||||
{ MKD_NOIMAGE, "!IMAGE" },
|
||||
{ MKD_NOPANTS, "!PANTS" },
|
||||
{ MKD_NOHTML, "!HTML" },
|
||||
{ MKD_STRICT, "STRICT" },
|
||||
{ MKD_TAGTEXT, "TAGTEXT" },
|
||||
{ MKD_NO_EXT, "!EXT" },
|
||||
{ MKD_CDATA, "CDATA" },
|
||||
{ MKD_NOSUPERSCRIPT, "!SUPERSCRIPT" },
|
||||
{ MKD_NORELAXED, "!RELAXED" },
|
||||
{ MKD_NOTABLES, "!TABLES" },
|
||||
{ MKD_NOSTRIKETHROUGH,"!STRIKETHROUGH" },
|
||||
{ MKD_TOC, "TOC" },
|
||||
{ MKD_1_COMPAT, "MKD_1_COMPAT" },
|
||||
{ MKD_AUTOLINK, "AUTOLINK" },
|
||||
{ MKD_SAFELINK, "SAFELINK" },
|
||||
{ MKD_NOHEADER, "!HEADER" },
|
||||
{ MKD_TABSTOP, "TABSTOP" },
|
||||
{ MKD_NODIVQUOTE, "!DIVQUOTE" },
|
||||
{ MKD_NOALPHALIST, "!ALPHALIST" },
|
||||
{ MKD_NODLIST, "!DLIST" },
|
||||
{ MKD_EXTRA_FOOTNOTE, "FOOTNOTE" },
|
||||
{ MKD_NOSTYLE, "!STYLE" },
|
||||
};
|
||||
#define NR(x) (sizeof x/sizeof x[0])
|
||||
|
||||
|
||||
void
|
||||
mkd_flags_are(FILE *f, DWORD flags, int htmlplease)
|
||||
{
|
||||
int i;
|
||||
int not, set, even=1;
|
||||
char *name;
|
||||
|
||||
if ( htmlplease )
|
||||
fprintf(f, "<table class=\"mkd_flags_are\">\n");
|
||||
for (i=0; i < NR(flagnames); i++) {
|
||||
set = flags & flagnames[i].flag;
|
||||
name = flagnames[i].name;
|
||||
if ( not = (*name == '!') ) {
|
||||
++name;
|
||||
set = !set;
|
||||
}
|
||||
|
||||
if ( htmlplease ) {
|
||||
if ( even ) fprintf(f, " <tr>");
|
||||
fprintf(f, "<td>");
|
||||
}
|
||||
else
|
||||
fputc(' ', f);
|
||||
|
||||
if ( !set )
|
||||
fprintf(f, htmlplease ? "<s>" : "!");
|
||||
|
||||
fprintf(f, "%s", name);
|
||||
|
||||
if ( htmlplease ) {
|
||||
if ( !set )
|
||||
fprintf(f, "</s>");
|
||||
fprintf(f, "</td>");
|
||||
if ( !even ) fprintf(f, "</tr>\n");
|
||||
}
|
||||
even = !even;
|
||||
}
|
||||
if ( htmlplease ) {
|
||||
if ( even ) fprintf(f, "</tr>\n");
|
||||
fprintf(f, "</table>\n");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
mkd_mmiot_flags(FILE *f, MMIOT *m, int htmlplease)
|
||||
{
|
||||
if ( m )
|
||||
mkd_flags_are(f, m->flags, htmlplease);
|
||||
}
|
||||
+1827
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,100 @@
|
||||
|
||||
/*
|
||||
* github_flavoured -- implement the obnoxious "returns are hard newlines"
|
||||
* feature in github flavoured markdown.
|
||||
*
|
||||
* Copyright (C) 2012 David L Parsons.
|
||||
* The redistribution terms are provided in the COPYRIGHT file that must
|
||||
* be distributed with this source code.
|
||||
*/
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "cstring.h"
|
||||
#include "markdown.h"
|
||||
#include "amalloc.h"
|
||||
|
||||
/* build a Document from any old input.
|
||||
*/
|
||||
typedef int (*getc_func)(void*);
|
||||
|
||||
Document *
|
||||
gfm_populate(getc_func getc, void* ctx, int flags)
|
||||
{
|
||||
Cstring line;
|
||||
Document *a = __mkd_new_Document();
|
||||
int c;
|
||||
int pandoc = 0;
|
||||
|
||||
if ( !a ) return 0;
|
||||
|
||||
a->tabstop = (flags & MKD_TABSTOP) ? 4 : TABSTOP;
|
||||
|
||||
CREATE(line);
|
||||
|
||||
while ( (c = (*getc)(ctx)) != EOF ) {
|
||||
if ( c == '\n' ) {
|
||||
if ( pandoc != EOF && pandoc < 3 ) {
|
||||
if ( S(line) && (T(line)[0] == '%') )
|
||||
pandoc++;
|
||||
else
|
||||
pandoc = EOF;
|
||||
}
|
||||
|
||||
if (pandoc == EOF) {
|
||||
EXPAND(line) = ' ';
|
||||
EXPAND(line) = ' ';
|
||||
}
|
||||
__mkd_enqueue(a, &line);
|
||||
S(line) = 0;
|
||||
}
|
||||
else if ( isprint(c) || isspace(c) || (c & 0x80) )
|
||||
EXPAND(line) = c;
|
||||
}
|
||||
|
||||
if ( S(line) )
|
||||
__mkd_enqueue(a, &line);
|
||||
|
||||
DELETE(line);
|
||||
|
||||
if ( (pandoc == 3) && !(flags & (MKD_NOHEADER|MKD_STRICT)) ) {
|
||||
/* the first three lines started with %, so we have a header.
|
||||
* clip the first three lines out of content and hang them
|
||||
* off header.
|
||||
*/
|
||||
Line *headers = T(a->content);
|
||||
|
||||
a->title = headers; __mkd_header_dle(a->title);
|
||||
a->author= headers->next; __mkd_header_dle(a->author);
|
||||
a->date = headers->next->next; __mkd_header_dle(a->date);
|
||||
|
||||
T(a->content) = headers->next->next->next;
|
||||
}
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
/* convert a block of text into a linked list
|
||||
*/
|
||||
Document *
|
||||
gfm_string(const char *buf, int len, DWORD flags)
|
||||
{
|
||||
struct string_stream about;
|
||||
|
||||
about.data = buf;
|
||||
about.size = len;
|
||||
|
||||
return gfm_populate((getc_func)__mkd_io_strget, &about, flags & INPUT_MASK);
|
||||
}
|
||||
|
||||
|
||||
/* convert a file into a linked list
|
||||
*/
|
||||
Document *
|
||||
gfm_in(FILE *f, DWORD flags)
|
||||
{
|
||||
return gfm_populate((getc_func)fgetc, f, flags & INPUT_MASK);
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
/* block-level tags for passing html5 blocks through the blender
|
||||
*/
|
||||
#include "tags.h"
|
||||
|
||||
void
|
||||
mkd_with_html5_tags()
|
||||
{
|
||||
static int populated = 0;
|
||||
|
||||
if ( populated ) return;
|
||||
populated = 1;
|
||||
|
||||
mkd_define_tag("ASIDE", 0);
|
||||
mkd_define_tag("FOOTER", 0);
|
||||
mkd_define_tag("HEADER", 0);
|
||||
mkd_define_tag("HGROUP", 0);
|
||||
mkd_define_tag("NAV", 0);
|
||||
mkd_define_tag("SECTION", 0);
|
||||
mkd_define_tag("ARTICLE", 0);
|
||||
|
||||
mkd_sort_tags();
|
||||
}
|
||||
+216
@@ -0,0 +1,216 @@
|
||||
/*
|
||||
* markdown: convert a single markdown document into html
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2007 David L Parsons.
|
||||
* The redistribution terms are provided in the COPYRIGHT file that must
|
||||
* be distributed with this source code.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
#include <unistd.h>
|
||||
#include <mkdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "amalloc.h"
|
||||
#include "pgm_options.h"
|
||||
#include "tags.h"
|
||||
|
||||
#if HAVE_LIBGEN_H
|
||||
#include <libgen.h>
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_BASENAME
|
||||
#include <string.h>
|
||||
|
||||
char*
|
||||
basename(char *p)
|
||||
{
|
||||
char *ret = strrchr(p, '/');
|
||||
|
||||
return ret ? (1+ret) : p;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
char *pgm = "markdown";
|
||||
|
||||
char *
|
||||
e_flags(const char *text, const int size, void *context)
|
||||
{
|
||||
return (char*)context;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
complain(char *fmt, ...)
|
||||
{
|
||||
va_list ptr;
|
||||
|
||||
fprintf(stderr, "%s: ", pgm);
|
||||
va_start(ptr, fmt);
|
||||
vfprintf(stderr, fmt, ptr);
|
||||
va_end(ptr);
|
||||
fputc('\n', stderr);
|
||||
fflush(stderr);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int opt;
|
||||
int rc;
|
||||
mkd_flag_t flags = 0;
|
||||
int debug = 0;
|
||||
int toc = 0;
|
||||
int content = 1;
|
||||
int version = 0;
|
||||
int with_html5 = 0;
|
||||
int styles = 0;
|
||||
int use_mkd_line = 0;
|
||||
int github_flavoured = 0;
|
||||
char *extra_footnote_prefix = 0;
|
||||
char *urlflags = 0;
|
||||
char *text = 0;
|
||||
char *ofile = 0;
|
||||
char *urlbase = 0;
|
||||
char *q;
|
||||
MMIOT *doc;
|
||||
|
||||
if ( q = getenv("MARKDOWN_FLAGS") )
|
||||
flags = strtol(q, 0, 0);
|
||||
|
||||
pgm = basename(argv[0]);
|
||||
opterr = 1;
|
||||
|
||||
while ( (opt=getopt(argc, argv, "5b:C:df:E:F:Gno:s:St:TV")) != EOF ) {
|
||||
switch (opt) {
|
||||
case '5': with_html5 = 1;
|
||||
break;
|
||||
case 'b': urlbase = optarg;
|
||||
break;
|
||||
case 'd': debug = 1;
|
||||
break;
|
||||
case 'V': version++;
|
||||
break;
|
||||
case 'E': urlflags = optarg;
|
||||
break;
|
||||
case 'F': if ( strcmp(optarg, "?") == 0 ) {
|
||||
show_flags(0);
|
||||
exit(0);
|
||||
}
|
||||
else
|
||||
flags = strtol(optarg, 0, 0);
|
||||
break;
|
||||
case 'f': if ( strcmp(optarg, "?") == 0 ) {
|
||||
show_flags(1);
|
||||
exit(0);
|
||||
}
|
||||
else if ( !set_flag(&flags, optarg) )
|
||||
complain("unknown option <%s>", optarg);
|
||||
break;
|
||||
case 'G': github_flavoured = 1;
|
||||
break;
|
||||
case 'n': content = 0;
|
||||
break;
|
||||
case 's': text = optarg;
|
||||
break;
|
||||
case 'S': styles = 1;
|
||||
break;
|
||||
case 't': text = optarg;
|
||||
use_mkd_line = 1;
|
||||
break;
|
||||
case 'T': toc = 1;
|
||||
break;
|
||||
case 'C': extra_footnote_prefix = optarg;
|
||||
break;
|
||||
case 'o': if ( ofile ) {
|
||||
complain("Too many -o options");
|
||||
exit(1);
|
||||
}
|
||||
if ( !freopen(ofile = optarg, "w", stdout) ) {
|
||||
perror(ofile);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
default: fprintf(stderr, "usage: %s [-dTV] [-b url-base]"
|
||||
" [-F bitmap] [-f {+-}flags]"
|
||||
" [-o ofile] [-s text]"
|
||||
" [-t text] [file]\n", pgm);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if ( version ) {
|
||||
printf("%s: discount %s%s", pgm, markdown_version,
|
||||
with_html5 ? " +html5":"");
|
||||
if ( version > 1 )
|
||||
mkd_flags_are(stdout, flags, 0);
|
||||
putchar('\n');
|
||||
exit(0);
|
||||
}
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if ( with_html5 )
|
||||
mkd_with_html5_tags();
|
||||
|
||||
if ( use_mkd_line )
|
||||
rc = mkd_generateline( text, strlen(text), stdout, flags);
|
||||
else {
|
||||
if ( text ) {
|
||||
doc = github_flavoured ? gfm_string(text, strlen(text), flags)
|
||||
: mkd_string(text, strlen(text), flags) ;
|
||||
|
||||
if ( !doc ) {
|
||||
perror(text);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ( argc && !freopen(argv[0], "r", stdin) ) {
|
||||
perror(argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
doc = github_flavoured ? gfm_in(stdin,flags) : mkd_in(stdin,flags);
|
||||
if ( !doc ) {
|
||||
perror(argc ? argv[0] : "stdin");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
if ( urlbase )
|
||||
mkd_basename(doc, urlbase);
|
||||
if ( urlflags ) {
|
||||
mkd_e_data(doc, urlflags);
|
||||
mkd_e_flags(doc, e_flags);
|
||||
}
|
||||
if ( extra_footnote_prefix )
|
||||
mkd_ref_prefix(doc, extra_footnote_prefix);
|
||||
|
||||
if ( debug )
|
||||
rc = mkd_dump(doc, stdout, 0, argc ? basename(argv[0]) : "stdin");
|
||||
else {
|
||||
rc = 1;
|
||||
if ( mkd_compile(doc, flags) ) {
|
||||
rc = 0;
|
||||
if ( styles )
|
||||
mkd_generatecss(doc, stdout);
|
||||
if ( toc )
|
||||
mkd_generatetoc(doc, stdout);
|
||||
if ( content )
|
||||
mkd_generatehtml(doc, stdout);
|
||||
mkd_cleanup(doc);
|
||||
}
|
||||
}
|
||||
}
|
||||
mkd_deallocate_tags();
|
||||
adump();
|
||||
exit( (rc == 0) ? 0 : errno );
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
.\" %A%
|
||||
.\"
|
||||
.Dd January 10, 2010
|
||||
.Dt MAKEPAGE 1
|
||||
.Os MASTODON
|
||||
.Sh NAME
|
||||
.Nm makepage
|
||||
.Nd convert markdown input to a fully-formed xhtml page
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl V
|
||||
.Op Fl F Pa bitmap
|
||||
.Op Fl f Ar flags
|
||||
.Op Pa file
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
utility parses a
|
||||
.Xr markdown 7 Ns -formatted
|
||||
.Pa textfile
|
||||
.Pq or stdin if not specified,
|
||||
compiles it, then prints a fully-formed xhtml page to stdout.
|
||||
.Pp
|
||||
The
|
||||
.Fl F ,
|
||||
.Fl f ,
|
||||
and
|
||||
.Fl V
|
||||
flags are identical to the same options in
|
||||
.Xr markdown 1 .
|
||||
.Pp
|
||||
.Nm
|
||||
is part of discount.
|
||||
.Sh RETURN VALUES
|
||||
The
|
||||
.Nm
|
||||
utility exits 0 on success, and >0 if an error occurs.
|
||||
.Sh SEE ALSO
|
||||
.Xr markdown 1 ,
|
||||
.Xr markdown 3 ,
|
||||
.Xr markdown 7 ,
|
||||
.Xr mkd-extensions 7 .
|
||||
.Sh AUTHOR
|
||||
.An David Parsons
|
||||
.Pq Li orc@pell.portland.or.us
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* makepage: Use mkd_xhtmlpage() to convert markdown input to a
|
||||
* fully-formed xhtml page.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <mkdio.h>
|
||||
#include "config.h"
|
||||
#include "pgm_options.h"
|
||||
|
||||
#ifndef HAVE_BASENAME
|
||||
char*
|
||||
basename(char *p)
|
||||
{
|
||||
char *ret = strrchr(p, '/');
|
||||
|
||||
return ret ? (1+ret) : p;
|
||||
}
|
||||
#endif
|
||||
|
||||
char *pgm = "makepage";
|
||||
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
MMIOT *doc;
|
||||
char *q;
|
||||
int version = 0;
|
||||
int opt;
|
||||
mkd_flag_t flags = 0;
|
||||
|
||||
if ( (q = getenv("MARKDOWN_FLAGS")) )
|
||||
flags = strtol(q, 0, 0);
|
||||
|
||||
opterr = 1;
|
||||
|
||||
while ( (opt=getopt(argc, argv, "F:f:V")) != EOF ) {
|
||||
switch (opt) {
|
||||
case 'V': version++;
|
||||
break;
|
||||
case 'F': if ( strcmp(optarg, "?") == 0 ) {
|
||||
show_flags(0);
|
||||
exit(0);
|
||||
}
|
||||
else
|
||||
flags = strtol(optarg, 0, 0);
|
||||
break;
|
||||
case 'f': if ( strcmp(optarg, "?") == 0 ) {
|
||||
show_flags(1);
|
||||
exit(0);
|
||||
}
|
||||
else if ( !set_flag(&flags, optarg) )
|
||||
fprintf(stderr, "unknown option <%s>\n", optarg);
|
||||
break;
|
||||
default: fprintf(stderr, "usage: %s [-V] [-F bitmap] [-f {+-}flags]"
|
||||
" [file]\n", pgm);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if ( version ) {
|
||||
printf("%s: discount %s", pgm, markdown_version);
|
||||
if ( version > 1 )
|
||||
mkd_flags_are(stdout, flags, 0);
|
||||
putchar('\n');
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if ( (argc > 1) && !freopen(argv[1], "r", stdin) ) {
|
||||
perror(argv[1]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ( (doc = mkd_in(stdin, flags)) == 0 ) {
|
||||
perror( (argc > 1) ? argv[1] : "stdin" );
|
||||
exit(1);
|
||||
}
|
||||
|
||||
exit(mkd_xhtmlpage(doc, flags, stdout));
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
.\" %A%
|
||||
.\"
|
||||
.Dd January 7, 2008
|
||||
.Dt MARKDOWN 1
|
||||
.Os MASTODON
|
||||
.Sh NAME
|
||||
.Nm markdown
|
||||
.Nd text to html conversion tool
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl d
|
||||
.Op Fl T
|
||||
.Op Fl V
|
||||
.Op Fl b Ar url-base
|
||||
.Op Fl C Ar prefix
|
||||
.Op Fl F Pa bitmap
|
||||
.Op Fl f Ar flags
|
||||
.Op Fl n
|
||||
.Op Fl o Pa file
|
||||
.Op Fl S
|
||||
.Op Fl s Pa text
|
||||
.Op Fl t Pa text
|
||||
.Op Pa textfile
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
utility reads the
|
||||
.Xr markdown 7 Ns -formatted
|
||||
.Pa textfile
|
||||
.Pq or stdin if not specified,
|
||||
compiles it, and writes the html output
|
||||
to stdout.
|
||||
.Pp
|
||||
The options are as follows:
|
||||
.Bl -tag -width "-o file"
|
||||
.It Fl b Ar url-base
|
||||
Links in source beginning with / will be prefixed with
|
||||
.Ar url-base
|
||||
in the output.
|
||||
.It Fl C
|
||||
When processing markdown extra-style footnotes, use the
|
||||
given prefix instead of the default of
|
||||
.Ar fn .
|
||||
.It Fl d
|
||||
Instead of writing the html file, dump a parse
|
||||
tree to stdout.
|
||||
.It Fl f Ar flags
|
||||
Set or clear various translation flags. The flags
|
||||
are in a comma-delimited list, with an optional
|
||||
.Ar +
|
||||
(enable),
|
||||
.Ar -
|
||||
(disable), or
|
||||
.Ar no
|
||||
(disable) lprefix on each flag.
|
||||
.Bl -tag -width "definitionlist"
|
||||
.It Ar links
|
||||
Allow links.
|
||||
.It Ar image
|
||||
Allow images.
|
||||
.It Ar smarty
|
||||
Enable smartypants.
|
||||
.It Ar pants
|
||||
Enable smartypants.
|
||||
.It Ar html
|
||||
Allow raw html.
|
||||
.It Ar strict
|
||||
Disable superscript, strikethrough & relaxed emphasis.
|
||||
.It Ar ext
|
||||
Enable pseudo-protocols.
|
||||
.It Ar cdata
|
||||
Generate code for xml
|
||||
.Em ![CDATA[...]] .
|
||||
.It Ar superscript
|
||||
Enable superscript processing.
|
||||
.It Ar emphasis
|
||||
Emphasis happens
|
||||
.Em everywhere .
|
||||
.It Ar tables
|
||||
Don't process PHP Markdown Extra tables.
|
||||
.It Ar del
|
||||
Enable
|
||||
.Em ~~strikethrough~~ .
|
||||
.It Ar strikethrough
|
||||
Enable
|
||||
.Em ~~strikethrough~~ .
|
||||
.It Ar toc
|
||||
Enable table-of-contents processing.
|
||||
.It Ar 1.0
|
||||
Compatibility with MarkdownTest_1.0
|
||||
.It Ar autolink
|
||||
Make
|
||||
.Pa http://foo.com
|
||||
a link even without
|
||||
.Em <> .
|
||||
.It Ar safelink
|
||||
Paranoid check for link protocol.
|
||||
.It Ar header
|
||||
Process pandoc-style header blocks.
|
||||
.It Ar tabstop
|
||||
Expand tabs to 4 spaces.
|
||||
.It Ar divquote
|
||||
Allow
|
||||
.Pa >%class%
|
||||
blocks.
|
||||
.It Ar alphalist
|
||||
Allow alphabetic lists.
|
||||
.It Ar definitionlist
|
||||
Allow definition lists.
|
||||
.It Ar footnote
|
||||
Allow markdown extra-style footnotes.
|
||||
.It Ar styles
|
||||
Extract <style> blocks from the output.
|
||||
.El
|
||||
.Pp
|
||||
As an example, the option
|
||||
.Fl f Ar nolinks,smarty
|
||||
tells
|
||||
.Nm
|
||||
to not allow \<a tags, and to do smarty
|
||||
pants processing.
|
||||
.It Fl F Ar bitmap
|
||||
Set translation flags.
|
||||
.Ar Bitmap
|
||||
is a bit map of the various configuration options
|
||||
described in
|
||||
.Xr markdown 3
|
||||
(the flag values are defined in
|
||||
.Pa mkdio.h )
|
||||
.It Fl n
|
||||
Don't write generated html.
|
||||
.It Fl o Pa file
|
||||
Write the generated html to
|
||||
.Pa file .
|
||||
.It Fl S
|
||||
output <style> blocks.
|
||||
.It Fl V
|
||||
Show the version# and compile-time configuration data.
|
||||
.Pp
|
||||
If the version includes the string
|
||||
.Em DEBUG ,
|
||||
.Nm
|
||||
was configured with memory allocation debugging.
|
||||
.Pp
|
||||
If the version includes the string
|
||||
.Em TAB ,
|
||||
.Nm
|
||||
was configured to use the specified tabstop.
|
||||
.It Fl VV
|
||||
Show the version#, the compile-time configuration, and the
|
||||
run-time configuration.
|
||||
.It Fl t Ar text
|
||||
Use
|
||||
.Xr mkd_text 3
|
||||
to format
|
||||
.Ar text
|
||||
instead of processing stdin with the
|
||||
.Xr markdown 3
|
||||
function.
|
||||
.It Fl T
|
||||
If run with the table-of-content flag on, dump the
|
||||
table of contents before the formatted text.
|
||||
.It Fl s Ar text
|
||||
Use the
|
||||
.Xr markdown 3
|
||||
function to format
|
||||
.Ar text .
|
||||
.El
|
||||
.Sh RETURN VALUES
|
||||
The
|
||||
.Nm
|
||||
utility exits 0 on success, and >0 if an error occurs.
|
||||
.Sh SEE ALSO
|
||||
.Xr markdown 3 ,
|
||||
.Xr markdown 7 ,
|
||||
.Xr mkd-extensions 7 .
|
||||
.Sh AUTHOR
|
||||
.An David Parsons
|
||||
.Pq Li orc@pell.portland.or.us
|
||||
@@ -0,0 +1,137 @@
|
||||
.\"
|
||||
.Dd December 20, 2007
|
||||
.Dt MARKDOWN 3
|
||||
.Os Mastodon
|
||||
.Sh NAME
|
||||
.Nm markdown
|
||||
.Nd process Markdown documents
|
||||
.Sh LIBRARY
|
||||
Markdown
|
||||
.Pq libmarkdown , -lmarkdown
|
||||
.Sh SYNOPSIS
|
||||
.Fd #include <mkdio.h>
|
||||
.Ft MMIOT
|
||||
.Fn *mkd_in "FILE *input" "int flags"
|
||||
.Ft MMIOT
|
||||
.Fn *mkd_string "char *string" "int size" "int flags"
|
||||
.Ft int
|
||||
.Fn markdown "MMIOT *doc" "FILE *output" "int flags"
|
||||
.Sh DESCRIPTION
|
||||
These functions
|
||||
convert
|
||||
.Em Markdown
|
||||
documents and strings into HTML.
|
||||
.Fn markdown
|
||||
processes an entire document, while
|
||||
.Fn mkd_text
|
||||
processes a single string.
|
||||
.Pp
|
||||
To process a file, you pass a FILE* to
|
||||
.Fn mkd_in ,
|
||||
and if it returns a nonzero value you pass that in to
|
||||
.Fn markdown ,
|
||||
which then writes the converted document to the specified
|
||||
.Em FILE* .
|
||||
If your input has already been written into a string (generated
|
||||
input or a file opened
|
||||
with
|
||||
.Xr mmap 2 )
|
||||
you can feed that string to
|
||||
.Fn mkd_string
|
||||
and pass its return value to
|
||||
.Fn markdown.
|
||||
.Pp
|
||||
.Fn Markdown
|
||||
accepts the following flag values (or-ed together if needed)
|
||||
to restrict how it processes input:
|
||||
.Bl -tag -width MKD_NOSTRIKETHROUGH -compact
|
||||
.It Ar MKD_NOLINKS
|
||||
Don't do link processing, block
|
||||
.Em <a>
|
||||
tags.
|
||||
.It Ar MKD_NOIMAGE
|
||||
Don't do image processing, block
|
||||
.Em <img> .
|
||||
.It Ar MKD_NOPANTS
|
||||
Don't run
|
||||
.Em smartypants() .
|
||||
.It Ar MKD_NOHTML
|
||||
Don't allow raw html through AT ALL
|
||||
.It Ar MKD_STRICT
|
||||
Disable
|
||||
superscript and relaxed emphasis.
|
||||
.It Ar MKD_TAGTEXT
|
||||
Process text inside an html tag; no
|
||||
.Em <em> ,
|
||||
no
|
||||
.Em <bold> ,
|
||||
no html or
|
||||
.Em []
|
||||
expansion.
|
||||
.It Ar MKD_NO_EXT
|
||||
Don't allow pseudo-protocols.
|
||||
.It Ar MKD_CDATA
|
||||
Generate code for xml
|
||||
.Em ![CDATA[...]] .
|
||||
.It Ar MKD_NOSUPERSCRIPT
|
||||
Don't generate superscripts.
|
||||
Emphasis happens _everywhere_
|
||||
.It Ar MKD_NOTABLES
|
||||
Disallow tables.
|
||||
.It Ar MKD_NOSTRIKETHROUGH
|
||||
Forbid
|
||||
.Em ~~strikethrough~~ .
|
||||
.It Ar MKD_TOC
|
||||
Do table-of-contents processing.
|
||||
.It Ar MKD_1_COMPAT
|
||||
Compatibility with MarkdownTest_1.0
|
||||
.It Ar MKD_AUTOLINK
|
||||
Make
|
||||
.Em http://foo.com
|
||||
into a link even without
|
||||
.Em <> s.
|
||||
.It Ar MKD_SAFELINK
|
||||
Paranoid check for link protocol.
|
||||
.It Ar MKD_NOHEADER
|
||||
Don't process header blocks.
|
||||
.It Ar MKD_TABSTOP
|
||||
Expand tabs to 4 spaces.
|
||||
.It Ar MKD_NODIVQUOTE
|
||||
Forbid
|
||||
.Em >%class%
|
||||
blocks.
|
||||
.It Ar MKD_NOALPHALIST
|
||||
Forbid alphabetic lists.
|
||||
.It Ar MKD_NODLIST
|
||||
Forbid definition lists.
|
||||
.It Ar MKD_EXTRA_FOOTNOTE
|
||||
Enable markdown extra-style footnotes.
|
||||
.El
|
||||
.Sh RETURN VALUES
|
||||
.Fn markdown
|
||||
returns 0 on success, 1 on failure.
|
||||
The
|
||||
.Fn mkd_in
|
||||
and
|
||||
.Fn mkd_string
|
||||
functions return a MMIOT* on success, null on failure.
|
||||
.Sh SEE ALSO
|
||||
.Xr markdown 1 ,
|
||||
.Xr mkd-callbacks 3 ,
|
||||
.Xr mkd-functions 3 ,
|
||||
.Xr mkd-line 3 ,
|
||||
.Xr markdown 7 ,
|
||||
.Xr mkd-extensions 7 ,
|
||||
.Xr mmap 2 .
|
||||
.Pp
|
||||
http://daringfireball.net/projects/markdown/syntax
|
||||
.Sh BUGS
|
||||
Error handling is minimal at best.
|
||||
.Pp
|
||||
The
|
||||
.Ar MMIOT
|
||||
created by
|
||||
.Fn mkd_string
|
||||
is deleted by the
|
||||
.Nm
|
||||
function.
|
||||
+1020
File diff suppressed because it is too large
Load Diff
+1346
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,227 @@
|
||||
#ifndef _MARKDOWN_D
|
||||
#define _MARKDOWN_D
|
||||
|
||||
#include "cstring.h"
|
||||
|
||||
/* reference-style links (and images) are stored in an array
|
||||
* of footnotes.
|
||||
*/
|
||||
typedef struct footnote {
|
||||
Cstring tag; /* the tag for the reference link */
|
||||
Cstring link; /* what this footnote points to */
|
||||
Cstring title; /* what it's called (TITLE= attribute) */
|
||||
int height, width; /* dimensions (for image link) */
|
||||
int dealloc; /* deallocation needed? */
|
||||
int refnumber;
|
||||
int flags;
|
||||
#define EXTRA_BOOKMARK 0x01
|
||||
#define REFERENCED 0x02
|
||||
} Footnote;
|
||||
|
||||
/* each input line is read into a Line, which contains the line,
|
||||
* the offset of the first non-space character [this assumes
|
||||
* that all tabs will be expanded to spaces!], and a pointer to
|
||||
* the next line.
|
||||
*/
|
||||
typedef enum { chk_text, chk_code,
|
||||
chk_hr, chk_dash,
|
||||
chk_tilde, chk_backtick,
|
||||
chk_equal } line_type;
|
||||
typedef struct line {
|
||||
Cstring text;
|
||||
struct line *next;
|
||||
int dle; /* leading indent on the line */
|
||||
int flags; /* special attributes for this line */
|
||||
#define PIPECHAR 0x01 /* line contains a | */
|
||||
#define CHECKED 0x02
|
||||
|
||||
line_type kind;
|
||||
int count;
|
||||
} Line;
|
||||
|
||||
|
||||
/* a paragraph is a collection of Lines, with links to the next paragraph
|
||||
* and (if it's a QUOTE, UL, or OL) to the reparsed contents of this
|
||||
* paragraph.
|
||||
*/
|
||||
typedef struct paragraph {
|
||||
struct paragraph *next; /* next paragraph */
|
||||
struct paragraph *down; /* recompiled contents of this paragraph */
|
||||
struct line *text; /* all the text in this paragraph */
|
||||
char *ident; /* %id% tag for QUOTE */
|
||||
char *lang; /* lang attribute for CODE */
|
||||
enum { WHITESPACE=0, CODE, QUOTE, MARKUP,
|
||||
HTML, STYLE, DL, UL, OL, AL, LISTITEM,
|
||||
HDR, HR, TABLE, SOURCE } typ;
|
||||
enum { IMPLICIT=0, PARA, CENTER} align;
|
||||
int hnumber; /* <Hn> for typ == HDR */
|
||||
} Paragraph;
|
||||
|
||||
enum { ETX, SETEXT }; /* header types */
|
||||
|
||||
|
||||
typedef struct block {
|
||||
enum { bTEXT, bSTAR, bUNDER } b_type;
|
||||
int b_count;
|
||||
char b_char;
|
||||
Cstring b_text;
|
||||
Cstring b_post;
|
||||
} block;
|
||||
|
||||
typedef STRING(block) Qblock;
|
||||
|
||||
|
||||
typedef char* (*mkd_callback_t)(const char*, const int, void*);
|
||||
typedef void (*mkd_free_t)(char*, void*);
|
||||
|
||||
typedef struct callback_data {
|
||||
void *e_data; /* private data for callbacks */
|
||||
mkd_callback_t e_url; /* url edit callback */
|
||||
mkd_callback_t e_flags; /* extra href flags callback */
|
||||
mkd_free_t e_free; /* edit/flags callback memory deallocator */
|
||||
} Callback_data;
|
||||
|
||||
|
||||
struct escaped {
|
||||
char *text;
|
||||
struct escaped *up;
|
||||
} ;
|
||||
|
||||
|
||||
struct footnote_list {
|
||||
int reference;
|
||||
STRING(Footnote) note;
|
||||
} ;
|
||||
|
||||
|
||||
/* a magic markdown io thing holds all the data structures needed to
|
||||
* do the backend processing of a markdown document
|
||||
*/
|
||||
typedef struct mmiot {
|
||||
Cstring out;
|
||||
Cstring in;
|
||||
Qblock Q;
|
||||
int isp;
|
||||
struct escaped *esc;
|
||||
char *ref_prefix;
|
||||
struct footnote_list *footnotes;
|
||||
DWORD flags;
|
||||
#define MKD_NOLINKS 0x00000001
|
||||
#define MKD_NOIMAGE 0x00000002
|
||||
#define MKD_NOPANTS 0x00000004
|
||||
#define MKD_NOHTML 0x00000008
|
||||
#define MKD_STRICT 0x00000010
|
||||
#define MKD_TAGTEXT 0x00000020
|
||||
#define MKD_NO_EXT 0x00000040
|
||||
#define MKD_CDATA 0x00000080
|
||||
#define MKD_NOSUPERSCRIPT 0x00000100
|
||||
#define MKD_NORELAXED 0x00000200
|
||||
#define MKD_NOTABLES 0x00000400
|
||||
#define MKD_NOSTRIKETHROUGH 0x00000800
|
||||
#define MKD_TOC 0x00001000
|
||||
#define MKD_1_COMPAT 0x00002000
|
||||
#define MKD_AUTOLINK 0x00004000
|
||||
#define MKD_SAFELINK 0x00008000
|
||||
#define MKD_NOHEADER 0x00010000
|
||||
#define MKD_TABSTOP 0x00020000
|
||||
#define MKD_NODIVQUOTE 0x00040000
|
||||
#define MKD_NOALPHALIST 0x00080000
|
||||
#define MKD_NODLIST 0x00100000
|
||||
#define MKD_EXTRA_FOOTNOTE 0x00200000
|
||||
#define MKD_NOSTYLE 0x00400000
|
||||
#define IS_LABEL 0x08000000
|
||||
#define USER_FLAGS 0x0FFFFFFF
|
||||
#define INPUT_MASK (MKD_NOHEADER|MKD_TABSTOP)
|
||||
|
||||
Callback_data *cb;
|
||||
} MMIOT;
|
||||
|
||||
|
||||
#define MKD_EOLN 3
|
||||
|
||||
|
||||
/*
|
||||
* the mkdio text input functions return a document structure,
|
||||
* which contains a header (retrieved from the document if
|
||||
* markdown was configured * with the * --enable-pandoc-header
|
||||
* and the document begins with a pandoc-style header) and the
|
||||
* root of the linked list of Lines.
|
||||
*/
|
||||
typedef struct document {
|
||||
int magic; /* "I AM VALID" magic number */
|
||||
#define VALID_DOCUMENT 0x19600731
|
||||
Line *title;
|
||||
Line *author;
|
||||
Line *date;
|
||||
ANCHOR(Line) content; /* uncompiled text, not valid after compile() */
|
||||
Paragraph *code; /* intermediate code generated by compile() */
|
||||
int compiled; /* set after mkd_compile() */
|
||||
int html; /* set after (internal) htmlify() */
|
||||
int tabstop; /* for properly expanding tabs (ick) */
|
||||
char *ref_prefix;
|
||||
MMIOT *ctx; /* backend buffers, flags, and structures */
|
||||
Callback_data cb; /* callback functions & private data */
|
||||
} Document;
|
||||
|
||||
|
||||
/*
|
||||
* economy FILE-type structure for pulling characters out of a
|
||||
* fixed-length string.
|
||||
*/
|
||||
struct string_stream {
|
||||
const char *data; /* the unread data */
|
||||
int size; /* and how much is there? */
|
||||
} ;
|
||||
|
||||
|
||||
extern int mkd_firstnonblank(Line *);
|
||||
extern int mkd_compile(Document *, DWORD);
|
||||
extern int mkd_document(Document *, char **);
|
||||
extern int mkd_generatehtml(Document *, FILE *);
|
||||
extern int mkd_css(Document *, char **);
|
||||
extern int mkd_generatecss(Document *, FILE *);
|
||||
#define mkd_style mkd_generatecss
|
||||
extern int mkd_xml(char *, int , char **);
|
||||
extern int mkd_generatexml(char *, int, FILE *);
|
||||
extern void mkd_cleanup(Document *);
|
||||
extern int mkd_line(char *, int, char **, DWORD);
|
||||
extern int mkd_generateline(char *, int, FILE*, DWORD);
|
||||
#define mkd_text mkd_generateline
|
||||
extern void mkd_basename(Document*, char *);
|
||||
|
||||
typedef int (*mkd_sta_function_t)(const int,const void*);
|
||||
extern void mkd_string_to_anchor(char*,int, mkd_sta_function_t, void*, int);
|
||||
|
||||
extern Document *mkd_in(FILE *, DWORD);
|
||||
extern Document *mkd_string(const char*,int, DWORD);
|
||||
|
||||
extern Document *gfm_in(FILE *, DWORD);
|
||||
extern Document *gfm_string(const char*,int, DWORD);
|
||||
|
||||
extern void mkd_initialize();
|
||||
extern void mkd_shlib_destructor();
|
||||
|
||||
extern void mkd_ref_prefix(Document*, char*);
|
||||
|
||||
/* internal resource handling functions.
|
||||
*/
|
||||
extern void ___mkd_freeLine(Line *);
|
||||
extern void ___mkd_freeLines(Line *);
|
||||
extern void ___mkd_freeParagraph(Paragraph *);
|
||||
extern void ___mkd_freefootnote(Footnote *);
|
||||
extern void ___mkd_freefootnotes(MMIOT *);
|
||||
extern void ___mkd_initmmiot(MMIOT *, void *);
|
||||
extern void ___mkd_freemmiot(MMIOT *, void *);
|
||||
extern void ___mkd_freeLineRange(Line *, Line *);
|
||||
extern void ___mkd_xml(char *, int, FILE *);
|
||||
extern void ___mkd_reparse(char *, int, int, MMIOT*, char*);
|
||||
extern void ___mkd_emblock(MMIOT*);
|
||||
extern void ___mkd_tidy(Cstring *);
|
||||
|
||||
extern Document *__mkd_new_Document();
|
||||
extern void __mkd_enqueue(Document*, Cstring *);
|
||||
extern void __mkd_header_dle(Line *);
|
||||
|
||||
extern int __mkd_io_strget(struct string_stream *);
|
||||
|
||||
#endif/*_MARKDOWN_D*/
|
||||
@@ -0,0 +1,71 @@
|
||||
.\"
|
||||
.Dd January 18, 2008
|
||||
.Dt MKD_CALLBACKS 3
|
||||
.Os Mastodon
|
||||
.Sh NAME
|
||||
.Nm mkd_callbacks
|
||||
.Nd functions that modify link targets
|
||||
.Sh LIBRARY
|
||||
Markdown
|
||||
.Pq libmarkdown , -lmarkdown
|
||||
.Sh SYNOPSIS
|
||||
.Fd #include <mkdio.h>
|
||||
.Ft char*
|
||||
.Fn (*mkd_callback_t) "const char*" "const int" "void*"
|
||||
.Ft void
|
||||
.Fn (*mkd_free_t) "char *" "void*"
|
||||
.Ft void
|
||||
.Fn mkd_e_url "MMIOT *document" "mkd_callback_t edit"
|
||||
.Ft void
|
||||
.Fn mkd_e_flags "MMIOT *document" "mkd_callback_t edit"
|
||||
.Ft void
|
||||
.Fn mkd_e_free "MMIOT *document" "mkd_free_t dealloc"
|
||||
.Ft void
|
||||
.Fn mkd_e_data "MMIOT *document" "void *data"
|
||||
.Sh DESCRIPTION
|
||||
.Pp
|
||||
.Nm Discount
|
||||
provides a small set of data access functions to let a
|
||||
library user modify the targets given in a `[]' link, and to
|
||||
add additional flags to the generated link.
|
||||
.Pp
|
||||
The data access functions are passed a character pointer to
|
||||
the url being generated, the size of the url, and a data pointer
|
||||
pointing to a user data area (set by the
|
||||
.Fn mkd_e_data
|
||||
function.) After the callback function is called (either
|
||||
.Fn mkd_e_url
|
||||
or
|
||||
.Fn mkd_e_flags )
|
||||
the data freeing function (if supplied) is called and passed the
|
||||
character pointer and user data pointer.
|
||||
.Sh EXAMPLE
|
||||
The
|
||||
.Fn mkd_basename
|
||||
function (in the module basename.c) is implemented by means of
|
||||
mkd callbacks; it modifies urls that start with a `/' so that
|
||||
they begin with a user-supplied url base by allocating a new
|
||||
string and filling it with the base + the url. Discount plugs
|
||||
that url in in place of the original, then calls the basename
|
||||
free function (it only does this when
|
||||
.Fn mkd_e_url
|
||||
or
|
||||
.Fn mkd_e_flags
|
||||
returns nonzero) to deallocate this memory.
|
||||
.Pp
|
||||
Note that only one level of callbacks are supported; if you
|
||||
wish to do multiple callbacks, you need to write your own
|
||||
code to handle them all.
|
||||
.Sh SEE ALSO
|
||||
.Xr markdown 1 ,
|
||||
.Xr markdown 3 ,
|
||||
.Xr mkd-line 3 ,
|
||||
.Xr markdown 7 ,
|
||||
.Xr mkd-extensions 7 ,
|
||||
.Xr mmap 2 .
|
||||
.Pp
|
||||
basename.c
|
||||
.Pp
|
||||
http://daringfireball.net/projects/markdown/syntax
|
||||
.Sh BUGS
|
||||
Error handling is minimal at best.
|
||||
@@ -0,0 +1,205 @@
|
||||
.\"
|
||||
.Dd Dec 22, 2007
|
||||
.Dt MKD-EXTENSIONS 7
|
||||
.Os MASTODON
|
||||
.Sh NAME
|
||||
.Nm mkd-extensions
|
||||
.Nd Extensions to the Markdown text formatting syntax
|
||||
.Sh DESCRIPTION
|
||||
This version of markdown has been extended in a few ways by
|
||||
extending existing markup, creating new markup from scratch,
|
||||
and borrowing markup from other markup languages.
|
||||
.Ss Image dimensions
|
||||
Markdown embedded images have been extended to allow specifying
|
||||
the dimensions of the image by adding a new argument
|
||||
.Em =/height/x/width/
|
||||
to the link description.
|
||||
.Pp
|
||||
The new image syntax is
|
||||
.nf
|
||||

|
||||
.fi
|
||||
.Ss pseudo-protocols
|
||||
Five pseudo-protocols have been added to links
|
||||
.Bl -tag -width XXXXX
|
||||
.It Ar id:
|
||||
The
|
||||
.Ar "alt text"
|
||||
is marked up and written to the output, wrapped with
|
||||
.Em "<a id=id>"
|
||||
and
|
||||
.Em "</a>" .
|
||||
.It Ar class:
|
||||
The
|
||||
.Ar "alt text"
|
||||
is marked up and written to the output, wrapped with
|
||||
.Em "<span class=class>"
|
||||
and
|
||||
.Em "</span>" .
|
||||
.It Ar raw:
|
||||
The
|
||||
.Ar title
|
||||
is written
|
||||
.Em -- with no further processing --
|
||||
to the output. The
|
||||
.Ar "alt text"
|
||||
is discarded.
|
||||
.It Ar abbr:
|
||||
The
|
||||
.Ar "alt text"
|
||||
is marked up and written to the output, wrapped with
|
||||
.Em "<abbr title=abbr>"
|
||||
and
|
||||
.Em "</abbr>" .
|
||||
.It Ar lang:
|
||||
The
|
||||
.Ar "alt text"
|
||||
s marked up and written to the output, wrapped with
|
||||
.Em "<span lang=lang>"
|
||||
and
|
||||
.Em "</span>" .
|
||||
.El
|
||||
.Ss Pandoc headers
|
||||
The markdown source document can have a 3-line
|
||||
.Xr Pandoc
|
||||
header in the format of
|
||||
.nf
|
||||
% title
|
||||
% author(s)
|
||||
% date
|
||||
.fi
|
||||
which will be made available to the
|
||||
.Fn mkd_doc_title ,
|
||||
.Fn mkd_doc_author ,
|
||||
and
|
||||
.Fn mkd_doc_date
|
||||
functions.
|
||||
.Ss Definition lists
|
||||
A definition list item
|
||||
is defined as
|
||||
.nf
|
||||
=tag=
|
||||
description
|
||||
.fi
|
||||
(that is a
|
||||
.Ar = ,
|
||||
followed by text, another
|
||||
.Ar = ,
|
||||
a newline, 4 spaces of intent, and then more text.)
|
||||
.Pp
|
||||
Alternatively, definition list items are defined as
|
||||
.nf
|
||||
tag
|
||||
: description
|
||||
.fi
|
||||
(This is the format that
|
||||
.Ar "PHP Markdown Extra"
|
||||
uses.)
|
||||
.Pp
|
||||
.Ss embedded stylesheets
|
||||
Stylesheets may be defined and modified in a
|
||||
.Em <style>
|
||||
block. A style block is parsed like any other
|
||||
block level html;
|
||||
.Em <style>
|
||||
starting on column 1, raw html (or, in this case, css) following
|
||||
it, and either ending with a
|
||||
.Em </style>
|
||||
at the end of the line or a
|
||||
.Em </style>
|
||||
at the beginning of a subsequent line.
|
||||
.Pp
|
||||
Be warned that style blocks work like footnote links -- no matter
|
||||
where you define them they are valid for the entire document.
|
||||
.Ss relaxed emphasis
|
||||
The rules for emphasis are changed so that a single
|
||||
.Ar _
|
||||
will
|
||||
.Em not
|
||||
count as a emphasis character if it's in the middle of a word.
|
||||
This is primarily for documenting code, if you don't wish to
|
||||
have to backquote all code references.
|
||||
.Ss alpha lists
|
||||
Alphabetic lists (like regular numeric lists, but with alphabetic
|
||||
items) are supported. So:
|
||||
.nf
|
||||
a. this
|
||||
b. is
|
||||
c. an alphabetic
|
||||
d. list
|
||||
.fi
|
||||
will produce:
|
||||
.nf
|
||||
<ol type=a>
|
||||
<li>this</li>
|
||||
<li>is</li>
|
||||
<li>an alphabetic</li>
|
||||
<li>list</li>
|
||||
</ol>
|
||||
.fi
|
||||
.Ss tables
|
||||
.Ar "PHP Markdown Extra"
|
||||
tables are supported; input of the form
|
||||
.nf
|
||||
header|header
|
||||
------|------
|
||||
text | text
|
||||
.fi
|
||||
will produce:
|
||||
.nf
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>header</th>
|
||||
<th>header</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>text</td>
|
||||
<td>text</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
.fi
|
||||
The dashed line can also contain
|
||||
.Em :
|
||||
characters for formatting; if a
|
||||
.Em :
|
||||
is at the start of a column, it tells
|
||||
.Nm discount
|
||||
to align the cell contents to the left; if it's at the end, it
|
||||
aligns right, and if there's one at the start and at the
|
||||
end, it centers.
|
||||
.Ss strikethrough
|
||||
A strikethrough syntax is supported in much the same way that
|
||||
.Ar `
|
||||
is used to define a section of code. If you enclose text with
|
||||
two or more tildes, such as
|
||||
.Em ~~erased text~~
|
||||
it will be written as
|
||||
.Em "<del>erased text</del>" .
|
||||
Like code sections, you may use as many
|
||||
.Ar ~
|
||||
as you want, but there must be as many starting tildes as closing
|
||||
tildes.
|
||||
.Ss markdown extra-style footnotes
|
||||
.Ar "PHP Markdown Extra"
|
||||
footnotes are supported. If a footnote link begins with a
|
||||
.Ar ^ ,
|
||||
the first use of that footnote will generate a link down to the
|
||||
bottom of the rendered document, which will contain a numbered footnote
|
||||
with a link back to where the footnote was called.
|
||||
.Sh AUTHOR
|
||||
David Parsons
|
||||
.%T http://www.pell.portland.or.us/~orc/
|
||||
.Sh SEE ALSO
|
||||
.Xr markdown 1 ,
|
||||
.Xr markdown 3 ,
|
||||
.Xr mkd-callbacks 3 ,
|
||||
.Xr mkd-functions 3 ,
|
||||
.Xr mkd-line 3 .
|
||||
.Pp
|
||||
.%T http://daringfireball.net/projects/markdown
|
||||
.Pp
|
||||
.%T http://michelf.com/projects/php-markdown
|
||||
@@ -0,0 +1,186 @@
|
||||
.\"
|
||||
.Dd January 18, 2008
|
||||
.Dt MKD_FUNCTIONS 3
|
||||
.Os Mastodon
|
||||
.Sh NAME
|
||||
.Nm mkd_functions
|
||||
.Nd access and process Markdown documents.
|
||||
.Sh LIBRARY
|
||||
Markdown
|
||||
.Pq libmarkdown , -lmarkdown
|
||||
.Sh SYNOPSIS
|
||||
.Fd #include <mkdio.h>
|
||||
.Ft int
|
||||
.Fn mkd_compile "MMIOT *document" "int flags"
|
||||
.Ft int
|
||||
.Fn mkd_css "MMIOT *document" "char **doc"
|
||||
.Ft int
|
||||
.Fn mkd_generatecss "MMIOT *document" "FILE *output"
|
||||
.Ft int
|
||||
.Fn mkd_document "MMIOT *document" "char **doc"
|
||||
.Ft int
|
||||
.Fn mkd_generatehtml "MMIOT *document" "FILE *output"
|
||||
.Ft int
|
||||
.Fn mkd_xhtmlpage "MMIOT *document" "int flags" "FILE *output"
|
||||
.Ft int
|
||||
.Fn mkd_toc "MMIOT *document" "char **doc"
|
||||
.Ft void
|
||||
.Fn mkd_generatetoc "MMIOT *document" "FILE *output"
|
||||
.Ft void
|
||||
.Fn mkd_cleanup "MMIOT*"
|
||||
.Ft char*
|
||||
.Fn mkd_doc_title "MMIOT*"
|
||||
.Ft char*
|
||||
.Fn mkd_doc_author "MMIOT*"
|
||||
.Ft char*
|
||||
.Fn mkd_doc_date "MMIOT*"
|
||||
.Sh DESCRIPTION
|
||||
.Pp
|
||||
The
|
||||
.Nm markdown
|
||||
format supported in this implementation includes
|
||||
Pandoc-style header and inline
|
||||
.Ar \<style\>
|
||||
blocks, and the standard
|
||||
.Xr markdown 3
|
||||
functions do not provide access to
|
||||
the data provided by either of those extensions.
|
||||
These functions give you access to that data, plus
|
||||
they provide a finer-grained way of converting
|
||||
.Em Markdown
|
||||
documents into HTML.
|
||||
.Pp
|
||||
Given a
|
||||
.Ar MMIOT*
|
||||
generated by
|
||||
.Fn mkd_in
|
||||
or
|
||||
.Fn mkd_string ,
|
||||
.Fn mkd_compile
|
||||
compiles the document into
|
||||
.Em \<style\> ,
|
||||
.Em Pandoc ,
|
||||
and
|
||||
.Em html
|
||||
sections.
|
||||
.Pp
|
||||
Once compiled, the document can be examined and written
|
||||
by the
|
||||
.Fn mkd_css ,
|
||||
.Fn mkd_document ,
|
||||
.Fn mkd_generatecss ,
|
||||
.Fn mkd_generatehtml ,
|
||||
.Fn mkd_generatetoc ,
|
||||
.Fn mkd_toc ,
|
||||
.Fn mkd_xhtmlpage ,
|
||||
.Fn mkd_doc_title ,
|
||||
.Fn mkd_doc_author ,
|
||||
and
|
||||
.Fn mkd_doc_date
|
||||
functions.
|
||||
.Pp
|
||||
.Fn mkd_css
|
||||
allocates a string and populates it with any \<style\> sections
|
||||
provided in the document,
|
||||
.Fn mkd_generatecss
|
||||
writes any \<style\> sections to the output,
|
||||
.Fn mkd_document
|
||||
points
|
||||
.Ar text
|
||||
to the text of the document and returns the
|
||||
size of the document,
|
||||
.Fn mkd_generatehtml
|
||||
writes the rest of the document to the output,
|
||||
and
|
||||
.Fn mkd_doc_title ,
|
||||
.Fn mkd_doc_author ,
|
||||
.Fn mkd_doc_date
|
||||
are used to read the contents of a Pandoc header,
|
||||
if any.
|
||||
.Pp
|
||||
.Fn mkd_xhtmlpage
|
||||
writes a xhtml page containing the document. The regular set of
|
||||
flags can be passed.
|
||||
.Pp
|
||||
.Fn mkd_toc
|
||||
writes a document outline, in the form of a collection of nested
|
||||
lists with links to each header in the document, into a string
|
||||
allocated with
|
||||
.Fn malloc ,
|
||||
and returns the size.
|
||||
.Pp
|
||||
.Fn mkd_generatetoc
|
||||
is like
|
||||
.Fn mkd_toc ,
|
||||
except that it writes the document outline to the given
|
||||
.Pa FILE*
|
||||
argument.
|
||||
.Pp
|
||||
.Fn mkd_cleanup
|
||||
deletes a
|
||||
.Ar MMIOT*
|
||||
after processing is done.
|
||||
.Pp
|
||||
.Fn mkd_compile
|
||||
accepts the same flags that
|
||||
.Fn markdown
|
||||
and
|
||||
.Fn mkd_string
|
||||
do;
|
||||
.Bl -tag -width MKD_NOSTRIKETHROUGH -compact
|
||||
.It Ar MKD_NOIMAGE
|
||||
Do not process `![]' and
|
||||
remove
|
||||
.Em \<img\>
|
||||
tags from the output.
|
||||
.It Ar MKD_NOLINKS
|
||||
Do not process `[]' and remove
|
||||
.Em \<a\>
|
||||
tags from the output.
|
||||
.It Ar MKD_NOPANTS
|
||||
Do not do Smartypants-style mangling of quotes, dashes, or ellipses.
|
||||
.It Ar MKD_TAGTEXT
|
||||
Process the input as if you were inside a html tag. This means that
|
||||
no html tags will be generated, and
|
||||
.Fn mkd_compile
|
||||
will attempt to escape anything that might terribly confuse a
|
||||
web browser.
|
||||
.It Ar MKD_NO_EXT
|
||||
Do not process any markdown pseudo-protocols when
|
||||
handing
|
||||
.Ar [][]
|
||||
links.
|
||||
.It Ar MKD_NOHEADER
|
||||
Do not attempt to parse any Pandoc-style headers.
|
||||
.It Ar MKD_TOC
|
||||
Label all headers for use with the
|
||||
.Fn mkd_generatetoc
|
||||
function.
|
||||
.It Ar MKD_1_COMPAT
|
||||
MarkdownTest_1.0 compatibility flag; trim trailing spaces from the
|
||||
first line of code blocks and disable implicit reference links.
|
||||
.It Ar MKD_NOSTRIKETHROUGH
|
||||
Disable strikethrough support.
|
||||
.El
|
||||
.Sh RETURN VALUES
|
||||
The function
|
||||
.Fn mkd_compile
|
||||
returns 1 in the case of success, or 0 if the document is already compiled.
|
||||
The function
|
||||
.Fn mkd_generatecss
|
||||
returns the number of bytes written in the case of success, or EOF if an error
|
||||
occurred.
|
||||
The function
|
||||
.Fn mkd_generatehtml
|
||||
returns 0 on success, \-1 on failure.
|
||||
.Sh SEE ALSO
|
||||
.Xr markdown 1 ,
|
||||
.Xr markdown 3 ,
|
||||
.Xr mkd-line 3 ,
|
||||
.Xr markdown 7 ,
|
||||
.Xr mkd-extensions 7 ,
|
||||
.Xr mmap 2 .
|
||||
.Pp
|
||||
http://daringfireball.net/projects/markdown/syntax
|
||||
.Sh BUGS
|
||||
Error handling is minimal at best.
|
||||
@@ -0,0 +1,41 @@
|
||||
.\"
|
||||
.Dd January 18, 2008
|
||||
.Dt MKD_LINE 3
|
||||
.Os Mastodon
|
||||
.Sh NAME
|
||||
.Nm mkd_line
|
||||
.Nd do Markdown translation of small items
|
||||
.Sh LIBRARY
|
||||
Markdown
|
||||
.Pq libmarkdown , -lmarkdown
|
||||
.Sh SYNOPSIS
|
||||
.Fd #include <mkdio.h>
|
||||
.Ft int
|
||||
.Fn mkd_line "char *string" "int size" "char **doc" "int flags"
|
||||
.Ft int
|
||||
.Fn mkd_generateline "char *string" "int size" "FILE *output" "int flags"
|
||||
.Sh DESCRIPTION
|
||||
.Pp
|
||||
Occasionally one might want to do markdown translations on fragments of
|
||||
data, like the title of an weblog article, a date, or a simple signature
|
||||
line.
|
||||
.Nm mkd_line
|
||||
and
|
||||
.Nm mkd_generateline
|
||||
allow you to do markdown translations on small blocks of text.
|
||||
.Nm mkd_line
|
||||
allocates a buffer, then writes the translated text into that buffer,
|
||||
and
|
||||
.Nm mkd_generateline
|
||||
writes the output to the specified
|
||||
.Ar FILE* .
|
||||
.Sh SEE ALSO
|
||||
.Xr markdown 1 ,
|
||||
.Xr markdown 3 ,
|
||||
.Xr markdown 7 ,
|
||||
.Xr mkd-extensions 7 ,
|
||||
.Xr mmap 2 .
|
||||
.Pp
|
||||
http://daringfireball.net/projects/markdown/syntax
|
||||
.Sh BUGS
|
||||
Error handling is minimal at best.
|
||||
@@ -0,0 +1,52 @@
|
||||
.\" %A%
|
||||
.\"
|
||||
.Dd January 10, 2010
|
||||
.Dt MKD2HTML 1
|
||||
.Os MASTODON
|
||||
.Sh NAME
|
||||
.Nm mkd2html
|
||||
.Nd markdown to html converter
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl css Pa file
|
||||
.Op Fl header Pa string
|
||||
.Op Fl footer Pa string
|
||||
.Op Pa file
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
utility parses a
|
||||
.Xr markdown 7 Ns -formatted
|
||||
.Pa textfile
|
||||
.Pq or stdin if not specified,
|
||||
and generates a web page. It
|
||||
reads
|
||||
.Ar file
|
||||
or
|
||||
.Ar file.text
|
||||
and writes the result in
|
||||
.Ar file.html
|
||||
.Pq where file is the passed argument.
|
||||
.Pp
|
||||
.Nm
|
||||
is part of discount.
|
||||
.Sh OPTIONS
|
||||
.Bl -tag -width "-header string"
|
||||
.It Fl css Ar file
|
||||
Specifies a CSS file.
|
||||
.It Fl header Ar string
|
||||
Specifies a line to add to the <header> tag.
|
||||
.It Fl footer Ar string
|
||||
Specifies a line to add before the <\/body> tag.
|
||||
.El
|
||||
.Sh RETURN VALUES
|
||||
The
|
||||
.Nm
|
||||
utility exits 0 on success, and >0 if an error occurs.
|
||||
.Sh SEE ALSO
|
||||
.Xr markdown 1 ,
|
||||
.Xr markdown 3 ,
|
||||
.Xr markdown 7 ,
|
||||
.Xr mkd-extensions 7 .
|
||||
.Sh AUTHOR
|
||||
.An David Parsons
|
||||
.Pq Li orc@pell.portland.or.us
|
||||
@@ -0,0 +1,191 @@
|
||||
/*
|
||||
* mkd2html: parse a markdown input file and generate a web page.
|
||||
*
|
||||
* usage: mkd2html [options] filename
|
||||
* or mkd2html [options] < markdown > html
|
||||
*
|
||||
* options
|
||||
* -css css-file
|
||||
* -header line-to-add-to-<HEADER>
|
||||
* -footer line-to-add-before-</BODY>
|
||||
*
|
||||
* example:
|
||||
*
|
||||
* mkd2html -cs /~orc/pages.css syntax
|
||||
* ( read syntax OR syntax.text, write syntax.html )
|
||||
*/
|
||||
/*
|
||||
* Copyright (C) 2007 David L Parsons.
|
||||
* The redistribution terms are provided in the COPYRIGHT file that must
|
||||
* be distributed with this source code.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifdef HAVE_BASENAME
|
||||
# ifdef HAVE_LIBGEN_H
|
||||
# include <libgen.h>
|
||||
# else
|
||||
# include <unistd.h>
|
||||
# endif
|
||||
#endif
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "mkdio.h"
|
||||
#include "cstring.h"
|
||||
#include "amalloc.h"
|
||||
|
||||
char *pgm = "mkd2html";
|
||||
|
||||
#ifndef HAVE_BASENAME
|
||||
char *
|
||||
basename(char *path)
|
||||
{
|
||||
char *p;
|
||||
|
||||
if ( p = strrchr(path, '/') )
|
||||
return 1+p;
|
||||
return path;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
fail(char *why, ...)
|
||||
{
|
||||
va_list ptr;
|
||||
|
||||
va_start(ptr,why);
|
||||
fprintf(stderr, "%s: ", pgm);
|
||||
vfprintf(stderr, why, ptr);
|
||||
fputc('\n', stderr);
|
||||
va_end(ptr);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
main(argc, argv)
|
||||
char **argv;
|
||||
{
|
||||
char *h;
|
||||
char *source = 0, *dest = 0;
|
||||
MMIOT *mmiot;
|
||||
int i;
|
||||
FILE *input, *output;
|
||||
STRING(char*) css, headers, footers;
|
||||
|
||||
|
||||
CREATE(css);
|
||||
CREATE(headers);
|
||||
CREATE(footers);
|
||||
pgm = basename(argv[0]);
|
||||
|
||||
while ( argc > 1 ) {
|
||||
if ( strcmp(argv[1], "-css") == 0 ) {
|
||||
EXPAND(css) = argv[2];
|
||||
argc -= 2;
|
||||
argv += 2;
|
||||
}
|
||||
else if ( strcmp(argv[1], "-header") == 0 ) {
|
||||
EXPAND(headers) = argv[2];
|
||||
argc -= 2;
|
||||
argv += 2;
|
||||
}
|
||||
else if ( strcmp(argv[1], "-footer") == 0 ) {
|
||||
EXPAND(footers) = argv[2];
|
||||
argc -= 2;
|
||||
argv += 2;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
switch ( argc ) {
|
||||
char *p, *dot;
|
||||
case 1:
|
||||
input = stdin;
|
||||
output = stdout;
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
dest = malloc(strlen(argv[argc-1]) + 6);
|
||||
source = malloc(strlen(argv[1]) + 6);
|
||||
|
||||
if ( !(source && dest) )
|
||||
fail("out of memory allocating name buffers");
|
||||
|
||||
strcpy(source, argv[1]);
|
||||
if (( p = strrchr(source, '/') ))
|
||||
p = source;
|
||||
else
|
||||
++p;
|
||||
|
||||
if ( (input = fopen(source, "r")) == 0 ) {
|
||||
strcat(source, ".text");
|
||||
if ( (input = fopen(source, "r")) == 0 )
|
||||
fail("can't open either %s or %s", argv[1], source);
|
||||
}
|
||||
strcpy(dest, source);
|
||||
|
||||
if (( dot = strrchr(dest, '.') ))
|
||||
*dot = 0;
|
||||
strcat(dest, ".html");
|
||||
|
||||
if ( (output = fopen(dest, "w")) == 0 )
|
||||
fail("can't write to %s", dest);
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "usage: %s [opts] source [dest]\n", pgm);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ( (mmiot = mkd_in(input, 0)) == 0 )
|
||||
fail("can't read %s", source ? source : "stdin");
|
||||
|
||||
if ( !mkd_compile(mmiot, 0) )
|
||||
fail("couldn't compile input");
|
||||
|
||||
|
||||
h = mkd_doc_title(mmiot);
|
||||
|
||||
/* print a header */
|
||||
|
||||
fprintf(output,
|
||||
"<!doctype html public \"-//W3C//DTD HTML 4.0 Transitional //EN\">\n"
|
||||
"<html>\n"
|
||||
"<head>\n"
|
||||
" <meta name=\"GENERATOR\" content=\"mkd2html %s\">\n", markdown_version);
|
||||
|
||||
fprintf(output," <meta http-equiv=\"Content-Type\"\n"
|
||||
" content=\"text/html; charset=utf-8\">");
|
||||
|
||||
for ( i=0; i < S(css); i++ )
|
||||
fprintf(output, " <link rel=\"stylesheet\"\n"
|
||||
" type=\"text/css\"\n"
|
||||
" href=\"%s\" />\n", T(css)[i]);
|
||||
|
||||
if ( h ) {
|
||||
fprintf(output," <title>");
|
||||
mkd_generateline(h, strlen(h), output, 0);
|
||||
fprintf(output, "</title>\n");
|
||||
}
|
||||
for ( i=0; i < S(headers); i++ )
|
||||
fprintf(output, " %s\n", T(headers)[i]);
|
||||
fprintf(output, "</head>\n"
|
||||
"<body>\n");
|
||||
|
||||
/* print the compiled body */
|
||||
|
||||
mkd_generatehtml(mmiot, output);
|
||||
|
||||
for ( i=0; i < S(footers); i++ )
|
||||
fprintf(output, "%s\n", T(footers)[i]);
|
||||
|
||||
fprintf(output, "</body>\n"
|
||||
"</html>\n");
|
||||
|
||||
mkd_cleanup(mmiot);
|
||||
exit(0);
|
||||
}
|
||||
@@ -0,0 +1,364 @@
|
||||
/*
|
||||
* mkdio -- markdown front end input functions
|
||||
*
|
||||
* Copyright (C) 2007 David L Parsons.
|
||||
* The redistribution terms are provided in the COPYRIGHT file that must
|
||||
* be distributed with this source code.
|
||||
*/
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "cstring.h"
|
||||
#include "markdown.h"
|
||||
#include "amalloc.h"
|
||||
|
||||
typedef ANCHOR(Line) LineAnchor;
|
||||
|
||||
/* create a new blank Document
|
||||
*/
|
||||
Document*
|
||||
__mkd_new_Document()
|
||||
{
|
||||
Document *ret = calloc(sizeof(Document), 1);
|
||||
|
||||
if ( ret ) {
|
||||
if ( ret->ctx = calloc(sizeof(MMIOT), 1) ) {
|
||||
ret->magic = VALID_DOCUMENT;
|
||||
return ret;
|
||||
}
|
||||
free(ret);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* add a line to the markdown input chain, expanding tabs and
|
||||
* noting the presence of special characters as we go.
|
||||
*/
|
||||
void
|
||||
__mkd_enqueue(Document* a, Cstring *line)
|
||||
{
|
||||
Line *p = calloc(sizeof *p, 1);
|
||||
unsigned char c;
|
||||
int xp = 0;
|
||||
int size = S(*line);
|
||||
unsigned char *str = (unsigned char*)T(*line);
|
||||
|
||||
CREATE(p->text);
|
||||
ATTACH(a->content, p);
|
||||
|
||||
while ( size-- ) {
|
||||
if ( (c = *str++) == '\t' ) {
|
||||
/* expand tabs into ->tabstop spaces. We use ->tabstop
|
||||
* because the ENTIRE FREAKING COMPUTER WORLD uses editors
|
||||
* that don't do ^T/^D, but instead use tabs for indentation,
|
||||
* and, of course, set their tabs down to 4 spaces
|
||||
*/
|
||||
do {
|
||||
EXPAND(p->text) = ' ';
|
||||
} while ( ++xp % a->tabstop );
|
||||
}
|
||||
else if ( c >= ' ' ) {
|
||||
if ( c == '|' )
|
||||
p->flags |= PIPECHAR;
|
||||
EXPAND(p->text) = c;
|
||||
++xp;
|
||||
}
|
||||
}
|
||||
EXPAND(p->text) = 0;
|
||||
S(p->text)--;
|
||||
p->dle = mkd_firstnonblank(p);
|
||||
}
|
||||
|
||||
|
||||
/* trim leading blanks from a header line
|
||||
*/
|
||||
void
|
||||
__mkd_header_dle(Line *p)
|
||||
{
|
||||
CLIP(p->text, 0, 1);
|
||||
p->dle = mkd_firstnonblank(p);
|
||||
}
|
||||
|
||||
|
||||
/* build a Document from any old input.
|
||||
*/
|
||||
typedef int (*getc_func)(void*);
|
||||
|
||||
Document *
|
||||
populate(getc_func getc, void* ctx, int flags)
|
||||
{
|
||||
Cstring line;
|
||||
Document *a = __mkd_new_Document();
|
||||
int c;
|
||||
int pandoc = 0;
|
||||
|
||||
if ( !a ) return 0;
|
||||
|
||||
a->tabstop = (flags & MKD_TABSTOP) ? 4 : TABSTOP;
|
||||
|
||||
CREATE(line);
|
||||
|
||||
while ( (c = (*getc)(ctx)) != EOF ) {
|
||||
if ( c == '\n' ) {
|
||||
if ( pandoc != EOF && pandoc < 3 ) {
|
||||
if ( S(line) && (T(line)[0] == '%') )
|
||||
pandoc++;
|
||||
else
|
||||
pandoc = EOF;
|
||||
}
|
||||
__mkd_enqueue(a, &line);
|
||||
S(line) = 0;
|
||||
}
|
||||
else if ( isprint(c) || isspace(c) || (c & 0x80) )
|
||||
EXPAND(line) = c;
|
||||
}
|
||||
|
||||
if ( S(line) )
|
||||
__mkd_enqueue(a, &line);
|
||||
|
||||
DELETE(line);
|
||||
|
||||
if ( (pandoc == 3) && !(flags & (MKD_NOHEADER|MKD_STRICT)) ) {
|
||||
/* the first three lines started with %, so we have a header.
|
||||
* clip the first three lines out of content and hang them
|
||||
* off header.
|
||||
*/
|
||||
Line *headers = T(a->content);
|
||||
|
||||
a->title = headers; __mkd_header_dle(a->title);
|
||||
a->author= headers->next; __mkd_header_dle(a->author);
|
||||
a->date = headers->next->next; __mkd_header_dle(a->date);
|
||||
|
||||
T(a->content) = headers->next->next->next;
|
||||
}
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
/* convert a file into a linked list
|
||||
*/
|
||||
Document *
|
||||
mkd_in(FILE *f, DWORD flags)
|
||||
{
|
||||
return populate((getc_func)fgetc, f, flags & INPUT_MASK);
|
||||
}
|
||||
|
||||
|
||||
/* return a single character out of a buffer
|
||||
*/
|
||||
int
|
||||
__mkd_io_strget(struct string_stream *in)
|
||||
{
|
||||
if ( !in->size ) return EOF;
|
||||
|
||||
--(in->size);
|
||||
|
||||
return *(in->data)++;
|
||||
}
|
||||
|
||||
|
||||
/* convert a block of text into a linked list
|
||||
*/
|
||||
Document *
|
||||
mkd_string(const char *buf, int len, DWORD flags)
|
||||
{
|
||||
struct string_stream about;
|
||||
|
||||
about.data = buf;
|
||||
about.size = len;
|
||||
|
||||
return populate((getc_func)__mkd_io_strget, &about, flags & INPUT_MASK);
|
||||
}
|
||||
|
||||
|
||||
/* write the html to a file (xmlified if necessary)
|
||||
*/
|
||||
int
|
||||
mkd_generatehtml(Document *p, FILE *output)
|
||||
{
|
||||
char *doc;
|
||||
int szdoc;
|
||||
|
||||
if ( (szdoc = mkd_document(p, &doc)) != EOF ) {
|
||||
if ( p->ctx->flags & MKD_CDATA )
|
||||
mkd_generatexml(doc, szdoc, output);
|
||||
else
|
||||
fwrite(doc, szdoc, 1, output);
|
||||
putc('\n', output);
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/* convert some markdown text to html
|
||||
*/
|
||||
int
|
||||
markdown(Document *document, FILE *out, int flags)
|
||||
{
|
||||
if ( mkd_compile(document, flags) ) {
|
||||
mkd_generatehtml(document, out);
|
||||
mkd_cleanup(document);
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/* write out a Cstring, mangled into a form suitable for `<a href=` or `<a id=`
|
||||
*/
|
||||
void
|
||||
mkd_string_to_anchor(char *s, int len, mkd_sta_function_t outchar,
|
||||
void *out, int labelformat)
|
||||
{
|
||||
#if WITH_URLENCODED_ANCHOR
|
||||
static const unsigned char hexchars[] = "0123456789abcdef";
|
||||
#endif
|
||||
unsigned char c;
|
||||
|
||||
int i, size;
|
||||
char *line;
|
||||
|
||||
size = mkd_line(s, len, &line, IS_LABEL);
|
||||
|
||||
#if !WITH_URLENCODED_ANCHOR
|
||||
if ( labelformat && (size>0) && !isalpha(line[0]) )
|
||||
(*outchar)('L',out);
|
||||
#endif
|
||||
for ( i=0; i < size ; i++ ) {
|
||||
c = line[i];
|
||||
if ( labelformat ) {
|
||||
if ( isalnum(c) || (c == '_') || (c == ':') || (c == '-') || (c == '.' ) )
|
||||
(*outchar)(c, out);
|
||||
else
|
||||
#if WITH_URLENCODED_ANCHOR
|
||||
{
|
||||
(*outchar)('%', out);
|
||||
(*outchar)(hexchars[c >> 4 & 0xf], out);
|
||||
(*outchar)(hexchars[c & 0xf], out);
|
||||
}
|
||||
#else
|
||||
(*outchar)('.', out);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
(*outchar)(c,out);
|
||||
}
|
||||
|
||||
if (line)
|
||||
free(line);
|
||||
}
|
||||
|
||||
|
||||
/* ___mkd_reparse() a line
|
||||
*/
|
||||
static void
|
||||
mkd_parse_line(char *bfr, int size, MMIOT *f, int flags)
|
||||
{
|
||||
___mkd_initmmiot(f, 0);
|
||||
f->flags = flags & USER_FLAGS;
|
||||
___mkd_reparse(bfr, size, 0, f, 0);
|
||||
___mkd_emblock(f);
|
||||
}
|
||||
|
||||
|
||||
/* ___mkd_reparse() a line, returning it in malloc()ed memory
|
||||
*/
|
||||
int
|
||||
mkd_line(char *bfr, int size, char **res, DWORD flags)
|
||||
{
|
||||
MMIOT f;
|
||||
int len;
|
||||
|
||||
mkd_parse_line(bfr, size, &f, flags);
|
||||
|
||||
if ( len = S(f.out) ) {
|
||||
/* kludge alert; we know that T(f.out) is malloced memory,
|
||||
* so we can just steal it away. This is awful -- there
|
||||
* should be an opaque method that transparently moves
|
||||
* the pointer out of the embedded Cstring.
|
||||
*/
|
||||
EXPAND(f.out) = 0;
|
||||
*res = T(f.out);
|
||||
T(f.out) = 0;
|
||||
S(f.out) = ALLOCATED(f.out) = 0;
|
||||
}
|
||||
else {
|
||||
*res = 0;
|
||||
len = EOF;
|
||||
}
|
||||
___mkd_freemmiot(&f, 0);
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
/* ___mkd_reparse() a line, writing it to a FILE
|
||||
*/
|
||||
int
|
||||
mkd_generateline(char *bfr, int size, FILE *output, DWORD flags)
|
||||
{
|
||||
MMIOT f;
|
||||
|
||||
mkd_parse_line(bfr, size, &f, flags);
|
||||
if ( flags & MKD_CDATA )
|
||||
mkd_generatexml(T(f.out), S(f.out), output);
|
||||
else
|
||||
fwrite(T(f.out), S(f.out), 1, output);
|
||||
|
||||
___mkd_freemmiot(&f, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* set the url display callback
|
||||
*/
|
||||
void
|
||||
mkd_e_url(Document *f, mkd_callback_t edit)
|
||||
{
|
||||
if ( f )
|
||||
f->cb.e_url = edit;
|
||||
}
|
||||
|
||||
|
||||
/* set the url options callback
|
||||
*/
|
||||
void
|
||||
mkd_e_flags(Document *f, mkd_callback_t edit)
|
||||
{
|
||||
if ( f )
|
||||
f->cb.e_flags = edit;
|
||||
}
|
||||
|
||||
|
||||
/* set the url display/options deallocator
|
||||
*/
|
||||
void
|
||||
mkd_e_free(Document *f, mkd_free_t dealloc)
|
||||
{
|
||||
if ( f )
|
||||
f->cb.e_free = dealloc;
|
||||
}
|
||||
|
||||
|
||||
/* set the url display/options context data field
|
||||
*/
|
||||
void
|
||||
mkd_e_data(Document *f, void *data)
|
||||
{
|
||||
if ( f )
|
||||
f->cb.e_data = data;
|
||||
}
|
||||
|
||||
|
||||
/* set the href prefix for markdown extra style footnotes
|
||||
*/
|
||||
void
|
||||
mkd_ref_prefix(Document *f, char *data)
|
||||
{
|
||||
if ( f )
|
||||
f->ref_prefix = data;
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
#ifndef _MKDIO_D
|
||||
#define _MKDIO_D
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
typedef void MMIOT;
|
||||
|
||||
typedef unsigned int mkd_flag_t;
|
||||
|
||||
/* line builder for markdown()
|
||||
*/
|
||||
MMIOT *mkd_in(FILE*,mkd_flag_t); /* assemble input from a file */
|
||||
MMIOT *mkd_string(const char*,int,mkd_flag_t); /* assemble input from a buffer */
|
||||
|
||||
/* line builder for github flavoured markdown
|
||||
*/
|
||||
MMIOT *gfm_in(FILE*,mkd_flag_t); /* assemble input from a file */
|
||||
MMIOT *gfm_string(const char*,int,mkd_flag_t); /* assemble input from a buffer */
|
||||
|
||||
void mkd_basename(MMIOT*,char*);
|
||||
|
||||
void mkd_initialize();
|
||||
void mkd_with_html5_tags();
|
||||
void mkd_shlib_destructor();
|
||||
|
||||
/* compilation, debugging, cleanup
|
||||
*/
|
||||
int mkd_compile(MMIOT*, mkd_flag_t);
|
||||
void mkd_cleanup(MMIOT*);
|
||||
|
||||
/* markup functions
|
||||
*/
|
||||
int mkd_dump(MMIOT*, FILE*, int, char*);
|
||||
int markdown(MMIOT*, FILE*, mkd_flag_t);
|
||||
int mkd_line(char *, int, char **, mkd_flag_t);
|
||||
typedef int (*mkd_sta_function_t)(const int,const void*);
|
||||
void mkd_string_to_anchor(char *, int, mkd_sta_function_t, void*, int);
|
||||
int mkd_xhtmlpage(MMIOT*,int,FILE*);
|
||||
|
||||
/* header block access
|
||||
*/
|
||||
char* mkd_doc_title(MMIOT*);
|
||||
char* mkd_doc_author(MMIOT*);
|
||||
char* mkd_doc_date(MMIOT*);
|
||||
|
||||
/* compiled data access
|
||||
*/
|
||||
int mkd_document(MMIOT*, char**);
|
||||
int mkd_toc(MMIOT*, char**);
|
||||
int mkd_css(MMIOT*, char **);
|
||||
int mkd_xml(char *, int, char **);
|
||||
|
||||
/* write-to-file functions
|
||||
*/
|
||||
int mkd_generatehtml(MMIOT*,FILE*);
|
||||
int mkd_generatetoc(MMIOT*,FILE*);
|
||||
int mkd_generatexml(char *, int,FILE*);
|
||||
int mkd_generatecss(MMIOT*,FILE*);
|
||||
#define mkd_style mkd_generatecss
|
||||
int mkd_generateline(char *, int, FILE*, mkd_flag_t);
|
||||
#define mkd_text mkd_generateline
|
||||
|
||||
/* url generator callbacks
|
||||
*/
|
||||
typedef char * (*mkd_callback_t)(const char*, const int, void*);
|
||||
typedef void (*mkd_free_t)(char*, void*);
|
||||
|
||||
void mkd_e_url(void *, mkd_callback_t);
|
||||
void mkd_e_flags(void *, mkd_callback_t);
|
||||
void mkd_e_free(void *, mkd_free_t );
|
||||
void mkd_e_data(void *, void *);
|
||||
|
||||
/* version#.
|
||||
*/
|
||||
extern char markdown_version[];
|
||||
void mkd_mmiot_flags(FILE *, MMIOT *, int);
|
||||
void mkd_flags_are(FILE*, mkd_flag_t, int);
|
||||
|
||||
void mkd_ref_prefix(MMIOT*, char*);
|
||||
|
||||
|
||||
/* special flags for markdown() and mkd_text()
|
||||
*/
|
||||
#define MKD_NOLINKS 0x00000001 /* don't do link processing, block <a> tags */
|
||||
#define MKD_NOIMAGE 0x00000002 /* don't do image processing, block <img> */
|
||||
#define MKD_NOPANTS 0x00000004 /* don't run smartypants() */
|
||||
#define MKD_NOHTML 0x00000008 /* don't allow raw html through AT ALL */
|
||||
#define MKD_STRICT 0x00000010 /* disable SUPERSCRIPT, RELAXED_EMPHASIS */
|
||||
#define MKD_TAGTEXT 0x00000020 /* process text inside an html tag; no
|
||||
* <em>, no <bold>, no html or [] expansion */
|
||||
#define MKD_NO_EXT 0x00000040 /* don't allow pseudo-protocols */
|
||||
#define MKD_NOEXT MKD_NO_EXT /* ^^^ (aliased for user convenience) */
|
||||
#define MKD_CDATA 0x00000080 /* generate code for xml ![CDATA[...]] */
|
||||
#define MKD_NOSUPERSCRIPT 0x00000100 /* no A^B */
|
||||
#define MKD_NORELAXED 0x00000200 /* emphasis happens /everywhere/ */
|
||||
#define MKD_NOTABLES 0x00000400 /* disallow tables */
|
||||
#define MKD_NOSTRIKETHROUGH 0x00000800 /* forbid ~~strikethrough~~ */
|
||||
#define MKD_TOC 0x00001000 /* do table-of-contents processing */
|
||||
#define MKD_1_COMPAT 0x00002000 /* compatibility with MarkdownTest_1.0 */
|
||||
#define MKD_AUTOLINK 0x00004000 /* make http://foo.com link even without <>s */
|
||||
#define MKD_SAFELINK 0x00008000 /* paranoid check for link protocol */
|
||||
#define MKD_NOHEADER 0x00010000 /* don't process header blocks */
|
||||
#define MKD_TABSTOP 0x00020000 /* expand tabs to 4 spaces */
|
||||
#define MKD_NODIVQUOTE 0x00040000 /* forbid >%class% blocks */
|
||||
#define MKD_NOALPHALIST 0x00080000 /* forbid alphabetic lists */
|
||||
#define MKD_NODLIST 0x00100000 /* forbid definition lists */
|
||||
#define MKD_EXTRA_FOOTNOTE 0x00200000 /* enable markdown extra-style footnotes */
|
||||
#define MKD_NOSTYLE 0x00400000 /* don't extract <style> blocks */
|
||||
#define MKD_EMBED MKD_NOLINKS|MKD_NOIMAGE|MKD_TAGTEXT
|
||||
|
||||
/* special flags for mkd_in() and mkd_string()
|
||||
*/
|
||||
|
||||
|
||||
#endif/*_MKDIO_D*/
|
||||
@@ -0,0 +1,115 @@
|
||||
#ifndef _MKDIO_D
|
||||
#define _MKDIO_D
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
typedef void MMIOT;
|
||||
|
||||
typedef @DWORD@ mkd_flag_t;
|
||||
|
||||
/* line builder for markdown()
|
||||
*/
|
||||
MMIOT *mkd_in(FILE*,mkd_flag_t); /* assemble input from a file */
|
||||
MMIOT *mkd_string(const char*,int,mkd_flag_t); /* assemble input from a buffer */
|
||||
|
||||
/* line builder for github flavoured markdown
|
||||
*/
|
||||
MMIOT *gfm_in(FILE*,mkd_flag_t); /* assemble input from a file */
|
||||
MMIOT *gfm_string(const char*,int,mkd_flag_t); /* assemble input from a buffer */
|
||||
|
||||
void mkd_basename(MMIOT*,char*);
|
||||
|
||||
void mkd_initialize();
|
||||
void mkd_with_html5_tags();
|
||||
void mkd_shlib_destructor();
|
||||
|
||||
/* compilation, debugging, cleanup
|
||||
*/
|
||||
int mkd_compile(MMIOT*, mkd_flag_t);
|
||||
void mkd_cleanup(MMIOT*);
|
||||
|
||||
/* markup functions
|
||||
*/
|
||||
int mkd_dump(MMIOT*, FILE*, int, char*);
|
||||
int markdown(MMIOT*, FILE*, mkd_flag_t);
|
||||
int mkd_line(char *, int, char **, mkd_flag_t);
|
||||
typedef int (*mkd_sta_function_t)(const int,const void*);
|
||||
void mkd_string_to_anchor(char *, int, mkd_sta_function_t, void*, int);
|
||||
int mkd_xhtmlpage(MMIOT*,int,FILE*);
|
||||
|
||||
/* header block access
|
||||
*/
|
||||
char* mkd_doc_title(MMIOT*);
|
||||
char* mkd_doc_author(MMIOT*);
|
||||
char* mkd_doc_date(MMIOT*);
|
||||
|
||||
/* compiled data access
|
||||
*/
|
||||
int mkd_document(MMIOT*, char**);
|
||||
int mkd_toc(MMIOT*, char**);
|
||||
int mkd_css(MMIOT*, char **);
|
||||
int mkd_xml(char *, int, char **);
|
||||
|
||||
/* write-to-file functions
|
||||
*/
|
||||
int mkd_generatehtml(MMIOT*,FILE*);
|
||||
int mkd_generatetoc(MMIOT*,FILE*);
|
||||
int mkd_generatexml(char *, int,FILE*);
|
||||
int mkd_generatecss(MMIOT*,FILE*);
|
||||
#define mkd_style mkd_generatecss
|
||||
int mkd_generateline(char *, int, FILE*, mkd_flag_t);
|
||||
#define mkd_text mkd_generateline
|
||||
|
||||
/* url generator callbacks
|
||||
*/
|
||||
typedef char * (*mkd_callback_t)(const char*, const int, void*);
|
||||
typedef void (*mkd_free_t)(char*, void*);
|
||||
|
||||
void mkd_e_url(void *, mkd_callback_t);
|
||||
void mkd_e_flags(void *, mkd_callback_t);
|
||||
void mkd_e_free(void *, mkd_free_t );
|
||||
void mkd_e_data(void *, void *);
|
||||
|
||||
/* version#.
|
||||
*/
|
||||
extern char markdown_version[];
|
||||
void mkd_mmiot_flags(FILE *, MMIOT *, int);
|
||||
void mkd_flags_are(FILE*, mkd_flag_t, int);
|
||||
|
||||
void mkd_ref_prefix(MMIOT*, char*);
|
||||
|
||||
|
||||
/* special flags for markdown() and mkd_text()
|
||||
*/
|
||||
#define MKD_NOLINKS 0x00000001 /* don't do link processing, block <a> tags */
|
||||
#define MKD_NOIMAGE 0x00000002 /* don't do image processing, block <img> */
|
||||
#define MKD_NOPANTS 0x00000004 /* don't run smartypants() */
|
||||
#define MKD_NOHTML 0x00000008 /* don't allow raw html through AT ALL */
|
||||
#define MKD_STRICT 0x00000010 /* disable SUPERSCRIPT, RELAXED_EMPHASIS */
|
||||
#define MKD_TAGTEXT 0x00000020 /* process text inside an html tag; no
|
||||
* <em>, no <bold>, no html or [] expansion */
|
||||
#define MKD_NO_EXT 0x00000040 /* don't allow pseudo-protocols */
|
||||
#define MKD_NOEXT MKD_NO_EXT /* ^^^ (aliased for user convenience) */
|
||||
#define MKD_CDATA 0x00000080 /* generate code for xml ![CDATA[...]] */
|
||||
#define MKD_NOSUPERSCRIPT 0x00000100 /* no A^B */
|
||||
#define MKD_NORELAXED 0x00000200 /* emphasis happens /everywhere/ */
|
||||
#define MKD_NOTABLES 0x00000400 /* disallow tables */
|
||||
#define MKD_NOSTRIKETHROUGH 0x00000800 /* forbid ~~strikethrough~~ */
|
||||
#define MKD_TOC 0x00001000 /* do table-of-contents processing */
|
||||
#define MKD_1_COMPAT 0x00002000 /* compatibility with MarkdownTest_1.0 */
|
||||
#define MKD_AUTOLINK 0x00004000 /* make http://foo.com link even without <>s */
|
||||
#define MKD_SAFELINK 0x00008000 /* paranoid check for link protocol */
|
||||
#define MKD_NOHEADER 0x00010000 /* don't process header blocks */
|
||||
#define MKD_TABSTOP 0x00020000 /* expand tabs to 4 spaces */
|
||||
#define MKD_NODIVQUOTE 0x00040000 /* forbid >%class% blocks */
|
||||
#define MKD_NOALPHALIST 0x00080000 /* forbid alphabetic lists */
|
||||
#define MKD_NODLIST 0x00100000 /* forbid definition lists */
|
||||
#define MKD_EXTRA_FOOTNOTE 0x00200000 /* enable markdown extra-style footnotes */
|
||||
#define MKD_NOSTYLE 0x00400000 /* don't extract <style> blocks */
|
||||
#define MKD_EMBED MKD_NOLINKS|MKD_NOIMAGE|MKD_TAGTEXT
|
||||
|
||||
/* special flags for mkd_in() and mkd_string()
|
||||
*/
|
||||
|
||||
|
||||
#endif/*_MKDIO_D*/
|
||||
@@ -0,0 +1,89 @@
|
||||
/* block-level tags for passing html blocks through the blender
|
||||
*/
|
||||
#include <stdio.h>
|
||||
|
||||
#define __WITHOUT_AMALLOC 1
|
||||
#include "cstring.h"
|
||||
#include "tags.h"
|
||||
|
||||
STRING(struct kw) blocktags;
|
||||
|
||||
|
||||
/* define a html block tag
|
||||
*/
|
||||
static void
|
||||
define_one_tag(char *id, int selfclose)
|
||||
{
|
||||
struct kw *p = &EXPAND(blocktags);
|
||||
|
||||
p->id = id;
|
||||
p->size = strlen(id);
|
||||
p->selfclose = selfclose;
|
||||
}
|
||||
|
||||
|
||||
/* case insensitive string sort (for qsort() and bsearch() of block tags)
|
||||
*/
|
||||
static int
|
||||
casort(struct kw *a, struct kw *b)
|
||||
{
|
||||
if ( a->size != b->size )
|
||||
return a->size - b->size;
|
||||
return strncasecmp(a->id, b->id, b->size);
|
||||
}
|
||||
|
||||
|
||||
/* stupid cast to make gcc shut up about the function types being
|
||||
* passed into qsort() and bsearch()
|
||||
*/
|
||||
typedef int (*stfu)(const void*,const void*);
|
||||
|
||||
|
||||
/* load in the standard collection of html tags that markdown supports
|
||||
*/
|
||||
main()
|
||||
{
|
||||
int i;
|
||||
|
||||
#define KW(x) define_one_tag(x, 0)
|
||||
#define SC(x) define_one_tag(x, 1)
|
||||
|
||||
KW("STYLE");
|
||||
KW("SCRIPT");
|
||||
KW("ADDRESS");
|
||||
KW("BDO");
|
||||
KW("BLOCKQUOTE");
|
||||
KW("CENTER");
|
||||
KW("DFN");
|
||||
KW("DIV");
|
||||
KW("OBJECT");
|
||||
KW("H1");
|
||||
KW("H2");
|
||||
KW("H3");
|
||||
KW("H4");
|
||||
KW("H5");
|
||||
KW("H6");
|
||||
KW("LISTING");
|
||||
KW("NOBR");
|
||||
KW("UL");
|
||||
KW("P");
|
||||
KW("OL");
|
||||
KW("DL");
|
||||
KW("PLAINTEXT");
|
||||
KW("PRE");
|
||||
KW("TABLE");
|
||||
KW("WBR");
|
||||
KW("XMP");
|
||||
SC("HR");
|
||||
KW("IFRAME");
|
||||
KW("MAP");
|
||||
|
||||
qsort(T(blocktags), S(blocktags), sizeof(struct kw), (stfu)casort);
|
||||
|
||||
printf("static struct kw blocktags[] = {\n");
|
||||
for (i=0; i < S(blocktags); i++)
|
||||
printf(" { \"%s\", %d, %d },\n", T(blocktags)[i].id, T(blocktags)[i].size, T(blocktags)[i].selfclose );
|
||||
printf("};\n\n");
|
||||
printf("#define NR_blocktags %d\n", S(blocktags));
|
||||
exit(0);
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
/* markdown: a C implementation of John Gruber's Markdown markup language.
|
||||
*
|
||||
* Copyright (C) 2007-2011 David L Parsons.
|
||||
* The redistribution terms are provided in the COPYRIGHT file that must
|
||||
* be distributed with this source code.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
#include <unistd.h>
|
||||
#include <mkdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "amalloc.h"
|
||||
|
||||
#if HAVE_LIBGEN_H
|
||||
#include <libgen.h>
|
||||
#endif
|
||||
|
||||
static struct _opt {
|
||||
char *name;
|
||||
char *desc;
|
||||
int off;
|
||||
int skip;
|
||||
int sayenable;
|
||||
mkd_flag_t flag;
|
||||
} opts[] = {
|
||||
{ "tabstop", "default (4-space) tabstops", 0, 0, 1, MKD_TABSTOP },
|
||||
{ "image", "images", 1, 0, 1, MKD_NOIMAGE },
|
||||
{ "links", "links", 1, 0, 1, MKD_NOLINKS },
|
||||
{ "relax", "emphasis inside words", 1, 1, 1, MKD_STRICT },
|
||||
{ "strict", "emphasis inside words", 0, 0, 1, MKD_STRICT },
|
||||
{ "tables", "tables", 1, 0, 1, MKD_NOTABLES },
|
||||
{ "header", "pandoc-style headers", 1, 0, 1, MKD_NOHEADER },
|
||||
{ "html", "raw html", 1, 0, 1, MKD_NOHTML },
|
||||
{ "ext", "extended protocols", 1, 0, 1, MKD_NO_EXT },
|
||||
{ "cdata", "generate cdata", 0, 0, 0, MKD_CDATA },
|
||||
{ "smarty", "smartypants", 1, 0, 1, MKD_NOPANTS },
|
||||
{ "pants", "smartypants", 1, 1, 1, MKD_NOPANTS },
|
||||
{ "toc", "tables of contents", 0, 0, 1, MKD_TOC },
|
||||
{ "autolink", "autolinking", 0, 0, 1, MKD_AUTOLINK },
|
||||
{ "safelink", "safe links", 0, 0, 1, MKD_SAFELINK },
|
||||
{ "strikethrough", "strikethrough", 1, 0, 1, MKD_NOSTRIKETHROUGH },
|
||||
{ "del", "strikethrough", 1, 1, 1, MKD_NOSTRIKETHROUGH },
|
||||
{ "superscript", "superscript", 1, 0, 1, MKD_NOSUPERSCRIPT },
|
||||
{ "emphasis", "emphasis inside words", 0, 0, 1, MKD_NORELAXED },
|
||||
{ "divquote", ">%class% blockquotes", 1, 0, 1, MKD_NODIVQUOTE },
|
||||
{ "alphalist", "alpha lists", 1, 0, 1, MKD_NOALPHALIST },
|
||||
{ "definitionlist","definition lists", 1, 0, 1, MKD_NODLIST },
|
||||
{ "1.0", "markdown 1.0 compatibility", 0, 0, 1, MKD_1_COMPAT },
|
||||
{ "footnotes", "markdown extra footnotes", 0, 0, 1, MKD_EXTRA_FOOTNOTE },
|
||||
{ "footnote", "markdown extra footnotes", 0, 1, 1, MKD_EXTRA_FOOTNOTE },
|
||||
{ "style", "extract style blocks", 1, 0, 1, MKD_NOSTYLE },
|
||||
} ;
|
||||
|
||||
#define NR(x) (sizeof x / sizeof x[0])
|
||||
|
||||
|
||||
typedef int (*stfu)(const void *, const void *);
|
||||
|
||||
int
|
||||
sort_by_name(struct _opt *a, struct _opt *b)
|
||||
{
|
||||
return strcmp(a->name,b->name);
|
||||
}
|
||||
|
||||
int
|
||||
sort_by_flag(struct _opt *a, struct _opt *b)
|
||||
{
|
||||
return a->flag - b->flag;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
show_flags(int byname)
|
||||
{
|
||||
int i;
|
||||
|
||||
if ( byname ) {
|
||||
qsort(opts, NR(opts), sizeof(opts[0]), (stfu)sort_by_name);
|
||||
|
||||
for (i=0; i < NR(opts); i++)
|
||||
if ( ! opts[i].skip )
|
||||
fprintf(stderr, "%16s : %s\n", opts[i].name, opts[i].desc);
|
||||
}
|
||||
else {
|
||||
qsort(opts, NR(opts), sizeof(opts[0]), (stfu)sort_by_flag);
|
||||
|
||||
for (i=0; i < NR(opts); i++)
|
||||
if ( ! opts[i].skip ) {
|
||||
fprintf(stderr, "%08lx : ", (long)opts[i].flag);
|
||||
if ( opts[i].sayenable )
|
||||
fprintf(stderr, opts[i].off ? "disable " : "enable ");
|
||||
fprintf(stderr, "%s\n", opts[i].desc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
set_flag(mkd_flag_t *flags, char *optionstring)
|
||||
{
|
||||
int i;
|
||||
int enable;
|
||||
char *arg;
|
||||
|
||||
for ( arg = strtok(optionstring, ","); arg; arg = strtok(NULL, ",") ) {
|
||||
if ( *arg == '+' || *arg == '-' )
|
||||
enable = (*arg++ == '+') ? 1 : 0;
|
||||
else if ( strncasecmp(arg, "no", 2) == 0 ) {
|
||||
arg += 2;
|
||||
enable = 0;
|
||||
}
|
||||
else
|
||||
enable = 1;
|
||||
|
||||
for ( i=0; i < NR(opts); i++ )
|
||||
if ( strcasecmp(arg, opts[i].name) == 0 )
|
||||
break;
|
||||
|
||||
if ( i < NR(opts) ) {
|
||||
if ( opts[i].off )
|
||||
enable = !enable;
|
||||
|
||||
if ( enable )
|
||||
*flags |= opts[i].flag;
|
||||
else
|
||||
*flags &= ~opts[i].flag;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
#ifndef PGM_OPTIONS_D
|
||||
#define PGM_OPTIONS_D
|
||||
|
||||
#include <mkdio.h>
|
||||
|
||||
int set_flag(mkd_flag_t *flags, char *optionstring);
|
||||
void show_flags(int byname);
|
||||
|
||||
#endif/*PGM_OPTIONS_D*/
|
||||
@@ -0,0 +1,159 @@
|
||||
/* markdown: a C implementation of John Gruber's Markdown markup language.
|
||||
*
|
||||
* Copyright (C) 2007 David L Parsons.
|
||||
* The redistribution terms are provided in the COPYRIGHT file that must
|
||||
* be distributed with this source code.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "cstring.h"
|
||||
#include "markdown.h"
|
||||
#include "amalloc.h"
|
||||
|
||||
/* free a (single) line
|
||||
*/
|
||||
void
|
||||
___mkd_freeLine(Line *ptr)
|
||||
{
|
||||
DELETE(ptr->text);
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
|
||||
/* free a list of lines
|
||||
*/
|
||||
void
|
||||
___mkd_freeLines(Line *p)
|
||||
{
|
||||
if (p->next)
|
||||
___mkd_freeLines(p->next);
|
||||
___mkd_freeLine(p);
|
||||
}
|
||||
|
||||
|
||||
/* bye bye paragraph.
|
||||
*/
|
||||
void
|
||||
___mkd_freeParagraph(Paragraph *p)
|
||||
{
|
||||
if (p->next)
|
||||
___mkd_freeParagraph(p->next);
|
||||
if (p->down)
|
||||
___mkd_freeParagraph(p->down);
|
||||
if (p->text)
|
||||
___mkd_freeLines(p->text);
|
||||
if (p->ident)
|
||||
free(p->ident);
|
||||
if (p->lang)
|
||||
free(p->lang);
|
||||
free(p);
|
||||
}
|
||||
|
||||
|
||||
/* bye bye footnote.
|
||||
*/
|
||||
void
|
||||
___mkd_freefootnote(Footnote *f)
|
||||
{
|
||||
DELETE(f->tag);
|
||||
DELETE(f->link);
|
||||
DELETE(f->title);
|
||||
}
|
||||
|
||||
|
||||
/* bye bye footnotes.
|
||||
*/
|
||||
void
|
||||
___mkd_freefootnotes(MMIOT *f)
|
||||
{
|
||||
int i;
|
||||
|
||||
if ( f->footnotes ) {
|
||||
for (i=0; i < S(f->footnotes->note); i++)
|
||||
___mkd_freefootnote( &T(f->footnotes->note)[i] );
|
||||
DELETE(f->footnotes->note);
|
||||
free(f->footnotes);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* initialize a new MMIOT
|
||||
*/
|
||||
void
|
||||
___mkd_initmmiot(MMIOT *f, void *footnotes)
|
||||
{
|
||||
if ( f ) {
|
||||
memset(f, 0, sizeof *f);
|
||||
CREATE(f->in);
|
||||
CREATE(f->out);
|
||||
CREATE(f->Q);
|
||||
if ( footnotes )
|
||||
f->footnotes = footnotes;
|
||||
else {
|
||||
f->footnotes = malloc(sizeof f->footnotes[0]);
|
||||
CREATE(f->footnotes->note);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* free the contents of a MMIOT, but leave the object alone.
|
||||
*/
|
||||
void
|
||||
___mkd_freemmiot(MMIOT *f, void *footnotes)
|
||||
{
|
||||
if ( f ) {
|
||||
DELETE(f->in);
|
||||
DELETE(f->out);
|
||||
DELETE(f->Q);
|
||||
if ( f->footnotes != footnotes )
|
||||
___mkd_freefootnotes(f);
|
||||
memset(f, 0, sizeof *f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* free lines up to an barrier.
|
||||
*/
|
||||
void
|
||||
___mkd_freeLineRange(Line *anchor, Line *stop)
|
||||
{
|
||||
Line *r = anchor->next;
|
||||
|
||||
if ( r != stop ) {
|
||||
while ( r && (r->next != stop) )
|
||||
r = r->next;
|
||||
if ( r ) r->next = 0;
|
||||
___mkd_freeLines(anchor->next);
|
||||
}
|
||||
anchor->next = 0;
|
||||
}
|
||||
|
||||
|
||||
/* clean up everything allocated in __mkd_compile()
|
||||
*/
|
||||
void
|
||||
mkd_cleanup(Document *doc)
|
||||
{
|
||||
if ( doc && (doc->magic == VALID_DOCUMENT) ) {
|
||||
if ( doc->ctx ) {
|
||||
___mkd_freemmiot(doc->ctx, 0);
|
||||
free(doc->ctx);
|
||||
}
|
||||
|
||||
if ( doc->code) ___mkd_freeParagraph(doc->code);
|
||||
if ( doc->title) ___mkd_freeLine(doc->title);
|
||||
if ( doc->author) ___mkd_freeLine(doc->author);
|
||||
if ( doc->date) ___mkd_freeLine(doc->date);
|
||||
if ( T(doc->content) ) ___mkd_freeLines(T(doc->content));
|
||||
memset(doc, 0, sizeof doc[0]);
|
||||
free(doc);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/* markdown: a C implementation of John Gruber's Markdown markup language.
|
||||
*
|
||||
* Copyright (C) 2007 David L Parsons.
|
||||
* The redistribution terms are provided in the COPYRIGHT file that must
|
||||
* be distributed with this source code.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "cstring.h"
|
||||
#include "markdown.h"
|
||||
#include "amalloc.h"
|
||||
#include "tags.h"
|
||||
|
||||
static int need_to_initrng = 1;
|
||||
|
||||
void
|
||||
mkd_initialize()
|
||||
{
|
||||
|
||||
if ( need_to_initrng ) {
|
||||
need_to_initrng = 0;
|
||||
INITRNG(time(0));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
mkd_shlib_destructor()
|
||||
{
|
||||
mkd_deallocate_tags();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
/* block-level tags for passing html blocks through the blender
|
||||
*/
|
||||
#define __WITHOUT_AMALLOC 1
|
||||
#include "cstring.h"
|
||||
#include "tags.h"
|
||||
|
||||
STRING(struct kw) extratags;
|
||||
|
||||
/* the standard collection of tags are built and sorted when
|
||||
* discount is configured, so all we need to do is pull them
|
||||
* in and use them.
|
||||
*
|
||||
* Additional tags still need to be allocated, sorted, and deallocated.
|
||||
*/
|
||||
#include "blocktags"
|
||||
|
||||
|
||||
/* define an additional html block tag
|
||||
*/
|
||||
void
|
||||
mkd_define_tag(char *id, int selfclose)
|
||||
{
|
||||
struct kw *p;
|
||||
|
||||
/* only add the new tag if it doesn't exist in
|
||||
* either the standard or extra tag tables.
|
||||
*/
|
||||
if ( !(p = mkd_search_tags(id, strlen(id))) ) {
|
||||
/* extratags could be deallocated */
|
||||
if ( S(extratags) == 0 )
|
||||
CREATE(extratags);
|
||||
p = &EXPAND(extratags);
|
||||
p->id = id;
|
||||
p->size = strlen(id);
|
||||
p->selfclose = selfclose;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* case insensitive string sort (for qsort() and bsearch() of block tags)
|
||||
*/
|
||||
static int
|
||||
casort(struct kw *a, struct kw *b)
|
||||
{
|
||||
if ( a->size != b->size )
|
||||
return a->size - b->size;
|
||||
return strncasecmp(a->id, b->id, b->size);
|
||||
}
|
||||
|
||||
|
||||
/* stupid cast to make gcc shut up about the function types being
|
||||
* passed into qsort() and bsearch()
|
||||
*/
|
||||
typedef int (*stfu)(const void*,const void*);
|
||||
|
||||
|
||||
/* sort the list of extra html block tags for later searching
|
||||
*/
|
||||
void
|
||||
mkd_sort_tags()
|
||||
{
|
||||
qsort(T(extratags), S(extratags), sizeof(struct kw), (stfu)casort);
|
||||
}
|
||||
|
||||
|
||||
/* look for a token in the html block tag list
|
||||
*/
|
||||
struct kw*
|
||||
mkd_search_tags(char *pat, int len)
|
||||
{
|
||||
struct kw key;
|
||||
struct kw *ret;
|
||||
|
||||
key.id = pat;
|
||||
key.size = len;
|
||||
|
||||
if ( (ret=bsearch(&key,blocktags,NR_blocktags,sizeof key,(stfu)casort)) )
|
||||
return ret;
|
||||
|
||||
if ( S(extratags) )
|
||||
return bsearch(&key,T(extratags),S(extratags),sizeof key,(stfu)casort);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* destroy the extratags list (for shared libraries)
|
||||
*/
|
||||
void
|
||||
mkd_deallocate_tags()
|
||||
{
|
||||
if ( S(extratags) > 0 )
|
||||
DELETE(extratags);
|
||||
} /* mkd_deallocate_tags */
|
||||
@@ -0,0 +1,19 @@
|
||||
/* block-level tags for passing html blocks through the blender
|
||||
*/
|
||||
#ifndef _TAGS_D
|
||||
#define _TAGS_D
|
||||
|
||||
struct kw {
|
||||
char *id;
|
||||
int size;
|
||||
int selfclose;
|
||||
} ;
|
||||
|
||||
|
||||
struct kw* mkd_search_tags(char *, int);
|
||||
void mkd_prepare_tags();
|
||||
void mkd_deallocate_tags();
|
||||
void mkd_sort_tags();
|
||||
void mkd_define_tag(char *, int);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,27 @@
|
||||
. tests/functions.sh
|
||||
|
||||
title 'Reddit-style automatic links'
|
||||
rc=0
|
||||
|
||||
try -fautolink 'single link' \
|
||||
'http://www.pell.portland.or.us/~orc/Code/discount' \
|
||||
'<p><a href="http://www.pell.portland.or.us/~orc/Code/discount">http://www.pell.portland.or.us/~orc/Code/discount</a></p>'
|
||||
|
||||
try -fautolink '[!](http://a.com "http://b.com")' \
|
||||
'[!](http://a.com "http://b.com")' \
|
||||
'<p><a href="http://a.com" title="http://b.com">!</a></p>'
|
||||
|
||||
try -fautolink 'link surrounded by text' \
|
||||
'here http://it is?' \
|
||||
'<p>here <a href="http://it">http://it</a> is?</p>'
|
||||
|
||||
try -fautolink 'naked @' '@' '<p>@</p>'
|
||||
|
||||
try -fautolink 'parenthesised (url)' \
|
||||
'(http://here)' \
|
||||
'<p>(<a href="http://here">http://here</a>)</p>'
|
||||
|
||||
try -fautolink 'token with trailing @' 'orc@' '<p>orc@</p>'
|
||||
|
||||
summary $0
|
||||
exit $rc
|
||||
@@ -0,0 +1,27 @@
|
||||
. tests/functions.sh
|
||||
|
||||
title "automatic links"
|
||||
|
||||
rc=0
|
||||
MARKDOWN_FLAGS=
|
||||
|
||||
try 'http url' '<http://here>' '<p><a href="http://here">http://here</a></p>'
|
||||
try 'ftp url' '<ftp://here>' '<p><a href="ftp://here">ftp://here</a></p>'
|
||||
try 'http://foo/bar' '<http://foo/bar>' '<p><a href="http://foo/bar">http://foo/bar</a></p>'
|
||||
try 'http:/foo/bar' '<http:/foo/bar>' '<p><a href="http:/foo/bar">http:/foo/bar</a></p>'
|
||||
try 'http:foo/bar' '<http:foo/bar>' '<p><a href="http:foo/bar">http:foo/bar</a></p>'
|
||||
try '</foo/bar>' '</foo/bar>' '<p></foo/bar></p>'
|
||||
match '<orc@pell.portland.or.us>' '<orc@pell.portland.or.us>' '<a href='
|
||||
match '<orc@pell.com.>' '<orc@pell.com.>' '<a href='
|
||||
try 'invalid <orc@>' '<orc@>' '<p><orc@></p>'
|
||||
try 'invalid <@pell>' '<@pell>' '<p><@pell></p>'
|
||||
try 'invalid <orc@pell>' '<orc@pell>' '<p><orc@pell></p>'
|
||||
try 'invalid <orc@.pell>' '<orc@.pell>' '<p><orc@.pell></p>'
|
||||
try 'invalid <orc@pell.>' '<orc@pell.>' '<p><orc@pell.></p>'
|
||||
match '<mailto:orc@pell>' '<mailto:orc@pell>' '<a href='
|
||||
match '<mailto:orc@pell.com>' '<mailto:orc@pell.com>' '<a href='
|
||||
match '<mailto:orc@>' '<mailto:orc@>' '<a href='
|
||||
match '<mailto:@pell>' '<mailto:@pell>' '<a href='
|
||||
|
||||
summary $0
|
||||
exit $rc
|
||||
@@ -0,0 +1,21 @@
|
||||
. tests/functions.sh
|
||||
|
||||
title "backslash escapes"
|
||||
|
||||
rc=0
|
||||
MARKDOWN_FLAGS=
|
||||
|
||||
try 'backslashes in []()' '[foo](http://\this\is\.a\test\(here\))' \
|
||||
'<p><a href="http://\this\is.a\test(here)">foo</a></p>'
|
||||
|
||||
try -fautolink 'autolink url with trailing \' \
|
||||
'http://a.com/\' \
|
||||
'<p><a href="http://a.com/\">http://a.com/\</a></p>'
|
||||
|
||||
|
||||
try 'backslashes before <text' '\<code>' '<p>\<code></p>'
|
||||
try 'backslashes before <{EOF}' '\<' '<p><</p>'
|
||||
try 'backslashes before <[space]' '\< j' '<p>< j</p>'
|
||||
|
||||
summary $0
|
||||
exit $rc
|
||||
@@ -0,0 +1,17 @@
|
||||
. tests/functions.sh
|
||||
|
||||
title "callbacks"
|
||||
|
||||
rc=0
|
||||
MARKDOWN_FLAGS=
|
||||
|
||||
try -bZZZ 'url modification' \
|
||||
'[a](/b)' \
|
||||
'<p><a href="ZZZ/b">a</a></p>'
|
||||
|
||||
try -EZZZ 'additional flags' \
|
||||
'[a](/b)' \
|
||||
'<p><a href="/b" ZZZ>a</a></p>'
|
||||
|
||||
summary $0
|
||||
exit $rc
|
||||
@@ -0,0 +1,13 @@
|
||||
->###chrome with my markdown###<-
|
||||
|
||||
1. `(c)` -> `©` (c)
|
||||
2. `(r)` -> `®` (r)
|
||||
3. `(tm)` -> `™` (tm)
|
||||
4. `...` -> `…` ...
|
||||
5. `--` -> `&emdash;` --
|
||||
6. `-` -> `–` - (but not if it's between-words)
|
||||
7. "fancy quoting"
|
||||
8. 'fancy quoting (#2)'
|
||||
9. don't do it unless it's a real quote.
|
||||
10. `` (`) ``
|
||||
|
||||
@@ -0,0 +1,166 @@
|
||||
. tests/functions.sh
|
||||
|
||||
title "code blocks"
|
||||
|
||||
rc=0
|
||||
MARKDOWN_FLAGS=
|
||||
|
||||
try 'format for code block html' \
|
||||
' this is
|
||||
code' \
|
||||
'<pre><code>this is
|
||||
code
|
||||
</code></pre>'
|
||||
|
||||
try 'mismatched backticks' '```tick``' '<p><code>`tick</code></p>'
|
||||
try 'mismatched backticks(2)' '``tick```' '<p>``tick```</p>'
|
||||
try 'unclosed single backtick' '`hi there' '<p>`hi there</p>'
|
||||
try 'unclosed double backtick' '``hi there' '<p>``hi there</p>'
|
||||
try 'triple backticks' '```hi there```' '<p><code>hi there</code></p>'
|
||||
try 'quadruple backticks' '````hi there````' '<p><code>hi there</code></p>'
|
||||
try 'remove space around code' '`` hi there ``' '<p><code>hi there</code></p>'
|
||||
try 'code containing backticks' '`` a```b ``' '<p><code>a```b</code></p>'
|
||||
try 'backslash before backtick' '`a\`' '<p><code>a\</code></p>'
|
||||
try '`>`' '`>`' '<p><code>></code></p>'
|
||||
try '`` ` ``' '`` ` ``' '<p><code>`</code></p>'
|
||||
try '````` ``` `' '````` ``` `' '<p><code>``</code> `</p>'
|
||||
try '````` ` ```' '````` ` ```' '<p><code>`` `</code></p>'
|
||||
try 'backslashes in code(1)' ' printf "%s: \n", $1;' \
|
||||
'<pre><code>printf "%s: \n", $1;
|
||||
</code></pre>'
|
||||
try 'backslashes in code(2)' '`printf "%s: \n", $1;`' \
|
||||
'<p><code>printf "%s: \n", $1;</code></p>'
|
||||
|
||||
if ./markdown -V | grep FENCED-CODE >/dev/null; then
|
||||
|
||||
try 'fenced code block with blank lines' \
|
||||
'~~~
|
||||
code!
|
||||
|
||||
still code!
|
||||
~~~' \
|
||||
'<pre><code>code!
|
||||
|
||||
still code!
|
||||
</code></pre>'
|
||||
|
||||
try 'fenced code block' \
|
||||
'~~~
|
||||
code!
|
||||
~~~' \
|
||||
'<pre><code>code!
|
||||
</code></pre>'
|
||||
|
||||
try 'fenced code block in list' \
|
||||
'1. ~~~
|
||||
code block
|
||||
~~~' \
|
||||
'<ol>
|
||||
<li><pre><code>code block
|
||||
</code></pre></li>
|
||||
</ol>'
|
||||
|
||||
try 'fenced code block in blockquote' \
|
||||
'>~~~
|
||||
code
|
||||
~~~' \
|
||||
'<blockquote><pre><code>code
|
||||
</code></pre></blockquote>'
|
||||
|
||||
try 'unterminated fenced code block' \
|
||||
'~~~
|
||||
code' \
|
||||
'<p>~~~
|
||||
code</p>'
|
||||
|
||||
try 'fenced code block with tildes' \
|
||||
'~~~~~
|
||||
~~~
|
||||
code with tildes
|
||||
~~~
|
||||
~~~~~' \
|
||||
'<pre><code>~~~
|
||||
code with tildes
|
||||
~~~
|
||||
</code></pre>'
|
||||
|
||||
try 'paragraph with trailing fenced block' \
|
||||
'text text text
|
||||
text text text
|
||||
~~~
|
||||
code code code?
|
||||
~~~' \
|
||||
'<p>text text text
|
||||
text text text
|
||||
~~~
|
||||
code code code?
|
||||
~~~</p>'
|
||||
|
||||
try 'fenced code blocks with backtick delimiters' \
|
||||
'```
|
||||
code
|
||||
```' \
|
||||
'<pre><code>code
|
||||
</code></pre>'
|
||||
|
||||
try 'fenced code block with mismatched delimters' \
|
||||
'```
|
||||
code
|
||||
~~~' \
|
||||
'<p>```
|
||||
code
|
||||
~~~</p>'
|
||||
|
||||
try 'fenced code block with lang attribute' \
|
||||
'```lang
|
||||
code
|
||||
```' \
|
||||
'<pre><code class="lang">code
|
||||
</code></pre>'
|
||||
|
||||
try 'fenced code block with lang-name attribute' \
|
||||
'```lang-name
|
||||
code
|
||||
```' \
|
||||
'<pre><code class="lang-name">code
|
||||
</code></pre>'
|
||||
|
||||
try 'fenced code block with lang_name attribute' \
|
||||
'```lang_name
|
||||
code
|
||||
```' \
|
||||
'<pre><code class="lang_name">code
|
||||
</code></pre>'
|
||||
|
||||
try 'fenced code block with lang attribute and space' \
|
||||
'``` lang
|
||||
code
|
||||
```' \
|
||||
'<pre><code class="lang">code
|
||||
</code></pre>'
|
||||
|
||||
try 'fenced code block with lang attribute and multiple spaces' \
|
||||
'``` lang
|
||||
code
|
||||
```' \
|
||||
'<pre><code class="lang">code
|
||||
</code></pre>'
|
||||
|
||||
try 'fenced code block with lang-name attribute and space' \
|
||||
'``` lang-name
|
||||
code
|
||||
```' \
|
||||
'<pre><code class="lang-name">code
|
||||
</code></pre>'
|
||||
|
||||
try 'fenced code block with lang_name attribute and space' \
|
||||
'``` lang_name
|
||||
code
|
||||
```' \
|
||||
'<pre><code class="lang_name">code
|
||||
</code></pre>'
|
||||
|
||||
fi
|
||||
|
||||
summary $0
|
||||
exit $rc
|
||||
@@ -0,0 +1,29 @@
|
||||
. tests/functions.sh
|
||||
|
||||
title "markdown 1.0 compatibility"
|
||||
|
||||
rc=0
|
||||
MARKDOWN_FLAGS=
|
||||
|
||||
LINKY='[this] is a test
|
||||
|
||||
[this]: /this'
|
||||
|
||||
try 'implicit reference links' "$LINKY" '<p><a href="/this">this</a> is a test</p>'
|
||||
try -f1.0 'implicit reference links (-f1.0)' "$LINKY" '<p>[this] is a test</p>'
|
||||
|
||||
WSP=' '
|
||||
WHITESPACE="
|
||||
white space$WSP
|
||||
and more"
|
||||
|
||||
try 'trailing whitespace' "$WHITESPACE" '<pre><code>white space ''
|
||||
and more
|
||||
</code></pre>'
|
||||
|
||||
try -f1.0 'trailing whitespace (-f1.0)' "$WHITESPACE" '<pre><code>white space''
|
||||
and more
|
||||
</code></pre>'
|
||||
|
||||
summary $0
|
||||
exit $rc
|
||||
@@ -0,0 +1,31 @@
|
||||
. tests/functions.sh
|
||||
|
||||
title "crashes"
|
||||
|
||||
rc=0
|
||||
MARKDOWN_FLAGS=
|
||||
|
||||
try 'zero-length input' '' ''
|
||||
|
||||
try 'hanging quote in list' \
|
||||
' * > this should not die
|
||||
|
||||
no.' \
|
||||
'<ul>
|
||||
<li><blockquote><p>this should not die</p></blockquote></li>
|
||||
</ul>
|
||||
|
||||
|
||||
<p>no.</p>'
|
||||
|
||||
try 'dangling list item' ' - ' \
|
||||
'<ul>
|
||||
<li></li>
|
||||
</ul>'
|
||||
|
||||
try -bHOHO 'empty []() with baseurl' '[]()' '<p><a href=""></a></p>'
|
||||
try 'unclosed html block' '<table></table' '<p><table></table</p>'
|
||||
try 'unclosed style block' '<style>' '<p><style></p>'
|
||||
|
||||
summary $0
|
||||
exit $rc
|
||||
@@ -0,0 +1,23 @@
|
||||
. tests/functions.sh
|
||||
|
||||
title "reported defects"
|
||||
|
||||
rc=0
|
||||
MARKDOWN_FLAGS=
|
||||
|
||||
try 'masses of non-block html' \
|
||||
'<span>foo</span><br>
|
||||
<br>
|
||||
<span>bar</span><br>' \
|
||||
'<p><span>foo</span><br>
|
||||
<br>
|
||||
<span>bar</span><br></p>'
|
||||
|
||||
try -fautolink -G 'autolink + github-flavoured markdown' \
|
||||
'http://foo
|
||||
bar' \
|
||||
'<p><a href="http://foo">http://foo</a><br/>
|
||||
bar</p>'
|
||||
|
||||
summary $0
|
||||
exit $rc
|
||||
@@ -0,0 +1,49 @@
|
||||
. tests/functions.sh
|
||||
|
||||
title "%div% blocks"
|
||||
|
||||
rc=0
|
||||
MARKDOWN_FLAGS=
|
||||
|
||||
try 'simple >%div% block' \
|
||||
'>%this%
|
||||
this this' \
|
||||
'<div class="this"><p>this this</p></div>'
|
||||
|
||||
try 'two >%div% blocks in a row' \
|
||||
'>%this%
|
||||
this this
|
||||
|
||||
>%that%
|
||||
that that' \
|
||||
'<div class="this"><p>this this</p></div>
|
||||
|
||||
<div class="that"><p>that that</p></div>'
|
||||
|
||||
try '>%class:div%' \
|
||||
'>%class:this%
|
||||
this this' \
|
||||
'<div class="this"><p>this this</p></div>'
|
||||
|
||||
try '>%id:div%' \
|
||||
'>%id:this%
|
||||
this this' \
|
||||
'<div id="this"><p>this this</p></div>'
|
||||
|
||||
try 'nested >%div%' \
|
||||
'>%this%
|
||||
>>%that%
|
||||
>>that
|
||||
|
||||
>%more%
|
||||
more' \
|
||||
'<div class="this"><div class="that"><p>that</p></div></div>
|
||||
|
||||
<div class="more"><p>more</p></div>'
|
||||
|
||||
try '%class% with _' '>%class:this_that%' '<div class="this_that"></div>'
|
||||
try '%class% with -' '>%class:this-that%' '<div class="this-that"></div>'
|
||||
try 'illegal %class%' '>%class:0zip%' '<blockquote><p>%class:0zip%</p></blockquote>'
|
||||
|
||||
summary $0
|
||||
exit $rc
|
||||
@@ -0,0 +1,91 @@
|
||||
. tests/functions.sh
|
||||
|
||||
title "definition lists"
|
||||
|
||||
eval `./markdown -V | tr ' ' '\n' | grep '^DL='`
|
||||
|
||||
DL=${DL:-BOTH}
|
||||
|
||||
rc=0
|
||||
MARKDOWN_FLAGS=
|
||||
|
||||
SRC='
|
||||
=this=
|
||||
is an ugly
|
||||
=test=
|
||||
eh?'
|
||||
|
||||
RSLT='<dl>
|
||||
<dt>this</dt>
|
||||
<dd>is an ugly</dd>
|
||||
<dt>test</dt>
|
||||
<dd>eh?</dd>
|
||||
</dl>'
|
||||
|
||||
if [ "$DL" = "DISCOUNT" -o "$DL" = "BOTH" ]; then
|
||||
try -fdefinitionlist '=tag= generates definition lists' "$SRC" "$RSLT"
|
||||
|
||||
try 'one item with two =tags=' \
|
||||
'=this=
|
||||
=is=
|
||||
A test, eh?' \
|
||||
'<dl>
|
||||
<dt>this</dt>
|
||||
<dt>is</dt>
|
||||
<dd>A test, eh?</dd>
|
||||
</dl>'
|
||||
|
||||
|
||||
try -fnodefinitionlist '=tag= does nothing' "$SRC" \
|
||||
'<p>=this=
|
||||
is an ugly
|
||||
=test=
|
||||
eh?</p>'
|
||||
fi
|
||||
|
||||
if [ "$DL" = "EXTRA" -o "$DL" = "BOTH" ]; then
|
||||
try 'markdown extra-style definition lists' \
|
||||
'foo
|
||||
: bar' \
|
||||
'<dl>
|
||||
<dt>foo</dt>
|
||||
<dd>bar</dd>
|
||||
</dl>'
|
||||
|
||||
try '... with two <dt>s in a row' \
|
||||
'foo
|
||||
bar
|
||||
: baz' \
|
||||
'<dl>
|
||||
<dt>foo</dt>
|
||||
<dt>bar</dt>
|
||||
<dd>baz</dd>
|
||||
</dl>'
|
||||
|
||||
try '... with two <dd>s in a row' \
|
||||
'foo
|
||||
: bar
|
||||
: baz' \
|
||||
'<dl>
|
||||
<dt>foo</dt>
|
||||
<dd>bar</dd>
|
||||
<dd>baz</dd>
|
||||
</dl>'
|
||||
|
||||
try '... with blanks between list items' \
|
||||
'foo
|
||||
: bar
|
||||
|
||||
zip
|
||||
: zap' \
|
||||
'<dl>
|
||||
<dt>foo</dt>
|
||||
<dd>bar</dd>
|
||||
<dt>zip</dt>
|
||||
<dd>zap</dd>
|
||||
</dl>'
|
||||
|
||||
fi
|
||||
|
||||
summary $0
|
||||
exit $rc
|
||||
@@ -0,0 +1,9 @@
|
||||
* [] (http://dustmite.org)
|
||||
* [[an embedded link](http://wontwork.org)](http://willwork.org)
|
||||
* [![dustmite][]] (http:/dustmite.org)
|
||||
* ![dustmite][]
|
||||
* ![dustmite][dustmite]
|
||||
* [<a href="http://cheating.us">cheat me</a>](http://I.am.cheating)
|
||||
|
||||
[dustmite]: http://dustmite.org/mite.jpg =25x25 "here I am!"
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
. tests/functions.sh
|
||||
|
||||
title "emphasis"
|
||||
|
||||
rc=0
|
||||
MARKDOWN_FLAGS=
|
||||
|
||||
try '*hi* -> <em>hi</em>' '*hi*' '<p><em>hi</em></p>'
|
||||
try '* -> *' 'A * A' '<p>A * A</p>'
|
||||
try -fstrict '***A**B*' '***A**B*' '<p><em><strong>A</strong>B</em></p>'
|
||||
try -fstrict '***A*B**' '***A*B**' '<p><strong><em>A</em>B</strong></p>'
|
||||
try -fstrict '**A*B***' '**A*B***' '<p><strong>A<em>B</em></strong></p>'
|
||||
try -fstrict '*A**B***' '*A**B***' '<p><em>A<strong>B</strong></em></p>'
|
||||
|
||||
try -frelax '_A_B with -frelax' '_A_B' '<p>_A_B</p>'
|
||||
try -fstrict '_A_B with -fstrict' '_A_B' '<p><em>A</em>B</p>'
|
||||
|
||||
summary $0
|
||||
exit $rc
|
||||
@@ -0,0 +1,120 @@
|
||||
. tests/functions.sh
|
||||
|
||||
title "markdown extra-style footnotes"
|
||||
|
||||
rc=0
|
||||
MARKDOWN_FLAGS=
|
||||
|
||||
FOOTIE='I haz a footnote[^1]
|
||||
[^1]: yes?'
|
||||
|
||||
try -ffootnote 'footnotes (-ffootnote)' "$FOOTIE" \
|
||||
'<p>I haz a footnote<sup id="fnref:1"><a href="#fn:1" rel="footnote">1</a></sup></p>
|
||||
<div class="footnotes">
|
||||
<hr/>
|
||||
<ol>
|
||||
<li id="fn:1">
|
||||
<p>yes?<a href="#fnref:1" rev="footnote">↩</a></p></li>
|
||||
</ol>
|
||||
</div>'
|
||||
|
||||
try -ffootnote -Cfoot 'footnotes (-ffootnote -Cfoot)' "$FOOTIE" \
|
||||
'<p>I haz a footnote<sup id="footref:1"><a href="#foot:1" rel="footnote">1</a></sup></p>
|
||||
<div class="footnotes">
|
||||
<hr/>
|
||||
<ol>
|
||||
<li id="foot:1">
|
||||
<p>yes?<a href="#footref:1" rev="footnote">↩</a></p></li>
|
||||
</ol>
|
||||
</div>'
|
||||
|
||||
try -fnofootnote 'footnotes (-fnofootnote)' "$FOOTIE" \
|
||||
'<p>I haz a footnote<a href="yes?">^1</a></p>'
|
||||
|
||||
|
||||
TSRC='Alpha[^AlphaF].
|
||||
|
||||
Column 1 | Column 2
|
||||
---------------------------------|--------------------------
|
||||
Beta[^BetaF] | cell
|
||||
|
||||
[^AlphaF]: Alpha Footnote
|
||||
|
||||
[^BetaF]: Beta Footnote'
|
||||
|
||||
TOUT='<p>Alpha<sup id="fnref:1"><a href="#fn:1" rel="footnote">1</a></sup>.</p>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Column 1 </th>
|
||||
<th> Column 2</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Beta<sup id="fnref:2"><a href="#fn:2" rel="footnote">2</a></sup> </td>
|
||||
<td> cell</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="footnotes">
|
||||
<hr/>
|
||||
<ol>
|
||||
<li id="fn:1">
|
||||
<p>Alpha Footnote<a href="#fnref:1" rev="footnote">↩</a></p></li>
|
||||
<li id="fn:2">
|
||||
<p>Beta Footnote<a href="#fnref:2" rev="footnote">↩</a></p></li>
|
||||
</ol>
|
||||
</div>'
|
||||
|
||||
try -ffootnote 'footnotes inside table elements' "$TSRC" "$TOUT"
|
||||
|
||||
|
||||
TSRC='[Test test[^test]](class:test)
|
||||
|
||||
<span class="test">
|
||||
Test2[^testtwo]
|
||||
</span>
|
||||
|
||||
Test3[^testthree]
|
||||
|
||||
<span class="test">
|
||||
Test4[^testfour]
|
||||
</span>
|
||||
|
||||
[^test]: Test footnote
|
||||
[^testtwo]: Test2 footnote
|
||||
[^testthree]: Test3 footnote
|
||||
[^testfour]: Test4 footnote'
|
||||
|
||||
TOUT='<p><span class="test">Test test<sup id="fnref:1"><a href="#fn:1" rel="footnote">1</a></sup></span></p>
|
||||
|
||||
<p><span class="test">
|
||||
Test2<sup id="fnref:2"><a href="#fn:2" rel="footnote">2</a></sup>
|
||||
</span></p>
|
||||
|
||||
<p>Test3<sup id="fnref:3"><a href="#fn:3" rel="footnote">3</a></sup></p>
|
||||
|
||||
<p><span class="test">
|
||||
Test4<sup id="fnref:4"><a href="#fn:4" rel="footnote">4</a></sup>
|
||||
</span></p>
|
||||
<div class="footnotes">
|
||||
<hr/>
|
||||
<ol>
|
||||
<li id="fn:1">
|
||||
<p>Test footnote<a href="#fnref:1" rev="footnote">↩</a></p></li>
|
||||
<li id="fn:2">
|
||||
<p>Test2 footnote<a href="#fnref:2" rev="footnote">↩</a></p></li>
|
||||
<li id="fn:3">
|
||||
<p>Test3 footnote<a href="#fnref:3" rev="footnote">↩</a></p></li>
|
||||
<li id="fn:4">
|
||||
<p>Test4 footnote<a href="#fnref:4" rev="footnote">↩</a></p></li>
|
||||
</ol>
|
||||
</div>'
|
||||
|
||||
try -ffootnote 'footnotes inside spans' "$TSRC" "$TOUT"
|
||||
|
||||
summary $0
|
||||
exit $rc
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user