I'm using tinymce to edit some field in a web application.
I need to have an html result (after editing) with some specification.
For example: when I press enter tinymce create a new paragraph (that's ok, and I know this behaviour can be changed, but paragraph is ok).
What I need is a specific style to the paragraph be applied.
I saw there is the possibility to specify content_css, but this is a visual deformation of what is written in the edited html.
my need is when I press enter a paragraph with specific style (margin, alignmnent, ..) must be written directly in the edited html text.
e.g. <P style="margin-top:2px; margin-bottom:10px"> ...</P>
Is it possibile to define specific style to be applied to each html tags ?
I need this because after editing, the html content is used in another part of application, where I can not add additional style configurations.
Did you try that?
...
'content_css' : './path/to/your/styles.css',
...
styles.css
p {
margin-top:2px;
margin-bottom:10px
}
..I saw there is the possibility to specify content_css, but this is a visual deformation..
True, but don't forget that this visual deformation is extracted when you call tinyMCE.activeEditor.getContent().
Though, i'm not sure it will extract your specific styles applied to <p> (untested)
Check also here
UPDATED
Ok, i have another suggestion using HTML parsing using this.
$html = str_get_html("<div>add here your HTML from tinymce editor <p></p></div> test <p></p>");
foreach($html->find("p") as $p) {
$p->style = "margin:2px 0 10px 0";
}
$html_modified = $html;
The $html_modified should contain the <p> with margin applied.
Yes it is possible in tinymce. Just go to Tools -> Source Code of the editor toolbar. Write your HTML code with style there. You can try yourself.
Related
I'm testing out CKEditor
I'm trying to get the display in the editor, to match my sites css style for displaying the end result.
What I'm trying to do is style the "wrap code" button to match the css of my site, by adding in a class.
I've seen on this page of the manual, that you can do stuff like this:
config.format_pre = { element: 'pre', attributes: { 'class': 'editorCode' } };
However, doing the same for a code block like so:
config.format_code = { element: 'code', attributes: { 'class': 'someclass' } };
Doesn't actually do anything. Anyone got a pointer on what I might be missing?
I've tested it working on other elements, so I know the config file changes are being picked up.
The one important thing is that every tag which is formatted via config.format_tagname should be also included in config.format_tags. However, this two settings (config.format_tagname and config.format_tags) works only form Block-Level elements (as stated in the manual page you referenced ).
As code element is considered as an inline one by CKEditor (see DTD), it is not possible to use this config here.
However, the easiest way to modify the elements added via Style dropdown is to edit styles.js file which is present in CKEditor directory. The dropdown styles are based on this file, so you can easily modify code element there. You can also define your custom stylesSet.
I designed my resume with bootstrap and material design lite, now I want to convert the html page to pdf file.
I tried some libraries (jsPdf) and some tools (html2pdf, princexml), it produces the pdf file but the problem is, that pdf is not what it looks in the html page.
There is no styles, the output i am getting is similar to pressing ctrl+p` in browser.
My question is,
Is there any tools or libraries for my problem ?
or
Is there any options in above mentioned tools that i can use?
pdf outputs
Try this converter WKHTMLTOPDF on your back-end. It outputs exactly what your see in you browser. It supports html, css and even js. Wkhtmltopdf based on webkit.
Using runtime it can be used like that
wkhtmltopdf http://google.com google.pdf
In your case, it seems that wkhtmltopdf can not load css. Check right css include path. Do not use relative path.
Your problem is the Bootstrap library, not any plugins or PDF tools you are using. It removes most styles when you "print" a web page, including print to PDF. My company, the DocRaptor HTML to PDF service, has a great blog post with a list of suggested fixes for getting Bootstrap styles to print correctly, but they could be summarized as:
Print using screen CSS mode/rules, not print. Otherwise, you have to a lot of overrides for Bootstrap to get it to work right. Much easier to just make the renderer use screen mode.
Bootstrap will think most PDFs are an extra small device, like a cell phone, so you have to either adjust your breakpoints or your in-code column definitions.
If your last column drops to a new row, this is because Bootstrap defines the width for many columns as XX.66666667%. The PDF engine adds all these up, and because of the 7 at the end, it is technically greater than 100%. Since the row width is over 100%, it bumps the last column to a new row. the fix is to override Bootstrap's column widths (handy Gist file for that).
jsPDF is able to use plugins. In order to enable it to print HTML, you have to include certain plugins and therefore have to do the following:
Go to https://github.com/MrRio/jsPDF and download the latest Version.
Include the following Scripts in your project:
jspdf.js
jspdf.plugin.from_html.js
jspdf.plugin.split_text_to_size.js
jspdf.plugin.standard_fonts_metrics.js
If you want to ignore certain elements, you have to mark them with an ID, which you can then ignore in a special element handler of jsPDF. Therefore your HTML should look like this:
<!DOCTYPE html>
<html>
<body>
<p id="ignorePDF">don't print this to pdf</p>
<div>
<p><font size="3" color="red">print this to pdf</font></p>
</div>
</body>
</html>
Then you use the following JavaScript code to open the created PDF in a PopUp:
var doc = new jsPDF();
var elementHandler = {
'#ignorePDF': function (element, renderer) {
return true;
}
};
var source = window.document.getElementsByTagName("body")[0];
doc.fromHTML(
source,
15,
15,
{
'width': 180,'elementHandlers': elementHandler
});
doc.output("dataurlnewwindow");
For me this created a nice and tidy PDF that only included the line 'print this to pdf'.
Please note that the special element handlers only deal with IDs in the current version, which is also stated in a GitHub Issue. It states:
Because the matching is done against every element in the node tree, my desire was to make it as fast as possible. In that case, it meant "Only element IDs are matched" The element IDs are still done in jQuery style "#id", but it does not mean that all jQuery selectors are supported.
Therefore replacing '#ignorePDF' with class selectors like '.ignorePDF' did not work for me. Instead you will have to add the same handler for each and every element, which you want to ignore like:
var elementHandler = {
'#ignoreElement': function (element, renderer) {
return true;
},
'#anotherIdToBeIgnored': function (element, renderer) {
return true;
}
};
From the examples it is also stated that it is possible to select tags like 'a' or 'li'. That might be a little bit to unrestrictive for the most usecases though:
We support special element handlers. Register them with jQuery-style
ID selector for either ID or node name. ("#iAmID", "div", "span" etc.)
There is no support for any other type of selectors (class, of
compound) at this time.
One very important thing to add is that you lose all your style information (CSS). Luckily jsPDF is able to nicely format h1, h2, h3 etc., which was enough for my purposes. Additionalyl it will only print text within text nodes, which means that it will not print the values of textareas and the like. Example:
<body>
<ul>
<!-- This is printed as the element contains a textnode -->
<li>Print me!</li>
</ul>
<div>
<!-- This is not printed because jsPDF doesn't deal with the value attribute -->
<input type="textarea" value="Please print me, too!">
</div>
</body>
Is there any easy way to take in a block of CSS from the user from an textarea and add this styling to the styling for a specific div?
See I'm creating a simple code preview tool like codePen, so far I have two textarea inputs, one for Html and one for CSS, as the user types in the Html input this updates the preview pane, this works, now I want to do it for CSS.
CSS textarea could contain a few blocks like:
h1 {
font-size:23px;
}
.myClass {
//Somestyle
}
Now I want this CSS to be contained in the
<div id="preview"></div>
So it doesnt effect the rest of the page, so a manual example would be
$('preview h1').css('font-size','23px');
Anyway to automate this?
Do it like this. Hope it works.
Add a style block for dynamic styling.
<style id="dynamicCss">
</style>
on the apply button click handler, set the style
$('#btnApplyStyle').click(function(){
$('#dynamicCss').html('').html($('#txtaCustomCss').val());
});
See the Fiddle here.
Please use developer tools to see the new style tag added to head section.
This script simply adds rule to the document. If you don't want that behavior, you can use this plugin in combination with my logic to set scope for rule. You will need to place the style tag inside of the container and add a scoped attribute to style for it to work. Please see the documentation.
If you want to use the iframe approach instead, you'll first need an HTML document to host inside of the iframe. The iframe document should be loaded for the same origin (protocol + domain) as the host document (cross-document cross-domain stuff is tricky otherwise). With your application, this is probably not an issue.
Host page:
<iframe id="preview" src="preview.html"></iframe>
To make things easier on yourself, this iframe document could load a script with convenience functions for injecting the HTML and CSS from the host.
preview.html:
<html>
<head>
<script src="preview.js"></script>
<style type="text/css" id="page-css"></style>
</head>
<body></body>
</html>
preview.js:
function setHTML(html) {
document.querySelector('body').innerHTML = html;
}
function setCSS(css) {
var stylesheet = document.querySelector('#page-css');
// Empty the stylesheet
while (stylesheet.firstChild) {
stylesheet.removeChild(stylesheet.firstChild);
}
// Inject new CSS
stylesheet.appendChild(document.createTextNode(css));
}
Now, from the host page, you can call these functions whenever your text inputs change:
document.querySelector('#preview').contentWindow.setCSS(someCSS);
This plugin may come in handy: https://github.com/websanova/wJSNova/downloads .
Edited
Insert the text of the rules in one of the existing cssStyleSheets you have.
It will be something like
window.document.styleSheets[0].insertRule("a{color:red;}",window.document.styleSheets[0].cssRules.length)
The first parameter is the rule to insert and the second is the index.
Fiddle
The only problem here is that this will affect all the DOM on the page maybe looking for a way to add the #preview before each css rule to get something like
#preview h1{}
I was wondering if it were possible to preformat text that is inside a textarea. Right now I have a textarea code that I want to add syntax highlighting and also add linenumbers so I am trying to wrap the text inside a pre tag. Is this correct or should I be doing something completely different?
<textarea id="conversation" class="codebox" style="font-family:courier;">
<pre class="brush: js;">// Start typing...</pre>
</textarea>
textareas are not able to render content like you're wanting to do, they only display text. I would suggest an in-browser code editor. A good one is CodeMirror, which is fairly easy to use:
HTML
<textarea id="code" name="code">
// Demo code (the actual new parser character stream implementation)
function StringStream(string) {
this.pos = 0;
this.string = string;
}
...
</textarea>
Javascript
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
matchBrackets: true
});
And CodeMirror insert an editable block with that content within the new editor.
There are other options. Wikipedia has a comparison of Javascript-based source code editors entry.
Having the Pre tag contain the textarea works in Chrome
The textarea element content is treated as preformatted in implementations, though browsers by default line wrap the text if a line is longer than specified by the cols attribute. The wrapping can be disabled using the nonstandard but widely supported attribute wrap=off.
The textarea element is not adequate for mere display of content, though. Neither is it suitable for setting up an input editor with formatting features, since all markup inside textarea is taken literally.
We've got a little tool that I built where you can edit a jQuery template in one field and JSON data in another and then hit a button to see the results immediately within the browser.
I really need to expand this though so the designer can edit a full CSS stylesheet within another field and when we render the template, it will have the CSS applied to it. The idea being that once we've got good results we can take the contents of these three fields, put them in files and use them in our project.
I found the jQuery.cssRule plugin but it looks like it's basically abandoned (all the links go nowhere and there's been no development in three years). Is there something better or is it the only game in town?
Note: We're looking for something where someone types traditional CSS stylesheet data in here and that is used immediately for rendering within the page and that can be edited and changed at will with the old rules going away and new ones used in their stead. I'm not looking for something where the designer has to learn jQuery syntax and enter in individual .css("attribute", "value") type calls to jQuery.
Sure, just append a style tag to the head:
$("head").append("<style>p { color: blue; }</style>");
See it in action here.
You can replace the text in a dynamically added style tag using something like this:
$("head").append("<style id='dynamicStylesheet'></style>");
$("#dynamicStylesheet").text(newStyleTextGoesHere);
See this in action here.
The cleanest way to achieve this is by sandboxing your user-generated content into an <iframe>. This way, changes to the CSS won't affect the editor. (For example, input { display:none; } can't break your page.)
Just render out your HTML (including the CSS in the document's <head>, and write it into the <iframe>.
Example:
<iframe id="preview" src="about:blank">
var i = $('#preview')[0];
var doc = i.contentWindow || i.contentDocument;
if (doc.document) doc = doc.document;
doc.open('text/html',true);
doc.write('<!DOCTYPE html><html>...</html>');
doc.close();
If the user should be able to edit a whole stylesheet, not only single style attributes, then you can store the entered stylesheet in a temporary file and load it into your html document using
$('head').append('<link rel="stylesheet" href="temp.css" type="text/css" />');
sounds like you want to write an interpreter for the css? if it is entered by hand in text, then using it later would be as simple as copy and pasting it into a css file.
so if you have a textarea on your page to type in css and want to apply those rules when you press the button, you could use something like this (only pseudocode, needs work):
//for each css id in the text area
$.each($('textarea[name=cssTextArea]').html().split('#'), function({
//now get each property
$.each($(this).split(';'), function(){
$(elem).css({property:value});
});
});
then you could write something to go through each element that your designer typed in, and get the current css rules for it (including those that you applied using some code like the snippet above) and create a css string from that which could then be output or saved in a db. It's a pain and much faffing around with substrings but unfortunately I don't know of a faster or more efficient way.
Hope this atleast gives you some ideas