/// <summary>Processes counters.</summary> /// <param name="cssProps">the CSS properties</param> /// <param name="context">the processor context</param> /// <param name="scope">the scope</param> public static void ProcessCounters(IDictionary <String, String> cssProps, CssContext context, INode scope) { String counterReset = cssProps.Get(CssConstants.COUNTER_RESET); if (counterReset != null) { CssCounterManager counterManager = context.GetCounterManager(); String[] @params = iText.IO.Util.StringUtil.Split(counterReset, " "); for (int i = 0; i < @params.Length; i++) { String counterName = @params[i]; int? possibleCounterValue; if (i + 1 < @params.Length && (possibleCounterValue = CssUtils.ParseInteger(@params[i + 1])) != null) { counterManager.ResetCounter(counterName, (int)possibleCounterValue, scope); i++; } else { counterManager.ResetCounter(counterName, scope); } } } String counterIncrement = cssProps.Get(CssConstants.COUNTER_INCREMENT); if (counterIncrement != null) { CssCounterManager counterManager = context.GetCounterManager(); String[] @params = iText.IO.Util.StringUtil.Split(counterIncrement, " "); for (int i = 0; i < @params.Length; i++) { String counterName = @params[i]; int? possibleIncrementValue; if (i + 1 < @params.Length && (possibleIncrementValue = CssUtils.ParseInteger(@params[i + 1])) != null) { counterManager.IncrementCounter(counterName, (int)possibleIncrementValue, scope); i++; } else { counterManager.IncrementCounter(counterName, scope); } } } }
private static void ProcessIncrement(String counterIncrement, CssContext context) { if (counterIncrement != null) { CssCounterManager counterManager = context.GetCounterManager(); String[] @params = iText.IO.Util.StringUtil.Split(counterIncrement, " "); for (int i = 0; i < @params.Length; i++) { String counterName = @params[i]; int? possibleIncrementValue; if (i + 1 < @params.Length && (possibleIncrementValue = CssDimensionParsingUtils.ParseInteger(@params[i + 1])) != null) { counterManager.IncrementCounter(counterName, (int)possibleIncrementValue); i++; } else { counterManager.IncrementCounter(counterName); } } } }
/// <summary>Resolves content.</summary> /// <param name="styles">the styles map</param> /// <param name="contentContainer">the content container</param> /// <param name="context">the CSS context</param> /// <returns> /// a list of /// <see cref="iText.StyledXmlParser.Node.INode"/> /// instances /// </returns> internal static IList <INode> ResolveContent(IDictionary <String, String> styles, INode contentContainer, CssContext context) { String contentStr = styles.Get(CssConstants.CONTENT); IList <INode> result = new List <INode>(); if (contentStr == null || CssConstants.NONE.Equals(contentStr) || CssConstants.NORMAL.Equals(contentStr)) { return(null); } CssDeclarationValueTokenizer tokenizer = new CssDeclarationValueTokenizer(contentStr); CssDeclarationValueTokenizer.Token token; CssQuotes quotes = null; while ((token = tokenizer.GetNextValidToken()) != null) { if (token.IsString()) { result.Add(new CssContentPropertyResolver.ContentTextNode(contentContainer, token.GetValue())); } else { if (token.GetValue().StartsWith(CssConstants.COUNTERS + "(")) { String paramsStr = token.GetValue().JSubstring(CssConstants.COUNTERS.Length + 1, token.GetValue().Length - 1); String[] @params = iText.IO.Util.StringUtil.Split(paramsStr, ","); if (@params.Length == 0) { return(ErrorFallback(contentStr)); } // Counters are denoted by case-sensitive identifiers String counterName = @params[0].Trim(); String counterSeparationStr = @params[1].Trim(); counterSeparationStr = counterSeparationStr.JSubstring(1, counterSeparationStr.Length - 1); String listStyleType = @params.Length > 2 ? @params[2].Trim() : null; CssCounterManager counterManager = context.GetCounterManager(); INode scope = contentContainer; if (CssConstants.PAGE.Equals(counterName)) { result.Add(new PageCountElementNode(false, contentContainer)); } else { if (CssConstants.PAGES.Equals(counterName)) { result.Add(new PageCountElementNode(true, contentContainer)); } else { String resolvedCounter = counterManager.ResolveCounters(counterName, counterSeparationStr, listStyleType, scope); if (resolvedCounter == null) { logger.Error(MessageFormatUtil.Format(iText.Html2pdf.LogMessageConstant.UNABLE_TO_RESOLVE_COUNTER, counterName )); } else { result.Add(new CssContentPropertyResolver.ContentTextNode(scope, resolvedCounter)); } } } } else { if (token.GetValue().StartsWith(CssConstants.COUNTER + "(")) { String paramsStr = token.GetValue().JSubstring(CssConstants.COUNTER.Length + 1, token.GetValue().Length - 1); String[] @params = iText.IO.Util.StringUtil.Split(paramsStr, ","); if (@params.Length == 0) { return(ErrorFallback(contentStr)); } // Counters are denoted by case-sensitive identifiers String counterName = @params[0].Trim(); String listStyleType = @params.Length > 1 ? @params[1].Trim() : null; CssCounterManager counterManager = context.GetCounterManager(); INode scope = contentContainer; if (CssConstants.PAGE.Equals(counterName)) { result.Add(new PageCountElementNode(false, contentContainer)); } else { if (CssConstants.PAGES.Equals(counterName)) { result.Add(new PageCountElementNode(true, contentContainer)); } else { String resolvedCounter = counterManager.ResolveCounter(counterName, listStyleType, scope); if (resolvedCounter == null) { logger.Error(MessageFormatUtil.Format(iText.Html2pdf.LogMessageConstant.UNABLE_TO_RESOLVE_COUNTER, counterName )); } else { result.Add(new CssContentPropertyResolver.ContentTextNode(scope, resolvedCounter)); } } } } else { if (token.GetValue().StartsWith("url(")) { IDictionary <String, String> attributes = new Dictionary <String, String>(); attributes.Put(AttributeConstants.SRC, CssUtils.ExtractUrl(token.GetValue())); //TODO: probably should add user agent styles on CssContentElementNode creation, not here. attributes.Put(AttributeConstants.STYLE, CssConstants.DISPLAY + ":" + CssConstants.INLINE_BLOCK); result.Add(new CssContentElementNode(contentContainer, TagConstants.IMG, attributes)); } else { if (CssGradientUtil.IsCssLinearGradientValue(token.GetValue())) { IDictionary <String, String> attributes = new Dictionary <String, String>(); attributes.Put(AttributeConstants.STYLE, CssConstants.BACKGROUND_IMAGE + ":" + token.GetValue() + ";" + CssConstants .HEIGHT + ":" + CssConstants.INHERIT + ";" + CssConstants.WIDTH + ":" + CssConstants.INHERIT + ";"); result.Add(new CssContentElementNode(contentContainer, TagConstants.DIV, attributes)); } else { if (token.GetValue().StartsWith("attr(") && contentContainer is CssPseudoElementNode) { int endBracket = token.GetValue().IndexOf(')'); if (endBracket > 5) { String attrName = token.GetValue().JSubstring(5, endBracket); if (attrName.Contains("(") || attrName.Contains(" ") || attrName.Contains("'") || attrName.Contains("\"")) { return(ErrorFallback(contentStr)); } IElementNode element = (IElementNode)contentContainer.ParentNode(); String value = element.GetAttribute(attrName); result.Add(new CssContentPropertyResolver.ContentTextNode(contentContainer, value == null ? "" : value)); } } else { if (token.GetValue().EndsWith("quote") && contentContainer is IStylesContainer) { if (quotes == null) { quotes = CssQuotes.CreateQuotes(styles.Get(CssConstants.QUOTES), true); } String value = quotes.ResolveQuote(token.GetValue(), context); if (value == null) { return(ErrorFallback(contentStr)); } result.Add(new CssContentPropertyResolver.ContentTextNode(contentContainer, value)); } else { if (token.GetValue().StartsWith(CssConstants.ELEMENT + "(") && contentContainer is PageMarginBoxContextNode ) { String paramsStr = token.GetValue().JSubstring(CssConstants.ELEMENT.Length + 1, token.GetValue().Length - 1); String[] @params = iText.IO.Util.StringUtil.Split(paramsStr, ","); if (@params.Length == 0) { return(ErrorFallback(contentStr)); } String name = @params[0].Trim(); String runningElementOccurrence = null; if (@params.Length > 1) { runningElementOccurrence = @params[1].Trim(); } result.Add(new PageMarginRunningElementNode(name, runningElementOccurrence)); } else { return(ErrorFallback(contentStr)); } } } } } } } } } return(result); }
/// <summary>Ends processing counters.</summary> /// <remarks> /// Ends processing counters. Pops values of given counter list from counters if necessary. /// Usually it is expected that this method should be called after processing cheldren of the element. /// </remarks> /// <param name="context">the processor context</param> /// <param name="element">the element which counters shall be processed</param> public static void EndProcessingCounters(CssContext context, IElementNode element) { CssCounterManager counterManager = context.GetCounterManager(); counterManager.PopEveryCounterFromCounters(element); }
/// <summary>Starts processing counters.</summary> /// <remarks> /// Starts processing counters. Pushes current counter values to counters if necessary. /// Usually it is expected that this method should be called before processing children of the element. /// </remarks> /// <param name="context">the processor context</param> /// <param name="element">the element which counters shall be processed</param> public static void StartProcessingCounters(CssContext context, IElementNode element) { CssCounterManager counterManager = context.GetCounterManager(); counterManager.PushEveryCounterToCounters(element); }