123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477 |
- /*******************************************************************
- *
- * File: CSimpleTextParser.cpp
- *
- * Author: Peter van Sebille (peter@yipton.net)
- *
- * (c) Copyright 2002, Peter van Sebille
- * All Rights Reserved
- *
- *******************************************************************/
- #include "CSimpleTextParser.h"
- enum
- {
- EBadTag,
- EBadZeroLengthTag,
- EBadIntegerParam,
- EBadAlignmentParam,
- EBadRgbColorParam
- };
- void Panic(TInt aPanic)
- {
- User::Panic(_L("STP"), aPanic);
- }
- CSimpleTextFormatParser* CSimpleTextFormatParser::NewLC()
- {
- CSimpleTextFormatParser* self = new(ELeave)CSimpleTextFormatParser;
- CleanupStack::PushL(self);
- self->ConstructL();
- return self;
- }
- CSimpleTextFormatParser::~CSimpleTextFormatParser()
- {
- delete iParaFormat;
- }
- void CSimpleTextFormatParser::ConstructL()
- {
- iParaFormat = CParaFormat::NewL();
- }
- void CSimpleTextFormatParser::SetBold(TBool aEnable)
- {
- iCharFormat.iFontSpec.iFontStyle.SetStrokeWeight(aEnable ? EStrokeWeightBold : EStrokeWeightNormal);
- iCharMask.ClearAll();
- iCharMask.SetAttrib(EAttFontStrokeWeight);
- iRichText->ApplyCharFormatL(iCharFormat, iCharMask, TextPos(), 0);
- }
- void CSimpleTextFormatParser::SetItalic(TBool aEnable)
- {
- iCharFormat.iFontSpec.iFontStyle.SetPosture(aEnable ? EPostureItalic : EPostureUpright);
- iCharMask.ClearAll();
- iCharMask.SetAttrib(EAttFontPosture);
- iRichText->ApplyCharFormatL(iCharFormat, iCharMask, TextPos(), 0);
- }
- void CSimpleTextFormatParser::SetUnderLine(TBool aEnable)
- {
- iCharFormat.iFontPresentation.iUnderline = aEnable ? EUnderlineOn : EUnderlineOff;
- iCharMask.ClearAll();
- iCharMask.SetAttrib(EAttFontUnderline);
- iRichText->ApplyCharFormatL(iCharFormat, iCharMask, TextPos(), 0);
- }
- void CSimpleTextFormatParser::SetHiddenText(TBool aEnable)
- {
- iCharFormat.iFontPresentation.iHiddenText = aEnable;
- iCharMask.ClearAll();
- iCharMask.SetAttrib(EAttFontHiddenText);
- iRichText->ApplyCharFormatL(iCharFormat, iCharMask, TextPos(), 0);
- }
- TRgb CSimpleTextFormatParser::ForegroundColor()
- {
- iCharMask.ClearAll();
- iCharMask.SetAttrib(EAttColor);
- iRichText->GetCharFormat(iCharFormat, iCharMask, TextPos(), 0);
- return iCharFormat.iFontPresentation.iTextColor;
- }
- void CSimpleTextFormatParser::SetForegroundColor(const TRgb& aColor)
- {
- iCharFormat.iFontPresentation.iTextColor = aColor;
- iCharMask.ClearAll();
- iCharMask.SetAttrib(EAttColor);
- iRichText->ApplyCharFormatL(iCharFormat, iCharMask, TextPos(), 0);
- }
- void CSimpleTextFormatParser::SetBackgroundColor(const TRgb& aColor)
- {
- iParaFormat->iFillColor = aColor;
- iParaMask.ClearAll();
- iParaMask.SetAttrib(EAttFillColor);
- iRichText->ApplyParaFormatL(iParaFormat, iParaMask, ParaPos(), 0);
- }
- void CSimpleTextFormatParser::NewParagraph()
- {
- iCurrentPara++;
- iRichText->AppendParagraphL();
- AppendTextL(_L(""));
- }
- void CSimpleTextFormatParser::SetAlignment(CParaFormat::TAlignment aAlignment)
- {
- iParaFormat->iHorizontalAlignment = aAlignment;
- iParaMask.ClearAll();
- iParaMask.SetAttrib(EAttAlignment);
- iRichText->ApplyParaFormatL(iParaFormat, iParaMask, ParaPos(), 0);
- }
- void CSimpleTextFormatParser::SetFontHeight(TInt aHeight)
- {
- iCharFormat.iFontSpec.iHeight = (aHeight * KTwipsPerInch)/KPointsPerInch;
- iCharMask.ClearAll();
- iCharMask.SetAttrib(EAttFontHeight);
- iRichText->ApplyCharFormatL(iCharFormat, iCharMask, TextPos(), 0);
- }
- void CSimpleTextFormatParser::SetFontName(const TDesC& aName)
- {
- iCharFormat.iFontSpec.iTypeface.iName = aName;
- iCharFormat.iFontSpec.iTypeface.SetAttributes(0);
- iCharFormat.iFontSpec.iTypeface.SetIsProportional(ETrue);
- iCharMask.ClearAll();
- iCharMask.SetAttrib(EAttFontTypeface);
- iRichText->ApplyCharFormatL(iCharFormat, iCharMask, TextPos(), 0);
- }
- /*
- * Character formatting:
- * <b> Bold on
- * </b> Bold of
- * <i> Italic on
- * </i> Italic off
- * <u> Underline on
- * </u> Underline off
- * <h> Hidden text on **doesn't work**
- * </h> Hidden text off **doesn't work**
- * <f=name> Fontname: name (type: string)
- * <s=size> Fontsize: size (type: integer)
- * <fg=color> Foreground color: color (type: color)
- * </fg> Restore foreground color
- *
- * Paragraph formatting:
- * <p> New paragraph - will reset both character & paragraph formatting to defaults
- * <a=align> Alignment: aling (type: alignement)
- * <bg=color> Background color: color (type: color) **doesn't work**
- *
- * Special characters:
- * </<> The character: <
- *
- * Types:
- * - string:
- * - integer: Either decimal or hexidecimal value
- * - color: Either integer specifing rgb value, or (r,g,b) in which r, g and b are of type integer
- * - align: element of enumeration {center, left, right}
- *
- * Comments:
- * The syntax/parser is fairly simplistic. The parser is not trying to match a tag like
- * <tag> </tag> as XML/HTML do. Basically, when it encounters a tag (e.g., <b>) it will
- * simply instruct the the editor to apply the formatting from the current position as
- * specified by the tag (e.g., enable bold). For example, <b><b>Hello</b>World</b> results
- * in Hello displayed in a Bold font and World in a normal font.
- *
- * The only case where state is maintained is when using <fg=color> and </fg>. The current
- * fg color is stored when parsing <fg=color> and restored when doing </fg>. Again, <fg> and
- * </fg> don't have the XML/HTML <tag> </tag> behavior. For example:
- * <fg=red>Peter<fg=blue>was</fg></fg>here
- * results in "Peter" displayed in red, "was" displayed in blue and "here" displayed in red.
- * It literally goes like this:
- * 1) <fg=red> --> apply editor text color red, previous color = whatever the editor's text color is now
- * 2) <fg=blue> --> apply editor text color blue, previous color = whatever the editor's text color
- * is now --> red
- * 3) </fg> --> apply editor text to previous color --> red
- * 4) </fg> --> apply editor text to previous color --> red
- *
- * What you probably wanted was:
- * <fg=red>Peter</fg><fg=blue>was</fg>here
- * Now "Peter" is displayed in red, "was" in blue and "here" in the default editor's color
- */
- static TUint32 ParseInteger(const TDesC& aString)
- {
- TUint32 val = 0;
- TBool parsed = EFalse;
- if (aString.Length() > 2)
- {
- if ((aString[0] == '0') && ((aString[0] == 'x') || (aString[0] == 'X')))
- {
- TLex lex(aString.Right(aString.Length()-2));
- if (lex.Val(val, EHex) != KErrNone)
- {
- __ASSERT_DEBUG(ETrue, Panic(EBadIntegerParam));
- }
- parsed = ETrue;
- }
- }
- if (!parsed)
- {
- TLex lex(aString);
- if (lex.Val(val, EDecimal) != KErrNone)
- {
- __ASSERT_DEBUG(ETrue, Panic(EBadIntegerParam));
- }
- }
- return val;
- }
- static TRgb ParseColor(const TDesC& aString)
- {
- if (aString.Length() > 0)
- {
- if (aString[0] == 'R')
- {
- if (aString.Compare(_L("RgbBlack")) == 0)
- return KRgbBlack;
- else if (aString.Compare(_L("RgbDarkGray")) == 0)
- return KRgbDarkGray;
- else if (aString.Compare(_L("RgbDarkRed")) == 0)
- return KRgbDarkRed;
- else if (aString.Compare(_L("RgbDarkGreen")) == 0)
- return KRgbDarkGreen;
- else if (aString.Compare(_L("RgbDarkYellow")) == 0)
- return KRgbDarkYellow;
- else if (aString.Compare(_L("RgbDarkBlue")) == 0)
- return KRgbDarkBlue;
- else if (aString.Compare(_L("RgbDarkMagenta")) == 0)
- return KRgbDarkMagenta;
- else if (aString.Compare(_L("RgbDarkCyan")) == 0)
- return KRgbDarkCyan;
- else if (aString.Compare(_L("RgbRed")) == 0)
- return KRgbRed;
- else if (aString.Compare(_L("RgbGreen")) == 0)
- return KRgbGreen;
- else if (aString.Compare(_L("RgbYellow")) == 0)
- return KRgbYellow;
- else if (aString.Compare(_L("RgbBlue")) == 0)
- return KRgbBlue;
- else if (aString.Compare(_L("RgbMagenta")) == 0)
- return KRgbMagenta;
- else if (aString.Compare(_L("RgbCyan")) == 0)
- return KRgbCyan;
- else if (aString.Compare(_L("RgbGray")) == 0)
- return KRgbGray;
- else if (aString.Compare(_L("RgbWhite")) == 0)
- return KRgbWhite;
- else
- {
- __ASSERT_DEBUG(ETrue, Panic(EBadRgbColorParam));
- }
- }
- return ParseInteger(aString);
- }
- __ASSERT_DEBUG(ETrue, Panic(EBadRgbColorParam));
- return KRgbBlack;
- }
- static CParaFormat::TAlignment ParseAlignment(const TDesC& aString)
- {
- if (aString.Compare(_L("center")) == 0)
- {
- return CParaFormat::ECenterAlign;
- }
- else if (aString.Compare(_L("left")) == 0)
- {
- return CParaFormat::ELeftAlign;
- }
- else if (aString.Compare(_L("right")) == 0)
- {
- return CParaFormat::ERightAlign;
- }
- __ASSERT_DEBUG(ETrue, Panic(EBadAlignmentParam));
- return CParaFormat::ECenterAlign;
- }
- void CSimpleTextFormatParser::ParseTagL(const TDesC& aTag)
- {
- TInt tagLength = aTag.Length();
- if (tagLength == 0)
- {
- __ASSERT_DEBUG(ETrue, Panic(EBadZeroLengthTag));
- return;
- }
- TPtrC param(_L(""));
- TInt pos = aTag.Find(_L("="));
- if (pos>0)
- {
- param.Set(aTag.Right(aTag.Length()-pos-1));
- tagLength = pos;
- }
- TPtrC tag = aTag.Left(tagLength);
- // RDebug::Print(_L("tag=%S, param=%S"), &tag, ¶m);
- switch (tagLength)
- {
- case 1:
- {
- if (tag.Compare(_L("a")) == 0)
- SetAlignment(ParseAlignment(param));
- else if (tag.Compare(_L("b")) == 0)
- SetBold();
- else if (tag.Compare(_L("f")) == 0)
- SetFontName(param);
- else if (tag.Compare(_L("h")) == 0)
- SetHiddenText();
- else if (tag.Compare(_L("i")) == 0)
- SetItalic();
- else if (tag.Compare(_L("p")) == 0)
- NewParagraph();
- else if (tag.Compare(_L("s")) == 0)
- SetFontHeight(ParseInteger(param));
- else if (tag.Compare(_L("u")) == 0)
- SetUnderLine();
- else
- {
- __ASSERT_DEBUG(ETrue, Panic(EBadTag));
- }
- break;
- }
-
- case 2:
- {
- if (tag.Compare(_L("/b")) == 0)
- SetBold(EFalse);
- if (tag.Compare(_L("bg")) == 0)
- SetBackgroundColor(ParseColor(param));
- if (tag.Compare(_L("fg")) == 0)
- {
- iPrevFgColor = ForegroundColor();
- SetForegroundColor(ParseColor(param));
- }
- else if (tag.Compare(_L("/h")) == 0)
- SetHiddenText(EFalse);
- else if (tag.Compare(_L("/i")) == 0)
- SetItalic(EFalse);
- else if (tag.Compare(_L("/u")) == 0)
- SetUnderLine(EFalse);
- else if (tag.Compare(_L("/<")) == 0)
- AppendTextL(_L("<"));
- break;
- }
- case 3:
- {
- if (tag.Compare(_L("/fg")) == 0)
- SetForegroundColor(iPrevFgColor);
- break;
- }
- default:
- ;
- }
- }
- void CSimpleTextFormatParser::ParseL(const TDesC& aSimpleText, CRichText& aRichText)
- {
- iRichText = &aRichText;
- iCurrentPara = 0;
- TBool done = EFalse;
- TPtrC simpleText(aSimpleText);
- do
- {
- TInt pos = simpleText.Locate('<');
- if (pos > 0)
- {
- AppendTextL(simpleText.Left(pos));
- simpleText.Set(simpleText.Right(simpleText.Length() - pos));
- }
- else if (pos == 0)
- {
- pos = simpleText.Locate('>');
- if (pos<=0)
- User::Leave(KErrArgument);
- ParseTagL(simpleText.Mid(1, pos-1));
- simpleText.Set(simpleText.Right(simpleText.Length() - pos - 1));
- }
- else
- {
- AppendTextL(simpleText);
- done = ETrue;
- }
- } while (!done);
- }
- TInt CSimpleTextFormatParser::TextPos()
- {
- return iRichText->DocumentLength();
- #if 0
- TInt pos, length;
- pos = iRichText->CharPosOfParagraph(length, iCurrentPara);
- return pos+length-1;
- #endif
- }
- TInt CSimpleTextFormatParser::ParaPos()
- {
- return TextPos();
- #if 0
- TInt pos, length;
- pos = iRichText->CharPosOfParagraph(length, iCurrentPara);
- return pos+length-1;
- #endif
- }
- void CSimpleTextFormatParser::AppendTextL(const TDesC& aText)
- {
- // RDebug::Print(_L("text=%S"), &aText);
- iRichText->InsertL(TextPos(), aText);
- }
- #if 0
- void CTestDialog::ShowTextL(CRichText& aRichText)
- {
- aRichText.Reset();
- TCharFormat charFormat;
- TCharFormatMask charMask;
- aRichText.GetCharFormat(charFormat, charMask, 0, 0);
- TInt para = 0;
- AppendTextL(_L("http://www.yipton.net"), aRichText);
- para++;
- aRichText.AppendParagraphL();
- CParaFormat* paraFormat = CParaFormat::NewLC();
- TParaFormatMask paraMask;
- aRichText.GetParaFormatL(paraFormat, paraMask, ParaPos(aRichText, para), 0);
- paraFormat->iHorizontalAlignment = CParaFormat::ECenterAlign;
- paraMask.ClearAll();
- paraMask.SetAttrib(EAttAlignment);
- aRichText.ApplyParaFormatL(paraFormat, paraMask, ParaPos(aRichText, para), 0);
- charFormat.iFontPresentation.iUnderline = EUnderlineOn;
- charFormat.iFontSpec.iFontStyle.SetPosture(EPostureItalic);
- charMask.ClearAll();
- charMask.SetAttrib(EAttFontPosture);
- charMask.SetAttrib(EAttFontUnderline);
- aRichText.ApplyCharFormatL(charFormat, charMask, TextPos(aRichText, para));
- AppendTextL(_L("mailto:Peter is here"), aRichText, para);
- para++;
- aRichText.AppendParagraphL();
- TFontSpec fontSpec(_L("edmunds"), 20 * KPointsPerInch);
- // CFont* font = NULL;
- // iCoeEnv->ScreenDevice()->GetNearestFontInTwips(font, fontSpec);
- charFormat.iFontSpec = fontSpec;
- charMask.ClearAll();
- charMask.SetAttrib(EAttFontHeight);
- charMask.SetAttrib(EAttFontTypeface);
- aRichText.ApplyCharFormatL(charFormat, charMask, TextPos(aRichText, para));
- AppendTextL(_L("mailto:Peter is here"), aRichText, para);
- CleanupStack::PopAndDestroy();
- }
- #endif
|