diff --git a/md2teach.xcodeproj/xcuserdata/jrand.xcuserdatad/xcschemes/xcschememanagement.plist b/md2teach.xcodeproj/xcuserdata/jrand.xcuserdatad/xcschemes/xcschememanagement.plist
index 38f213f..a1d7f13 100644
--- a/md2teach.xcodeproj/xcuserdata/jrand.xcuserdatad/xcschemes/xcschememanagement.plist
+++ b/md2teach.xcodeproj/xcuserdata/jrand.xcuserdatad/xcschemes/xcschememanagement.plist
@@ -7,12 +7,12 @@
Binary.xcscheme_^#shared#^_
orderHint
- 1
+ 2
doNotBuild.xcscheme_^#shared#^_
orderHint
- 2
+ 1
md2teach.xcscheme_^#shared#^_
diff --git a/md2teach/io.c b/md2teach/io.c
index 0e57b17..e37e299 100644
--- a/md2teach/io.c
+++ b/md2teach/io.c
@@ -22,6 +22,7 @@
static IORecGS writeRec;
static char writeBuffer[4096];
static int32_t writeBufferOffset = 0;
+static MD_SIZE writePos = 0;
// Implementation
@@ -94,6 +95,7 @@ void writeChar(MD_CHAR ch)
ch = '\r';
writeBuffer[writeBufferOffset] = ch;
writeBufferOffset++;
+ writePos++;
}
@@ -106,6 +108,12 @@ void writeString(const MD_CHAR * str, MD_SIZE size)
}
+MD_SIZE outputPos(void)
+{
+ return writePos;
+}
+
+
void closeOutputFile(void)
{
RefNumRecGS closeRec;
diff --git a/md2teach/io.h b/md2teach/io.h
index 18562fc..3d7f87d 100644
--- a/md2teach/io.h
+++ b/md2teach/io.h
@@ -16,6 +16,7 @@
extern int openOutputFile(const char * filename);
extern void writeChar(MD_CHAR ch);
extern void writeString(const MD_CHAR * str, MD_SIZE size);
+extern MD_SIZE outputPos(void);
extern void closeOutputFile(void);
extern const MD_CHAR * readInputFile(const char * filename, MD_SIZE * bufferSize);
diff --git a/md2teach/md4c.h b/md2teach/md4c.h
index cdb68c2..f70c700 100644
--- a/md2teach/md4c.h
+++ b/md2teach/md4c.h
@@ -47,7 +47,11 @@
// GS_SPECIFIC - This was just unsigned but on a GS, we need this to be unsigned
// long to support > 64K sizes and offsets. Also, rather than create a dependency
// on stdint.h which doesn't exist in the base ORCA/C distribution, I am defining
-// int32_t and uint32_t here:
+// int32_t, uint32_t and some other similar defines here:
+typedef signed char int8_t;
+typedef unsigned char uint8_t;
+typedef int int16_t;
+typedef unsigned int uint16_t;
typedef long int32_t;
typedef unsigned long uint32_t;
diff --git a/md2teach/style.c b/md2teach/style.c
index c0af662..41da5e7 100644
--- a/md2teach/style.c
+++ b/md2teach/style.c
@@ -6,13 +6,34 @@
*
*/
-#include
+#include
+#include
+#include
#include
+#include "io.h"
+#include "main.h"
#include "style.h"
+// Defines
+
+#define NUM_HEADER_SIZES 6
+
+// This is plain, emphasized, strong or strong+empasized
+#define NUM_TEXT_FORMATS 4
+
+#define NUM_HEADER_STYLES (NUM_HEADER_SIZES * NUM_TEXT_FORMATS)
+#define NUM_TEXT_STYLES NUM_TEXT_FORMATS
+#define NUM_QUOTE_STYLES NUM_TEXT_FORMATS
+#define NUM_CODE_STYLES 1
+
+#define TOTAL_STYLES (NUM_HEADER_STYLES + NUM_TEXT_STYLES + NUM_QUOTE_STYLES + NUM_CODE_STYLES)
+
+#define STARTING_STYLE_ITEMS 32
+
+
// Typedefs
typedef struct tWindowPos
@@ -56,8 +77,6 @@ typedef struct tFormat
StyleItem styleItems[1];
} tFormat;
-//typedef struct tStyle
-
// Globals
@@ -86,3 +105,166 @@ static uint8_t headerFontSizes[NUM_HEADER_SIZES] = {
};
static tFormat * formatPtr = NULL;
+static uint32_t allocStyleItems = 0;
+static MD_SIZE styleChangedAt = 0;
+
+
+// Implementation
+
+void growStyleItems(void)
+{
+ uint32_t newAllocStyleItems = 2 * allocStyleItems;
+
+ formatPtr = realloc(formatPtr, sizeof(formatPtr->header) + newAllocStyleItems * sizeof(StyleItem));
+ if (formatPtr == NULL) {
+ fprintf(stderr, "%s: Out of memory\n", commandName);
+ exit(1);
+ }
+ allocStyleItems = newAllocStyleItems;
+}
+
+
+int addStyle(int styleListNum, uint16_t fontFamily, uint8_t fontSize, uint8_t fontStyle, uint16_t backgroundColour)
+{
+ formatPtr->header.styleList[styleListNum].styleFontID.fidRec.famNum = fontFamily;
+ formatPtr->header.styleList[styleListNum].styleFontID.fidRec.fontSize = fontSize;
+ formatPtr->header.styleList[styleListNum].styleFontID.fidRec.fontStyle = fontStyle;
+ formatPtr->header.styleList[styleListNum].foreColor = 0x00;
+ formatPtr->header.styleList[styleListNum].backColor = backgroundColour;
+ formatPtr->header.styleList[styleListNum].userData = 0x00;
+
+ return styleListNum + 1;
+}
+
+int styleInit(void)
+{
+ int styleListNum;
+ int headerSize;
+
+ formatPtr = malloc(sizeof(formatPtr->header) + STARTING_STYLE_ITEMS * sizeof(StyleItem));
+ if (formatPtr == NULL) {
+ fprintf(stderr, "%s: Out of memory\n", commandName);
+ return 1;
+ }
+ allocStyleItems = STARTING_STYLE_ITEMS;
+
+ formatPtr->header.version = 0x0000;
+
+ formatPtr->header.rulerSize = sizeof(formatPtr->header.ruler);
+ formatPtr->header.ruler.leftMargin = 0x00;
+ formatPtr->header.ruler.leftIndent = 0x00;
+ formatPtr->header.ruler.rightMargin = 0x0221;
+ formatPtr->header.ruler.just = leftJust;
+ formatPtr->header.ruler.extraLS = 0x00;
+ formatPtr->header.ruler.flags = 0x00;
+ formatPtr->header.ruler.userData = 0x00;
+ formatPtr->header.ruler.tabType = stdTabs;
+ formatPtr->header.ruler.tabTerminator = 0x40;
+
+ formatPtr->header.styleListLength = sizeof(formatPtr->header.styleList);
+
+ styleListNum = 0;
+
+ // Add header styles
+ for (headerSize = 0; headerSize < NUM_HEADER_SIZES; headerSize++) {
+ styleListNum = addStyle(styleListNum, helvetica, headerFontSizes[headerSize], plainMask, 0xffff);
+ styleListNum = addStyle(styleListNum, helvetica, headerFontSizes[headerSize], boldMask, 0xffff);
+ styleListNum = addStyle(styleListNum, helvetica, headerFontSizes[headerSize], italicMask, 0xffff);
+ styleListNum = addStyle(styleListNum, helvetica, headerFontSizes[headerSize], boldMask | italicMask, 0xffff);
+ }
+
+ // Add test styles - Also default the first text format to plain.
+ formatPtr->header.numberOfStyles = 1;
+ formatPtr->styleItems[0].dataOffset = 0;
+ formatPtr->styleItems[0].dataOffset = styleListNum * sizeof(formatPtr->header.styleList[0]);
+
+ styleListNum = addStyle(styleListNum, helvetica, 12, plainMask, 0xffff);
+ styleListNum = addStyle(styleListNum, helvetica, 12, boldMask, 0xffff);
+ styleListNum = addStyle(styleListNum, helvetica, 12, italicMask, 0xffff);
+ styleListNum = addStyle(styleListNum, helvetica, 12, boldMask | italicMask, 0xffff);
+
+ // Add quote styles
+ styleListNum = addStyle(styleListNum, helvetica, 12, plainMask, 0xeeee);
+ styleListNum = addStyle(styleListNum, helvetica, 12, boldMask, 0xeeee);
+ styleListNum = addStyle(styleListNum, helvetica, 12, italicMask, 0xeeee);
+ styleListNum = addStyle(styleListNum, helvetica, 12, boldMask | italicMask, 0xeeee);
+
+ // Add code style
+ styleListNum = addStyle(styleListNum, courier, 12, plainMask, 0xffff);
+
+ if (styleListNum != TOTAL_STYLES)
+ {
+ fprintf(stderr, "%s: Expected %d styles but created %d styles.\n", commandName);
+ return 1;
+ }
+
+ return 0;
+}
+
+
+void setStyle(tStyleType styleType, uint16_t textMask, uint16_t headerSize)
+{
+ int32_t styleOffset;
+ MD_SIZE currentPos;
+ int lastStyleIndex = formatPtr->header.numberOfStyles - 1;
+
+ switch (styleType) {
+ case STYLE_TYPE_HEADER:
+ styleOffset = ((headerSize - 1) * NUM_TEXT_FORMATS) + textMask;
+ break;
+
+ case STYLE_TYPE_TEXT:
+ styleOffset = NUM_HEADER_STYLES + textMask;
+ break;
+
+ case STYLE_TYPE_QUOTE:
+ styleOffset = NUM_HEADER_STYLES + NUM_TEXT_STYLES + textMask;
+ break;
+
+ case STYLE_TYPE_CODE:
+ styleOffset = NUM_HEADER_STYLES + NUM_TEXT_STYLES + NUM_QUOTE_STYLES;
+ break;
+
+ default:
+ fprintf(stderr, "%s: Unexpected style type (%u)\n", commandName, (uint16_t)styleType);
+ }
+
+ styleOffset *= sizeof(formatPtr->header.styleList[0]);
+
+ // If the offset requested is the same as the one we already have, then just return.
+ // Nothing has changed.
+ if (formatPtr->styleItems[lastStyleIndex].dataOffset == styleOffset)
+ return;
+
+ // Check to see if the previous style actually emitted any characters and if not,
+ // then just overwrite it with this new style.
+ currentPos = outputPos();
+ if (styleChangedAt == currentPos) {
+ formatPtr->styleItems[lastStyleIndex].dataOffset = styleOffset;
+ return;
+ }
+
+ formatPtr->styleItems[lastStyleIndex].dataLength = currentPos - styleChangedAt;
+ styleChangedAt = currentPos;
+
+ if (formatPtr->header.numberOfStyles == allocStyleItems)
+ growStyleItems();
+
+ lastStyleIndex++;
+ formatPtr->header.numberOfStyles++;
+ formatPtr->styleItems[lastStyleIndex].dataOffset = styleOffset;
+}
+
+void closeStyle(void)
+{
+ MD_SIZE currentPos = outputPos();
+ int lastStyleIndex = formatPtr->header.numberOfStyles - 1;
+
+ // If the final style was not used, then remove it. Otherwise, update the length of the
+ // final style.
+ if (styleChangedAt == currentPos) {
+ formatPtr->header.numberOfStyles--;
+ } else {
+ formatPtr->styleItems[lastStyleIndex]. dataLength = currentPos - styleChangedAt;
+ }
+}
diff --git a/md2teach/style.h b/md2teach/style.h
index 4119765..2655eaf 100644
--- a/md2teach/style.h
+++ b/md2teach/style.h
@@ -9,19 +9,31 @@
#ifndef _GUARD_PROJECTmd2teach_FILEstyle_
#define _GUARD_PROJECTmd2teach_FILEstyle_
+#include "md4c.h"
+
+
// Defines
-#define NUM_HEADER_SIZES 6
+#define STYLE_TEXT_PLAIN 0u
+#define STYLE_TEXT_MASK_STRONG 1u
+#define STYLE_TEXT_MASK_EMPHASIZED 2u
-// This is plain, emphasized, strong or strong+empasized
-#define NUM_TEXT_FORMATS 4
-#define NUM_HEADER_STYLES (NUM_HEADER_SIZES * NUM_TEXT_FORMATS)
-#define NUM_CODE_STYLES 1
-#define NUM_TEXT_STYLES NUM_TEXT_FORMATS
-#define NUM_QUOTE_STYLES NUM_TEXT_FORMATS
+// Typedefs
-#define TOTAL_STYLES (NUM_HEADER_STYLES + NUM_CODE_STYLES + NUM_TEXT_STYLES + NUM_QUOTE_STYLES)
+typedef enum tStyleType {
+ STYLE_TYPE_HEADER,
+ STYLE_TYPE_TEXT,
+ STYLE_TYPE_QUOTE,
+ STYLE_TYPE_CODE
+} tStyleType;
+
+
+// API
+
+extern int styleInit(void);
+extern void setStyle(tStyleType styleType, uint16_t textMask, uint16_t headerSize);
+extern void closeStyle(void);
#endif /* define _GUARD_PROJECTmd2teach_FILEstyle_ */
diff --git a/md2teach/translate.c b/md2teach/translate.c
index 206d8b9..0361923 100644
--- a/md2teach/translate.c
+++ b/md2teach/translate.c
@@ -12,6 +12,7 @@
#include "translate.h"
#include "io.h"
#include "main.h"
+#include "style.h"
// Typedefs
@@ -720,5 +721,14 @@ static void debugLogHook(const char * message, void * userdata)
int parse(const MD_CHAR* text, MD_SIZE size)
{
- return md_parse(text, size, &parser, NULL);
+ int result;
+
+ if (styleInit() != 0)
+ return 1;
+
+ result = md_parse(text, size, &parser, NULL);
+
+ closeStyle();
+
+ return result;
}