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; }