/* Copyright (c) 2017, Computer History Museum All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted (subject to the limitations in the disclaimer below) provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Computer History Museum nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. 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 HOLDER 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. */ //depot/projects/eudora/mac/Current/rich.c#24 - edit change 4405 (text) #include "rich.h" /* Copyright (c) 1995 by QUALCOMM Incorporated */ #define FILE_NUM 76 OSErr UnwindRich(short *counters,StackHandle openStack,StackHandle redoStack,AccuPtr enriched); OSErr RewindRich(StackHandle openStack,StackHandle redoStack,AccuPtr enriched); OSErr BuildEnrichedDirectives(PETETextStylePtr oldStyle,PETETextStylePtr newStyle, PETEParaInfoPtr oldInfo,PETEParaInfoPtr newInfo, StackHandle openStack,StackHandle redoStack, AccuPtr enriched); PStr BuildRichParaParam(PStr directive,PSMPtr marg); PStr BuildRichFontParam(PStr directive,short fontID); PStr BuildRichColorParam(PStr directive,RGBColor *color); void AddToStyle(EnrichedEnum cmd,Boolean neg,long offset,OffsetAndStyleHandle *styles,uLong valid); OSErr EnrichedToken(UHandle enriched,long maxLen,Boolean headers,short *cmdId,Boolean *neg,long *tStart,long *tStop); OSErr InsertEnriched(UHandle text, long *textOffset, long textLen, long *offset, Boolean unwrap, PETEHandle pte); OSErr InsertEnrichedLo(UHandle text, long *textOffset, long textLen, long *inOffset, Boolean unwrap, PETEHandle pte, TextEncoding encoding); OSErr InsertFlowed(UHandle text, long *textOffset, long textLen, long *inOffset, PETEHandle pte, Boolean delSP); OSErr InsertFlowedLo(UHandle text, long *textOffset, long textLen, long *inOffset, PETEHandle pte, Boolean delSP, TextEncoding encoding); OSErr InsertFixed(UHandle text, long *textOffset, long textLen, long *inOffset, PETEHandle pte, TextEncoding encoding); #define FlushIntlText(pte, offset, converter) PeteInsertIntlText(pte, offset, nil, 0L, 0L, converter, kTextEncodingUnknown, false, true); Boolean PartIsReferenced(uLong cID,uLong baseID,uLong sourceID,StackHandle partRefStack); OSErr FakeAttachment(PETEHandle pte,uLong *offset,FSSpecPtr spec); #pragma segment Enriched /********************************************************************** * Text/Enriched building **********************************************************************/ typedef struct { EnrichedEnum directive; union { RGBColor color; PeteSaneMargin marg; short fontID; } param; } DirectiveType,*DTPtr, **DTHandle; #define ISSUE_DIRECTIVE \ do { \ ComposeRString(directive,MIME_RICH_ON,EnrichedStrn+pushMe.directive); \ if (err=AccuAddStr(enriched,directive)) goto done; \ if (err=StackPush(&pushMe,openStack)) goto done; \ } while (0) /********************************************************************** * BuildEnriched - take a block of text and turn it into text/enriched **********************************************************************/ OSErr BuildEnriched(AccuPtr enriched,PETEHandle pte,UHandle text,long len,long offset,PETEStyleListHandle pslh,Boolean xrich) { long eSize = 0; long eOffset = 0; Byte c; OSErr err = noErr; Boolean cr = False; PETEStyleEntry oldStyle, newStyle; PETEParaInfo oldInfo, newInfo; long oldPara = -1; long para; short paraDiff, styleDiff; StackHandle openStack=nil; StackHandle redoStack=nil; long runLen; Str255 directive; DirectiveType pushMe; Boolean kkk; UPtr spot; #ifdef DEBUG Str255 scratch; #endif #ifdef NEVER EuStyleSheet ess; #endif if (pte) { oldInfo.tabHandle = nil; PETEGetParaInfo(PETE,pte,kPETEDefaultPara,&oldInfo); PeteStyleAt(pte,kPETEDefaultStyle,&oldStyle); PETEGetRawText(PETE,pte,&text); } if (!(err=StackInit(sizeof(DirectiveType),&openStack))) if (!(err=StackInit(sizeof(DirectiveType),&redoStack))) { if (xrich) { pushMe.directive = enXRich; ISSUE_DIRECTIVE; } while (offsetoffset && (*enriched->data)[enriched->offset-1]=='\015') enriched->offset--; if (enriched->offset && (*enriched->data)[enriched->offset-1]=='\015') enriched->offset--; // finish up the directives err = UnwindRich(nil,openStack,nil,enriched); if (err==fnfErr) err = 0; // make sure we end with hard linebreak while (enriched->offset<2) AccuAddChar(enriched,'\015'); if ((*enriched->data)[enriched->offset-1] != '\015') AccuAddChar(enriched,'\015'); if ((*enriched->data)[enriched->offset-2] != '\015') AccuAddChar(enriched,'\015'); } ZapHandle(openStack); ZapHandle(redoStack); if (!err) AccuTrim(enriched); return(err); } /********************************************************************** * BuildEnrichedDirectives - build directives for moving from one style to another **********************************************************************/ OSErr BuildEnrichedDirectives(PETETextStylePtr oldStyle,PETETextStylePtr newStyle, PETEParaInfoPtr oldInfo,PETEParaInfoPtr newInfo, StackHandle openStack,StackHandle redoStack, AccuPtr enriched) { short styleDiff = oldStyle ? PeteTextStyleDiff(oldStyle,newStyle) : 0; short paraDiff = oldInfo ? PeteParaInfoDiff(oldInfo,newInfo) : 0; short counters[enPLeft]; short i; OSErr err = noErr; Str255 directive; DirectiveType pushMe; short oldInc, newInc, normInc; PeteSaneMargin marg; /* * undo section */ // clear counters for (i=0;itsFace&bold)) counters[enBold]=1; if ((styleDiff & italic) && !(newStyle->tsFace&italic)) counters[enItalic]=1; if ((styleDiff & underline) && !(newStyle->tsFace&underline)) counters[enUnderline]=1; if (styleDiff & peFontValid && oldStyle->tsFont!=kPETEDefaultFont) { #ifdef USEFIXEDDEFAULTFONT if(oldStyle->tsFont == kPETEDefaultFixed) counters[enFixed]=1; else #endif counters[enFont]=1; } if (styleDiff & peColorValid && !IS_DEFAULT_COLOR(oldStyle->tsColor)) counters[enColor]=1; if ((styleDiff & peSizeValid)) { oldInc = FindSizeInc(oldStyle->tsSize); newInc = FindSizeInc(newStyle->tsSize); normInc = FindSizeInc(FontSize); if (oldInc==newInc) styleDiff &= ~peSizeValid; else if (oldIncnewInc) { if (oldInc>normInc) { while(oldInc>normInc && oldInc>newInc) {counters[enBigger]++;oldInc--;} } } if (oldInc==newInc) styleDiff &= ~peSizeValid; } if ((paraDiff & peQuoteLevelValid) && oldInfo->quoteLevel>newInfo->quoteLevel) counters[enExcerpt] = oldInfo->quoteLevel-newInfo->quoteLevel; if (paraDiff & peJustificationValid) { if (oldInfo->justification==teCenter) counters[enCenter] = 1; else if (oldInfo->justification==teFlushRight) counters[enRight] = 1; if (newInfo->justification==teFlushDefault || newInfo->justification==teFlushLeft) paraDiff &= ~peJustificationValid; } if (paraDiff & (peEndMarginValid|peStartMarginValid|peIndentValid)) { PeteConvert2Marg(oldInfo,&marg); if (marg.first||marg.second||marg.right) counters[enPara]++; } //undo them if (err=UnwindRich(counters,openStack,redoStack,enriched)) goto done; //redo the ones we need to redo if (err=RewindRich(openStack,redoStack,enriched)) goto done; /* * do section */ if (paraDiff & peQuoteLevelValid) for(i=oldInfo->quoteLevel;iquoteLevel;i++) { pushMe.directive = enExcerpt; ISSUE_DIRECTIVE; } if (paraDiff & peJustificationValid) { if (newInfo->justification==teCenter) pushMe.directive = enCenter; else pushMe.directive = enRight; ISSUE_DIRECTIVE; } if (paraDiff & (peEndMarginValid|peStartMarginValid|peIndentValid)) { PeteConvert2Marg(newInfo,&marg); if (marg.first||marg.second||marg.right) { pushMe.directive = enPara; pushMe.param.marg = marg; ISSUE_DIRECTIVE; BuildRichParaParam(directive,&marg); AccuAddStr(enriched,directive); } } if ((styleDiff & bold) && (newStyle->tsFace&bold)) { pushMe.directive = enBold; ISSUE_DIRECTIVE; } if ((styleDiff & italic) && (newStyle->tsFace&italic)) { pushMe.directive = enItalic; ISSUE_DIRECTIVE; } if ((styleDiff & underline) && (newStyle->tsFace&underline)) { pushMe.directive = enUnderline; ISSUE_DIRECTIVE; } if (styleDiff & peFontValid && newStyle->tsFont!=kPETEDefaultFont) { #ifdef USEFIXEDDEFAULTFONT if(newStyle->tsFont==kPETEDefaultFixed) { pushMe.directive = enFixed; ISSUE_DIRECTIVE; } else #endif { pushMe.directive = enFont; pushMe.param.fontID = newStyle->tsFont; ISSUE_DIRECTIVE; BuildRichFontParam(directive,newStyle->tsFont); AccuAddStr(enriched,directive); } } if (styleDiff & peColorValid && !IS_DEFAULT_COLOR(newStyle->tsColor)) { pushMe.directive = enColor; pushMe.param.color = newStyle->tsColor; ISSUE_DIRECTIVE; BuildRichColorParam(directive,&newStyle->tsColor); AccuAddStr(enriched,directive); } if (styleDiff & peSizeValid) { //smaller? if (oldInc>newInc) { pushMe.directive = enSmaller; while(oldInc>newInc) {ISSUE_DIRECTIVE;oldInc--;} } //bigger? else if (oldIncright;i;i--) { PCatR(guts,EnrichedStrn+enPRight); PCatC(guts,','); } if (marg->first>marg->second) { for (i=marg->second;i;i--) { PCatR(guts,EnrichedStrn+enPLeft); PCatC(guts,','); } for (i=marg->first-marg->second;i;i--) { PCatR(guts,EnrichedStrn+enPIn); PCatC(guts,','); } } else { for (i=marg->second;i;i--) { PCatR(guts,EnrichedStrn+enPLeft); PCatC(guts,','); } for (i=marg->second-marg->first;i;i--) { PCatR(guts,EnrichedStrn+enPOut); PCatC(guts,','); } } if (*guts) { --*guts; ComposeRString(directive,MIME_RICH_PARAM,guts); } else *directive = 0; return(directive); } /********************************************************************** * BuildRichFontParam - build the font parameter **********************************************************************/ PStr BuildRichFontParam(PStr directive,short fontID) { Str255 scratch; GetFontName(fontID,scratch); PTr(scratch," ","_"); ComposeRString(directive,MIME_RICH_PARAM,scratch); return(directive); } /********************************************************************** * BuildRichColorParam - build the font parameter **********************************************************************/ PStr BuildRichColorParam(PStr directive,RGBColor *color) { Str31 scratch; Bytes2Hex((void*)&color->red,2,scratch+1); Bytes2Hex((void*)&color->green,2,scratch+6); Bytes2Hex((void*)&color->blue,2,scratch+11); scratch[5] = scratch[10] = ','; *scratch = 14; ComposeRString(directive,MIME_RICH_PARAM,scratch); return(directive); } /********************************************************************** * UnwindRich - unwind richtext to remove certain directives **********************************************************************/ OSErr UnwindRich(short *counters,StackHandle openStack,StackHandle redoStack,AccuPtr enriched) { OSErr err = fnfErr; DirectiveType top; Str31 cmd; long counterCount=0; short i; if (counters) { counterCount = 0; for (i=0;itocH)->sums[(*messH)->sumNum].mesgErrH) { AddMesgError((*messH)->tocH, (*messH)->sumNum, GetRString(scratch,BAD_CHARSET_ERR), err); } if((tempoOffset = offset) == -1) PeteGetTextAndSelection(pte,nil,&tempoOffset,nil); offset = tempiOffset; PeteDelete(pte, tempiOffset, tempoOffset); encoding = CreateSystemRomanEncoding(); tStart = tempStart; goto TryItAgain; } tStop = tStart; wasRel = false; paraMe = true; } else { JustText : MakePStr(scratch,*text+tStart,tStop-tStart); if (!RelLine2Spec(scratch,&pd.spec,&pd.cid,&pd.relURL,&pd.absURL)) { if (partStack && PartIsReferenced(pd.cid,pd.relURL,pd.absURL,partRefStack)) StackQueue(&pd,partStack); else { err = FakeAttachment(pte,&offset,&pd.spec); if (err) break; paraMe = false; } wasRel = True; } else if (!wasRel) { if (paraMe) // make sure we start a new para? { if (offset==-1) PeteGetTextAndSelection(pte,nil,&realOffset,nil); else realOffset = offset; } if(headers) { err = PeteInsertHeader(pte,&offset,text,tStop-tStart,tStart); if(EncodingError(err)) err = noErr; else if(err) break; if((tStop-tStart == 2) && ((*text)[tStart] == 13) && ((*text)[tStart+1] == 13)) headers = false; } else { err = PETEInsertTextHandle(PETE,pte,offset,text,tStop-tStart,tStart,nil); if(err) break; if (offset!=-1) offset += tStop-tStart; } // plain, please if (paraMe) { long oldLen = PeteLen(pte); PeteEnsureCrAndBreakLo(pte,realOffset,&realOffset,¶Me); PetePlainParaAt(pte,realOffset,realOffset+tStop-tStart); if (offset==-1) PeteSelect(nil,pte,realOffset+tStop-tStart,realOffset+tStop-tStart); else offset += PeteLen(pte)-oldLen; } } else wasRel = false; // skip only one token paraMe = false; } } ZapHandle(partRefStack); return(err==eofErr ? noErr : err); } /************************************************************************ * PartIsReferenced - is this part actually referenced by anything? ************************************************************************/ Boolean PartIsReferenced(uLong cID,uLong baseID,uLong sourceID,StackHandle partRefStack) { uLong id; short item; if (!partRefStack) return false; for (item=0;item<(*partRefStack)->elCount;item++) { StackItem(&id,item,partRefStack); if (id==cID || id==baseID || id==sourceID) return true; } return false; } /************************************************************************ * FakeAttachment - an html part wasn't referenced by anything; pretend * it's an attachment ************************************************************************/ OSErr FakeAttachment(PETEHandle pte,uLong *offset,FSSpecPtr spec) { OSErr err; Str255 scratch; // snide comment GetRString(scratch,UNREFERENCED_PART); err = PeteInsertPtr(pte,*offset,scratch+1,*scratch); if (err) return err; if (*offset!=-1) *offset += *scratch; // attachment AttachNoteLo(spec,scratch); err = PeteInsertPtr(pte,*offset,scratch+1,*scratch); if (err) return err; if (*offset!=-1) *offset += *scratch; return noErr; } /************************************************************************ * InsertFlowed - insert some format=flowed, until we run out ************************************************************************/ OSErr InsertFlowed(UHandle text, long *textOffset, long textLen, long *inOffset, PETEHandle pte, Boolean delSP) { return InsertFlowedLo(text, textOffset, textLen, inOffset, pte, delSP, kTextEncodingUnknown); } /************************************************************************ * InsertFlowed - insert some format=flowed, until we run out ************************************************************************/ OSErr InsertFlowedLo(UHandle text, long *textOffset, long textLen, long *inOffset, PETEHandle pte, Boolean delSP, TextEncoding encoding) { long tStart, tStop, cStart; Str31 notFlowed, testMe; Boolean flowNext = false; short size; long offset = *inOffset; OSErr err = noErr; Boolean interpret = UseFlowIn; Boolean excerpt = UseFlowInExcerpt; long quoteLevel, oldQuoteLevel=0; long lastCR; Str15 sigSep; #ifdef DEBUG Str255 line; #endif IntlConverter converter; err = CreateIntlConverter(&converter, encoding); if(err) return err; textLen += *textOffset; // reset to absolute offset, please if (offset==-1) PeteGetTextAndSelection(pte,nil,&offset,nil); err = PeteEnsureCrAndBreak(pte,lastCR=offset,&offset); if(err) return err; ComposeRString(notFlowed,MIME_RICH_OFF,EnrichedStrn+enXFlowed); GetRString(sigSep,SIG_SEPARATOR); // skip token for (cStart = -1, tStart = *textOffset;tStart') break; } if((cStart > 0) && (encoding == kTextEncodingUnknown)) { MakePStr(testMe, (*text) + cStart, tStart - cStart); UpdateIntlConverter(&converter, testMe); } tStart++; /* * process input one line at a time */ while(!err && tStart';quoteLevel++); quoteLevel -= tStart; // if quotelevel changes, make hard newline if (oldQuoteLevel!=quoteLevel && flowNext) { err = FlushIntlText(pte, &offset, &converter); if(err) break; if (excerpt) { err = PeteEnsureBreak(pte,lastCR); if(err) break; } err = PeteInsertChar(pte,offset,'\015',nil); if(err) break; ++offset; if (excerpt) err = PeteSetExcerptLevelAt(pte,lastCR=offset,oldQuoteLevel); flowNext = false; } oldQuoteLevel = quoteLevel; // undo space-stuffing? if ((*text)[tStart]==' ') tStart++; // remove quotes else if ((excerpt||flowNext) && (*text)[tStart]=='>') { while (tStart') tStart++; if (tStart0) { Boolean excerptChange; excerptChange = excerpt && !flowNext && quoteLevel!=PeteIsExcerptAt(pte,lastCR); err = PeteInsertIntlText(pte,&offset,text,tStart,tStart+size,&converter,kTextEncodingUnknown,false,excerptChange); if (!err && excerptChange) { err = PeteEnsureBreak(pte,lastCR); if(!err) err = PeteSetExcerptLevelAt(pte,offset,quoteLevel); } if (!flowNext) lastCR = offset; } tStart = tStop+1; } if (*inOffset!=-1) *inOffset = offset; // record where we ended else PeteSelect(nil,pte,offset,offset); // if at insertion point, make sure we end insertion point at end of text *textOffset = tStop; DisposeIntlConverter(converter); return(err); } OSErr InsertFixed(UHandle text, long *textOffset, long textLen, long *inOffset, PETEHandle pte, TextEncoding encoding) { long tStart, tStop, cStart, textStart; Str31 notCharset, testMe; long offset = *inOffset; OSErr err = noErr; IntlConverter converter; err = CreateIntlConverter(&converter, encoding); if(err) return err; textLen += *textOffset; // reset to absolute offset, please if (offset==-1) PeteGetTextAndSelection(pte,nil,&offset,nil); PeteEnsureCrAndBreak(pte,offset,&offset); ComposeRString(notCharset,MIME_RICH_OFF,EnrichedStrn+enXCharset); // skip token for (cStart = -1, tStart = *textOffset;tStart') break; } if((cStart > 0) && (encoding == kTextEncodingUnknown)) { MakePStr(testMe, (*text) + cStart, tStart - cStart); UpdateIntlConverter(&converter, testMe); if(err) goto DoDispose; } textStart = ++tStart; /* * Look for end one line at a time */ while(tStartsecond++; marg->first++; break; case enPRight: marg->right++; break; case enPIn: marg->first++; break; case enPOut: marg->second++; break; default: return(fnfErr); } } return(noErr); } /********************************************************************** * EnrichedToken - get the next token from a text/enriched stream **********************************************************************/ OSErr EnrichedToken(UHandle enriched,long maxLen,Boolean headers,short *cmdId,Boolean *neg,long *tStart,long *tStop) { UPtr start,stop,end; Str63 cmd; long len = GetHandleSize(enriched); if (maxLen=len) {UL(enriched); return(eofErr);} // carriage return? if (*start=='\015') { for (stop=start+1;stop-delimited-thing else if (*stop=='>') { UPtr tempStop; for(tempStop=start+1;tempStop=*std) { sizeIndex = std-(*StdSizes); if (tempSize==*std) break; } else break; #ifdef USERELATIVESIZES if ((size < 0) && (size != kPETEDefaultSize)) { sizeIndex += size - kPETERelativeSizeBase; if(sizeIndex < 0) sizeIndex = 0; if(sizeIndex >= nSizes) sizeIndex = nSizes - 1; } #endif return(sizeIndex); } /********************************************************************** * SetMessRich - set the rich text flag for a message **********************************************************************/ Boolean SetMessRich(MessHandle messH) { StyleLevelEnum result; HeadSpec hSpec; Boolean html = !PrefIsSet(PREF_SEND_ENRICHED_NEW) || MessOptIsSet(messH,OPT_HTML); if (!CompHeadFind(messH,0,&hSpec)) { // No body. Not good. result = false; } else { result=HasStyles(TheBody,hSpec.value,hSpec.stop,html); } if (result) { if (html) { SetMessOpt(messH,OPT_HTML); ClearMessFlag(messH,FLAG_RICH); } else { SetMessFlag(messH,FLAG_RICH); ClearMessOpt(messH,OPT_HTML); } } else { ClearMessFlag(messH,FLAG_RICH); ClearMessOpt(messH,OPT_HTML); } if (result==hasOnlyExcerpt && UseFlowOutExcerpt) SetMessOpt(messH,OPT_JUST_EXCERPT); else ClearMessOpt(messH,OPT_JUST_EXCERPT); return(result); } /********************************************************************** * HasStyles - does an edit record use multiple styles? **********************************************************************/ StyleLevelEnum HasStyles(PETEHandle pte,long from,long to,Boolean allowGraphics) { PETEParaInfo defInfo, curInfo; PETEStyleEntry defStyle, curStyle; long para; long len; StyleLevelEnum result = hasNoStyle; short paraDiff; defInfo.tabHandle = curInfo.tabHandle = nil; PeteGetStyle(pte,kPETEDefaultStyle,nil,&defStyle); PETEGetParaInfo(PETE,pte,kPETEDefaultPara,&defInfo); for (;fromstyleName); PCatC(string,','); /* * text info */ // valid bits PXCat(string,ess->textValid); PCatC(string,','); // font name if ((ess->textValid & peFontValid) && ess->textStyle.tsFont!=kPETEDefaultFont) { GetFontName(ess->textStyle.tsFont,s); PCat(string,s); } PCatC(string,','); // font size if (ess->textValid & peFontValid) PLCat(string,FindSizeInc(ess->textStyle.tsSize)-FindSizeInc(FontSize)); PCatC(string,','); // style if (ess->textValid & peFaceValid) PXWCat(string,ess->textStyle.tsFace); PCatC(string,','); // color if (ess->textValid & peColorValid) { PXWCat(string,ess->textStyle.tsColor.red); PCatC(string,','); PXWCat(string,ess->textStyle.tsColor.green); PCatC(string,','); PXWCat(string,ess->textStyle.tsColor.blue); PCatC(string,','); } else { PCatC(string,','); PCatC(string,','); PCatC(string,','); } // language if (ess->textValid & peLangValid) PLCat(string,ess->textStyle.tsLang); PCatC(string,','); // lock if (ess->textValid & peLockValid) PLCat(string,ess->textStyle.tsLang); PCatC(string,','); // do not save label /* * paragraph info */ // valid bits PXWCat(string,ess->paraValid); PCatC(string,','); // margins if (ess->paraValid & peStartMarginValid) PLCat(string,ess->paraInfo.startMargin); PCatC(string,','); if (ess->paraValid & peEndMarginValid) PLCat(string,ess->paraInfo.endMargin); PCatC(string,','); if (ess->paraValid & peIndentValid) PLCat(string,ess->paraInfo.indent); PCatC(string,','); // direction if (ess->paraValid & peDirectionValid) PLCat(string,ess->paraInfo.direction); PCatC(string,','); // justification if (ess->paraValid & peJustificationValid) PLCat(string,ess->paraInfo.justification); PCatC(string,','); // quote level if (ess->paraValid & peQuoteLevelValid) PLCat(string,ess->paraInfo.quoteLevel); PCatC(string,','); // flags if (ess->paraValid & peFlagsValid) PXWCat(string,ess->paraInfo.paraFlags); PCatC(string,','); /* * flags for us */ PLCat(string,ess->wholePara); PCatC(string,','); PLCat(string,ess->formatBar); PCatC(string,','); return string; } /************************************************************************ * String2Style - decode a style from a string ************************************************************************/ OSErr String2Style(ESSPtr ess,PStr string) { return unimpErr; }