In itextsharp, i use
var paragraph = new Paragraph();
var reader = new StringReader(text);
var handler = new HtmlHandler();
XMLWorkerHelper.GetInstance().ParseXHtml(handler, reader);
foreach (var element in handler.elements)
{
paragraph.Add(element);
}
to get the IElements of a given HTML text "text" since
iTextSharp.text.html.simpleparser.HTMLWorker.ParseToList (reader, stylesheet)
is deprecated and I had some problem with unorderded lists (the list items were not indented and had not bullet).
Is there a possibility to include a css-file (like in the old version of the parser)?
Thanks in advance!
In the current version of the API, ParseXHtml has an overload for passing in a css file.
Related
I use itextsharp for creating a pdf. I need to place XHTML on it so I uase the XMLWorkerHelper class:
iTextSharp.tool.xml.XMLWorkerHelper worker = iTextSharp.tool.xml.XMLWorkerHelper.GetInstance();
worker.ParseXHtml(pdfWrite, doc, new StringReader(sb.ToString()));
However I would like to specify a position for the parsed XHTML. How do I do that?
EDIT:
I thought I will post the code in the case someone else runs into this. The link provided below was for JAVA and in C# things work a bit different.
First you need a class for gathering the Elements:
class ElementHandlerClass : iTextSharp.tool.xml.IElementHandler
{
public List<IElement> elements = new List<IElement>();
public void Add(iTextSharp.tool.xml.IWritable input)
{
if (input is iTextSharp.tool.xml.pipeline.WritableElement)
{
elements.AddRange(((iTextSharp.tool.xml.pipeline.WritableElement)input).Elements());
}
}
}
Then you use it
ElementHandlerClass ehc = new ElementHandlerClass();
worker.ParseXHtml(ehc, new StringReader(sb.ToString()));
Now you have the elements. Next step is to create a ColumnText and fill it with the Elements:
iTextSharp.text.pdf.ColumnText ct = new iTextSharp.text.pdf.ColumnText(pdfWrite.DirectContent);
ct.SetSimpleColumn(200, 300, 300, 500);
foreach (IElement element in ehc.elements)
ct.AddElement(element);
ct.Go();
You need to combine the answers of two previous questions on StackOverflow.
The first answer you need, is the one to How to get particular html table contents to write it in pdf using itext
In this answer, you learn how to parse an XHTML source into a list of Element objects.
Once you have this list, you need the answer to itext ColumnText ignores alignment
You can create a ColumnText object, define a rectangle with the setSimpleColumn() method, add all the elements retrieved from the XHTML using XML Worker with the addElement() method, and go() to add that content.
I hope someone will be able to help here, so first of all though let's take a look at exactly what my problem is ...
I would have liked to insert a movieclip from an external swf into my textarea but I think it isn't as easy as I thought... because the Textarea,TextFlow components are unfortunately almost unusable to me in this respect ..
I have read the API of Textarea and TextFlow , and I searched a lot on Google and some forums, but I have not found the solution to my problem.
I have found similar topics to this one like as :
Using symbol from library in htmlText <img> tag in ActionScript 3
http://help.adobe.com/en_US/AS2LCR/Flash_10.0/help.html?content=00000322.html
I have tried several ways to refer to the symbol but to no avail...
Here is my code :
[Bindable]
/**
* The text which will be displayed
**/
public var pblMessages:String = "";
<s:TextArea id="pblArea" left="10" right="242" top="241" bottom="55" editable="false"
textFlow="{TextConverter.importToFlow(pblMessages,TextConverter.TEXT_FIELD_HTML_FORMAT)}"
valueCommit="pblAreaCommitHandler(event)">
</s:TextArea>
Method for adding new line :
private function submitText(keyPress:Boolean=false) :void {
if (pblInput.text=="") {
pblInput.setFocus();
return;
}
var format:ElementFormat = new ElementFormat();
var fontDescription:FontDescription = new FontDescription("Arial");
format.fontSize = 11;
format.fontDescription = fontDescription;
var s:String = pblInput.text;
var re: RegExp = new RegExp("\r|\n","gi");
s = s.replace(re,"");
var inlineGraphicElement:InlineGraphicElement = new InlineGraphicElement();
inlineGraphicElement.source = Smileys.smi_kiss;
var p:ParagraphElement = new ParagraphElement();
p.addChild(inlineGraphicElement);
//pblArea.textFlow.addChild(p);
pblMessages += "<font color='#000000'>" + s + "</font><img src='assets/testmovie.swf#smi_kiss' width='20' height='20'/><br/>";
pblInput.text="";
}
If the smiley is displayed on the first frame in the swf, then it displayed (without symbol) too in the TextArea of course.. but I don't want to make 100 different swf file.. I'm quite sure that the smileys can be displayed by using symbols.
Thank you in advance for your help.
Try to create complete TextFlow without using TextConverter.importToFlow. After adding inlineGraphicElement to p, you should add a SpanElement to p, and then add text to SpanElement.text, and then assign a textFlow to pblArea.textFlow.
However I try to create an HTMLNode for the P tag and inject it into the HTMLDocument DOM, it always appears as an unclosed tag. For example.
// different ways I've tried creating the node:
var p = HtmlNode.CreateNode("<p />");
var p = HtmlNode.CreateNode("<p></p>");
var p = HtmlNode.CreateNode("<p>");
var p = HtmlTextNode.CreateNode("<p></p>");
// some other properties I've played with:
p.Name = "p";
p.InnerHtml = "";
They all end up as just <p> in the output after using the .Save() method.
I want it properly closed for XHTML like <p /> or <p></p>. Either is fine.
My workaround: What I can do is issue CreateNode("<p> </p>") (with a space in between) and it retains the entire source, but I think there has to be a better way.
Other options tried or considered:
When I turn on the option .OutputAsXml it escapes the existing entities, for example turns to which is not ideal, and it doesn't close my injected P tag.
when I enable the option .OptionWriteEmptyNodes it still doesn't close my injected P tag.
I see the Agility Pack contains the enum HtmlElementFlag with values Closed, Empty, CData, CanOverlap (Closed might be useful) but cannot see where I would apply it when creating a new element/node.
I found the answer: the P tag has to be created off the HtmlDocument instance using the CreateElement(..) factory method like so:
var hdoc = new HtmlDocument(); // HTML doc instance
// ... stuff
HtmlNode p = hdoc.CreateElement("p"); // << will close itself for XHTML.
Then P will close itself like <p />.
If you instead create an HtmlNode instance using the HtmlNode.CreateNode(..) factory method like I was trying in the question, it behaves differently in the DOM as far as closure.
HtmlNode.ElementsFlags["p"] = HtmlElementFlag.Closed;
Default value for "p" is "Empty | Closed". You should to set it as "Closed" to return:
<p></p>
I've reviewed all the documentation and Google results surrounding this and I think I have everything setup correctly. My problem is that the symbol is not appearing in my app. I have a MovieClip symbol that I've embedded to my Flex Component. I need to create a new Image control for each item from my dataProvider and assign this embedded symbol as the Image's source. I thought it was simple but apparently not. Here's a stub of the code:
[Embed(source="../assets/assetLib.swf", symbol="StarMC")]
private var StarClass:Class;
protected function rebuildChildren():void {
iterator.seek( CursorBookmark.FIRST );
while ( !iterator.afterLast ) {
child = new Image();
var asset:MovieClipAsset = new StarClass() as MovieClipAsset;
(child as Image).source = asset;
}
}
I know the child is being created because I can draw a shape and and that appears. Am I doing something wrong? Thank you!
You should be able to simply set child.source to StarClass:
child = new Image();
child.source = StarClass;
See the MovieClipAsset Language Reference for more details:
you rarely need to create MovieClipAsset instances yourself
because image-related properties and
styles can be set to an
image-producing class, and components
will create instances as necessary.
For example, to set the application
background to this animation, you can
simply write the following:
<mx:Application backgroundImage="{backgroundAnimationClass}"/>
Will this run inside an ASCX file in my ASP.Net project?
I can't seem to get it to work, just wondered if there was some particular thing missing? Do i need to include "runat="server""?
<!--[if lte IE 6]>
<script type="text/javascript">
window.onload = function() {
var images = document.getElementById("GetQuote").getAttribute("ImageUrl");
for (var i = 0; i < images.length; i++) {
var image_png_src = images[i].src;
var image_gif_src = image_png_src.replace(".png", ".gif");
images[i].src = image_gif_src;
}
};
</script>
<![endif]-->
It appears that this JavaScript function is attempting to reference ASP.NET web control properties, which are not accessible from the client side. You can, however, reference the HTML entities that are output to the page by ASP.NET, along with their attributes.
Assuming your JavaScript code is code within the .ascx code, change this line:
var images = document.getElementById("GetQuote").getAttribute("ImageUrl");
To this:
var images = document.getElementById('<%=GetQuote.ClientID%>').getAttribute("src");
What this does is insert the client ID that ASP.NET creates for the GetQuote Image control so that it can be referenced from the client side. It also references the proper attribute of the HTML img element (src) that corresponds to the ImageUrl property of the server side Image control.
EDIT:
I noticed after seeing TheVillageIdiot's response (and reading your code a bit more closely, which I should have done initially) that you are trying to use the images variable as an array. It appears that you may be trying to match several image elements that contain the text "GetQuote" in their IDs (like GetQuote1, GetQuote2, etc.).
Assuming that you need to do this on the client side, and that you are not using a framework like jQuery, try this:
window.onload = function()
{
// get all img elements on the page and load them into an array
var images = document.getElementsByTagName("img");
// iterate through the image array
for (var i = 0; i < images.length; i++)
{
// check that the current image's id contains "GetQuote" (case sensitive)
if (images[i].id.indexOf("GetQuote") >= 0)
{
var image_png_src = images[i].src;
var image_gif_src = image_png_src.replace(".png", ".gif");
images[i].src = image_gif_src;
}
}
};
You don't need a runat="server" because this is code that will run on the client. It should work, but maybe you are having problems because you are referencing IDs on items that are asp.net controls? This would mean that your ID values would not match. If so you could solve this by using control.ClientID redndered into the JavaScript server-side to make them match.
If GetQuote is an aspx element then you need to replace it with <%= GetQuote.ClientID %> and ImageUrl with src like
var images = document.getElementById('<%=GetQuote.ClientID%>')
.getAttribute("src");
Also images should be one string not an array of strings so your loop is also at fault. Try this one instead:
var image = document.getElementById('<%=GetQuote.ClientID%>').
if(images){
var src = image.GetAttribute("src");
image.SetAttribute("src",src.replace(".png", ".gif");
}