mxGraph export image loss css - html

my english is poor,sorry,i used mxGraph js front-end invoke java back-end servlet to export image,the graph contains html and css,the format of export is png,but the result of export lossed css,but the xml data contains css

To add the CSS in Java if using the export XML format, the createHtmlDocument(String, String) method can be overridden and the CSS can be added as an internal stylesheet (ie in the HEAD section inside a style tag) as follows:
protected String createHtmlDocument(String text, String style)
{
return "<html><head><style type=\"text/css\">.myStyle {color:blue;}</style></head><div style=\"" + style + "\">" + text + "</div></html>";
}

Related

Add Code and pre tags to include code sample to angular component template

I was using <code> & <pre> tags in html pages to include code samples in my website...
Like:
<pre class="code">
// Host creation
public class Program
{
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}
services.AddTransient<IDataAccessLayer>(a => new DataAccessLayer(_config));
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
}
</pre>
The same pre tag when I use inside my angular component file its showing error for opening brace { and 'IDataAccessLayer' is not a known element.
I replaced all my "{", "}" with ( and )
Now the C# sample code inside <pre> is still showing error. Is there any way of displaying the sample code block in the component as I have multiple code block returning the html through function is not feasible.
package
version installed
angular cli
13.2.6
TS
4.5.5
Have you seen this lib ngx-highlight ?

Qt: Set background image on QTextDocument using HTML to generate pdf file

i am wrapping my head in this problem for a few time.
I need to create a report by creating a pdf file with some data on it.
So my plan was to instead of using the QTextCursor, i use HTML + CSS to create the content in my pdf file.
Unfortunately I can't go with the QWebEngine widgets solution because I am compiling into MinGW and setting the MVSC 2017 environment is a huge mess.
Sadly i have to go with the QTextDocument and his HTML subset support.
My problem is I can't put a background image in my pdf file.
I want to put this image as a background image:
What make me crazy is that I use the css property to display a background image in my pdf file.
background-image: url(:/images/blue-gradient-background.jpg);
And it seems that Qt is taking this into account but it still don't display the background.
Have a look:
The first pdf file don't contain the css property background image on the html content but the second does and you can see that the size of the file is bigger so it has considered the css property.
But it hasn't displayed the background:
On the left is the first file and on the right is the second file with the css property.
I use a html file in the ressource to generate the report :
<!DOCTYPE html>
<html>
<style>
body {
background-image: url(:/images/blue-gradient-background.jpg);
}
h1 {
color: blue;
}
#table-content {
}
#table-content table {
margin: 1em
}
</style>
<body>
<div align="center"><h1>[title-template]</h1></div>
<div align="center" id="table-content">[table-template]</div>
</body>
</html>
This html file is open and read in the constructor of the class:
FileEditor::FileEditor()
{
QFile htmlTemplate(":/html/report.html");
if (htmlTemplate.open(QIODevice::ReadOnly | QIODevice::Text))
{
QTextStream in(&htmlTemplate);
m_reportPageHTMLTemplate = in.readAll();
}
}
Then i use a custom class with this function that use QPrinter and QPainter to write the data:
void FileEditor::writeReportPdfFile(const QString &i_path, const S12xConf &i_s12xConf, const S12xData &i_s12xData, const BenchTestData &i_benchTestData)
{
QDir directory(i_path); // we create a QDir with the path
if (!directory.exists()) // if the directory does not exist then
{
directory.mkpath("."); // we create the path
}
QString fileName = getCurrentHourDate() + "_S12xNG_Test_Report.pdf";
QPrinter pdfPrinter(QPrinter::HighResolution);
pdfPrinter.setOutputFormat(QPrinter::PdfFormat);
pdfPrinter.setPageSize(QPageSize(QPageSize::A4));
pdfPrinter.setOutputFileName(i_path + "/" + fileName);
pdfPrinter.setFullPage(true);
QPainter painter(&pdfPrinter);
painter.setBackgroundMode(Qt::OpaqueMode);
QTextDocument measuresDoc;
QTextDocument averagesDoc;
QTextDocument inOutDoc;
measuresDoc.documentLayout()->setPaintDevice(&pdfPrinter);
measuresDoc.setPageSize(pdfPrinter.pageRect().size());
averagesDoc.documentLayout()->setPaintDevice(&pdfPrinter);
averagesDoc.setPageSize(pdfPrinter.pageRect().size());
inOutDoc.documentLayout()->setPaintDevice(&pdfPrinter);
inOutDoc.setPageSize(pdfPrinter.pageRect().size());
setMeasuresTextDocument(&measuresDoc);
setAveragesTextDocument(&averagesDoc);
setInputsOutputsTextDocument(&inOutDoc);
measuresDoc.drawContents(&painter); // We print TextDocument of the Measures into the document
pdfPrinter.newPage(); // We inject the current page and continue printing on new page
averagesDoc.drawContents(&painter); // We print the TextDocument of the Averages into the document
pdfPrinter.newPage(); // We inject the current page and continue printing on new page
inOutDoc.drawContents(&painter); // We print the TextDocument of the Inputs/Outputs into the document
measuresDoc.undo();
averagesDoc.undo();
inOutDoc.undo();
}
Here is the function to add the html data into the measures QTextDocument:
void FileEditor::setMeasuresTextDocument(QTextDocument *o_measuresDoc)
{
QString htmlContent = m_reportPageHTMLTemplate;
htmlContent.replace("[title-template]","I. Measures Data");
o_measuresDoc->setHtml(htmlContent);
}
So what i am doing wrong?
Thanks in advance for your responses.
I have found the answer!
it is about the drawContents method of QTextDocument.
There is a second parameter that you need to add in order to see the background image in your document.
It's the a QRectF object that represend the size of the rect that the background image will be clipped into.
void QTextDocument::drawContents(QPainter *p, const QRectF &rect = QRectF())
Draws the content of the document with painter p, clipped to rect. If rect is a null rectangle (default) then the document is painted unclipped.
So what I did is:
easuresDoc.drawContents(&painter, pdfPrinter.paperRect()); // We print TextDocument of the Measures into the document
pdfPrinter.newPage(); // We inject the current page and continue printing on new page
averagesDoc.drawContents(&painter, pdfPrinter.paperRect()); // We print the TextDocument of the Averages into the document
pdfPrinter.newPage(); // We inject the current page and continue printing on new page
inOutDoc.drawContents(&painter, pdfPrinter.paperRect()); // We print the TextDocument of the Inputs/Outputs into the document
pdfPrinter.paperRect is the rectangle of the page without the margin.
Also if you want the background image to be printed scaled with no repeat than you need to put the printer into QPrinter::PrinterResolution
QPrinter pdfPrinter(QPrinter::PrinterResolution);

Compile CSS into HTML as Inline Style in Grails?

I want to generate GSP templates for html emails. To support more mail clients it is recommended to use inline css in html style elements.
Here is a discussion on that topic: "Compile" CSS into HTML as inline styles
Is there a Grails plugin where I can specify certain GSP files for which the CSS should be compiled as inline?
If there is no plugin, how can I specify GSP files for which the css should be complied inline?
Here is an example. I have the following GSP templates for my html mails that I send with the Grails mail plugin.
/mail/signup_mail.gsp
/mail/welcome.gsp
/mail/newsletter.gsp
Each GSP file includes a style.css file. This should be compiled inline.
We do this with a free method on the Mailchimp API. You can also use Premailer.
http://apidocs.mailchimp.com/api/1.2/inlinecss.func.php
http://premailer.dialect.ca/
You can fit the following Java code in your grails application.
import java.io.IOException;
import java.util.StringTokenizer;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
public class AutomaticCssInliner {
public static void main(String[] args) throws IOException {
final String style = "style";
final String html = "<html>" + "<body> <style>"
+ "body{background:#FFC} \n p{background:red}"
+ "body, p{font-weight:bold} </style>"
+ "<p>...</p> </body> </html>";
// Document doc = Jsoup.connect("http://mypage.com/inlineme.php").get();
Document doc = Jsoup.parse(html);
Elements els = doc.select(style);// to get all the style elements
for (Element e : els) {
String styleRules = e.getAllElements().get(0).data().replaceAll(
"\n", "").trim(), delims = "{}";
StringTokenizer st = new StringTokenizer(styleRules, delims);
while (st.countTokens() > 1) {
String selector = st.nextToken(), properties = st.nextToken();
Elements selectedElements = doc.select(selector);
for (Element selElem : selectedElements) {
String oldProperties = selElem.attr(style);
selElem.attr(style,
oldProperties.length() > 0 ? concatenateProperties(
oldProperties, properties) : properties);
}
}
e.remove();
}
System.out.println(doc);// now we have the result html without the
// styles tags, and the inline css in each
// element
}
private static String concatenateProperties(String oldProp, String newProp) {
oldProp = oldProp.trim();
if (!newProp.endsWith(";"))
newProp += ";";
return newProp + oldProp; // The existing (old) properties should take precedence.
}
}

Adding html text to Word using Interop

I'm trying to add some HTML formatted text to Word using Office Interop. My code looks like this:
Clipboard.SetText(notes, TextDataFormat.Html);
pgCriteria.Range.Paste();
but it's throwing a Command Failed exception. Any idea?
After spending several hours the solutions is to use this excellent class
http://blogs.msdn.com/jmstall/pages/sample-code-html-clipboard.aspx
This worked for me on Windows 7 and Word 2007:
public static void pasteHTML(this Range range, string html)
{
Clipboard.SetData(
"HTML Format",
string.Format("Version:0.9\nStartHTML:80\nEndHTML:{0,8}\nStart" + "Fragment:80\nEndFragment:{0,8}\n", 80 + html.Length) + html + "<");
range.Paste();
}
Sample use: range.pasteHTML("a<b>b</b>c");
Probably a bit more reliable way without using the clipboard is to save the HTML fragment in a file and use InsertFile. Something like:
public static void insertHTML(this Range range, string html) {
string path = System.IO.Path.GetTempFileName();
System.IO.File.WriteAllText(path, "<html>" + html); // must start with certain tag to be detected as html: <html> or <body> or <table> ...
range.InsertFile(path, ConfirmConversions: false);
System.IO.File.Delete(path); }
It is kind of tricky to add the html in a word document. The best way is creating a temporary file and than insert this file to selected range of the word. The trick is to leverage the InsertFile function of the Range. This allows us to insert arbitrary HTML strings by first saving them as files to a temporary location on disk.
The only trick is that < html/> must be the root element of the
document.
I use something like this at one of my project.
private static string HtmlHeader => "<html lang='en' xmlns='http://www.w3.org/1999/xhtml'><head><meta charset='utf-8' /></ head >{0}</html>";
public static string GenerateTemporaryHtmlFile(Range range,string htmlContent)
{
string path = Path.GetTempFileName();
File.WriteAllText(path, string.Format(HtmlHeader , htmlContent));
range.InsertFile(FileName: tmpFilePath, ConfirmConversions: false);
return path;
}
it is important to adding
charset='utf-8'
to head of html file other wise you may see unexpected characters at your word document after you insert file.
Just build a temporary html file with your html content and insert it like below.
// 1- Sample HTML Text
var Html = #"<h1>Sample Title</h1><p>Lorem ipsum dolor <b>his sonet</b> simul</p>";
// 2- Write temporary html file
var HtmlTempPath = Path.Combine(Path.GetTempPath(), $"{Path.GetRandomFileName()}.html");
File.WriteAllText(HtmlTempPath, $"<html>{Html}</html>");
// 3- Insert html file to word
ContentControl ContentCtrl = Document.ContentControls.Add(WdContentControlType.wdContentControlRichText, Missing);
ContentCtrl.Range.InsertFile(HtmlTempPath, ref Missing, ref Missing, ref Missing, ref Missing);

jsf messages: adding link

Currently in JSF, all HTML contained within a message (rich:messages tag) is escaped and just shows up as the markup. For example, in my backing bean, I have:
createMessage("Title created successfully with product number: " + product.getProductNumber() + ".");
where createMessage() is just a helper function that adds a new Message to the faces context and is then viewable in my rich:messages tag.
When this message is created, my message simply shows up with the escaped HTML:
Title created successfully with product number: 1234.
Is there any way to avoid this and just provide an actual link in the message instead?
Thanks in advance
~Zack
A quick solution is to create a new renderer.
I've done this for h:messages as I wanted to separate the messages of different severities into separate divs. If you never want to use the default renderer then it's a good option.
The standard class that you would overwrite/extend is:
public class MessagesRenderer extends HtmlBasicRenderer
You would just use a ResponseWriter that doesn't escape the text. The concrete class is the HtmlResponseWriter which escapes the text. You could extend this and overwrite the
public void writeText(Object text, String componentPropertyName)
so that it doesn't use HtmlUtils.
Then just add your new renderer to faces-config.xml
<render-kit>
<renderer>
<component-family>javax.faces.Messages</component-family>
<renderer-type>javax.faces.Messages</renderer-type>
<renderer-class>com.mypackage.MessagesRenderer</renderer-class>
</renderer>
</render-kit>
It sounds like you need to create your own version of rich:messages that has an escape attribute, like h:outputText, so you can disable HTML escaping.
If you're using jquery you can unescape the xml characters:
<script type="text/javascript">
//<![CDATA[
$(document).ready(function() {
$(".esc").each(function(i) {
var h = $(this).html();
h = h.replace(/</gi, "<");
h = h.replace(/>/gi, ">");
$(this).html(h);
});
});
//]]>
</script>