Html2pdf Css Stylesheet Html
How to place two tables side by side. You would separate the css from html, by putting a link elements in the head section, pointing at the css external files, having the style. The converter has full support for HTML tags, CSS and JavaScript and for advanced HTML5 features like CSS3, SVG and Web Fonts. EVO HTML to PDF Converter for Azure was developed for Azure Websites which have to run under a restricted environment. The general library for.NET can still be used directly in web roles and worker roles of Azure. Working with css floats in html2pdf. Ask Question 13. I'm using floats to position 2 divs beside each other. PDF is impossible to debug in relation to the HTML input; To be fair, this is not only the issue for HTML2PDF but also for the TCPDF that HTML2PDF uses. Document Ready. By enablind the document mode, the Froala WYSIWYG HTML Editor sets by default the best options for creating online documents. After editing the content, the print and export as PDF buttons are perfect so you to take the content and use it further just as you'd do with any Word processor such as Microsoft Word or Google Docs.
- Free Css Stylesheet Templates
- Basic Css Stylesheet
- Link Css Stylesheet Html
- Free Css Stylesheet Examples
Join GitHub today
GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.
Sign up<?php |
/** |
* @package dompdf |
* @link http://www.dompdf.com/ |
* @author Benj Carson <benjcarson@digitaljunkies.ca> |
* @author Helmut Tischer <htischer@weihenstephan.org> |
* @author Fabien Ménager <fabien.menager@gmail.com> |
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License |
* @version $Id: stylesheet.cls.php 461 2012-01-26 20:26:02Z fabien.menager $ |
*/ |
/** |
* The location of the default built-in CSS file. |
* {@link Stylesheet::DEFAULT_STYLESHEET} |
*/ |
define('__DEFAULT_STYLESHEET', DOMPDF_LIB_DIR.DIRECTORY_SEPARATOR.'res'.DIRECTORY_SEPARATOR.'html.css'); |
/** |
* The master stylesheet class |
* |
* The Stylesheet class is responsible for parsing stylesheets and style |
* tags/attributes. It also acts as a registry of the individual Style |
* objects generated by the current set of loaded CSS files and style |
* elements. |
* |
* @see Style |
* @package dompdf |
*/ |
classStylesheet { |
/** |
* The location of the default built-in CSS file. |
*/ |
constDEFAULT_STYLESHEET=__DEFAULT_STYLESHEET; |
/** |
* User agent stylesheet origin |
* @var int |
*/ |
constORIG_UA=1; |
/** |
* User normal stylesheet origin |
* @var int |
*/ |
constORIG_USER=2; |
/** |
* Author normal stylesheet origin |
* @var int |
*/ |
constORIG_AUTHOR=3; |
privatestatic$_stylesheet_origins=array( |
self::ORIG_UA=>-0x0FFFFFFF, // user agent style sheets |
self::ORIG_USER=>-0x0000FFFF, // user normal style sheets |
self::ORIG_AUTHOR=>0x00000000, // author normal style sheets |
); |
/** |
* Current dompdf instance |
* @var DOMPDF |
*/ |
private$_dompdf; |
/** |
* Array of currently defined styles |
* @var array |
*/ |
private$_styles; |
/** |
* Base protocol of the document being parsed |
* Used to handle relative urls. |
* @var string |
*/ |
private$_protocol; |
/** |
* Base hostname of the document being parsed |
* Used to handle relative urls. |
* @var string |
*/ |
private$_base_host; |
/** |
* Base path of the document being parsed |
* Used to handle relative urls. |
* @var string |
*/ |
private$_base_path; |
/** |
* The styles defined by @page rules |
* @var array<Style> |
*/ |
private$_page_styles; |
/** |
* List of loaded files, used to prevent recursion |
* @var array |
*/ |
private$_loaded_files; |
private$_current_origin=self::ORIG_UA; |
/** |
* Accepted CSS media types |
* List of types and parsing rules for future extensions: |
* http://www.w3.org/TR/REC-html40/types.html |
* screen, tty, tv, projection, handheld, print, braille, aural, all |
* The following are non standard extensions for undocumented specific environments. |
* static, visual, bitmap, paged, dompdf |
* Note, even though the generated pdf file is intended for print output, |
* the desired content might be different (e.g. screen or projection view of html file). |
* Therefore allow specification of content by dompdf setting DOMPDF_DEFAULT_MEDIA_TYPE. |
* If given, replace media 'print' by DOMPDF_DEFAULT_MEDIA_TYPE. |
* (Previous version $ACCEPTED_MEDIA_TYPES = $ACCEPTED_GENERIC_MEDIA_TYPES + $ACCEPTED_DEFAULT_MEDIA_TYPE) |
*/ |
static$ACCEPTED_DEFAULT_MEDIA_TYPE='print'; |
static$ACCEPTED_GENERIC_MEDIA_TYPES=array('all', 'static', 'visual', 'bitmap', 'paged', 'dompdf'); |
/** |
* The class constructor. |
* |
* The base protocol, host & path are initialized to those of |
* the current script. |
*/ |
function__construct(DOMPDF$dompdf) { |
$this->_dompdf=$dompdf; |
$this->_styles=array(); |
$this->_loaded_files=array(); |
list($this->_protocol, $this->_base_host, $this->_base_path) = explode_url($_SERVER['SCRIPT_FILENAME']); |
$this->_page_styles=array('base'=>null); |
} |
/** |
* Class destructor |
*/ |
function__destruct() { |
clear_object($this); |
} |
/** |
* Set the base protocol |
* |
* @param string $proto |
*/ |
functionset_protocol($proto) { $this->_protocol=$proto; } |
/** |
* Set the base host |
* |
* @param string $host |
*/ |
functionset_host($host) { $this->_base_host=$host; } |
/** |
* Set the base path |
* |
* @param string $path |
*/ |
functionset_base_path($path) { $this->_base_path=$path; } |
/** |
* Return the DOMPDF object |
* |
* @return DOMPDF |
*/ |
functionget_dompdf() { return$this->_dompdf; } |
/** |
* Return the base protocol for this stylesheet |
* |
* @return string |
*/ |
functionget_protocol() { return$this->_protocol; } |
/** |
* Return the base host for this stylesheet |
* |
* @return string |
*/ |
functionget_host() { return$this->_base_host; } |
/** |
* Return the base path for this stylesheet |
* |
* @return string |
*/ |
functionget_base_path() { return$this->_base_path; } |
/** |
* Return the array of page styles |
* |
* @return array<Style> |
*/ |
functionget_page_styles() { return$this->_page_styles; } |
/** |
* Add a new Style object to the stylesheet |
* |
* add_style() adds a new Style object to the current stylesheet, or |
* merges a new Style with an existing one. |
* |
* @param string $key the Style's selector |
* @param Style $style the Style to be added |
*/ |
functionadd_style($key, Style$style) { |
if (!is_string($key)) |
thrownewDOMPDF_Exception('CSS rule must be keyed by a string.'); |
if ( isset($this->_styles[$key]) ) |
$this->_styles[$key]->merge($style); |
else |
$this->_styles[$key] =clone$style; |
$this->_styles[$key]->set_origin( $this->_current_origin ); |
} |
/** |
* lookup a specifc Style object |
* |
* lookup() returns the Style specified by $key, or null if the Style is |
* not found. |
* |
* @param string $key the selector of the requested Style |
* @return Style |
*/ |
functionlookup($key) { |
if ( !isset($this->_styles[$key]) ) |
returnnull; |
return$this->_styles[$key]; |
} |
/** |
* create a new Style object associated with this stylesheet |
* |
* @param Style $parent The style of this style's parent in the DOM tree |
* @return Style |
*/ |
functioncreate_style(Style$parent=null) { |
returnnewStyle($this, $this->_current_origin); |
} |
/** |
* load and parse a CSS string |
* |
* @param string $css |
*/ |
functionload_css(&$css) { $this->_parse_css($css); } |
/** |
* load and parse a CSS file |
* |
* @param string $file |
*/ |
functionload_css_file($file, $origin=self::ORIG_AUTHOR) { |
global$_dompdf_warnings; |
if ( $origin ) { |
$this->_current_origin=$origin; |
} |
// Prevent circular references |
if ( isset($this->_loaded_files[$file]) ) |
return; |
$this->_loaded_files[$file] =true; |
$parsed_url= explode_url($file); |
list($this->_protocol, $this->_base_host, $this->_base_path, $filename) =$parsed_url; |
// Fix submitted by Nick Oostveen for aliased directory support: |
if ( $this->_protocol'' ) |
$file=$this->_base_path.$filename; |
else |
$file= build_url($this->_protocol, $this->_base_host, $this->_base_path, $filename); |
set_error_handler('record_warnings'); |
$css=file_get_contents($file, null, $this->_dompdf->get_http_context()); |
$good_mime_type=true; |
if ( !$this->_dompdf->get_quirksmode() ) { |
// See http://the-stickman.com/web-development/php/getting-http-response-headers-when-using-file_get_contents/ |
if ( isset($http_response_header) ) { |
foreach($http_response_headeras$_header) { |
if ( preg_match('@Content-Type:s*([w/]+)@i', $_header, $matches) ) { |
if ( $matches[1] !'text/css' ) { |
$good_mime_type=false; |
} |
} |
} |
} |
} |
restore_error_handler(); |
if ( !$good_mime_type$css'' ) { |
record_warnings(E_USER_WARNING, 'Unable to load css file $file', __FILE__, __LINE__); |
return; |
} |
$this->_parse_css($css); |
} |
/** |
* @link http://www.w3.org/TR/CSS21/cascade.html#specificity |
* |
* |
* |
* @param string $selector |
* @param string $origin : |
* - ua: user agent style sheets |
* - un: user normal style sheets |
* - an: author normal style sheets |
* - ai: author important style sheets |
* - ui: user important style sheets |
* |
* @return int |
*/ |
privatefunction_specificity($selector, $origin=self::ORIG_AUTHOR) { |
// http://www.w3.org/TR/CSS21/cascade.html#specificity |
// ignoring the ':' pseudoclass modifyers |
// also ignored in _css_selector_to_xpath |
$a= ($selector'!attr') ? 1 : 0; |
$b=min(mb_substr_count($selector, '#'), 255); |
$c=min(mb_substr_count($selector, '.') + |
mb_substr_count($selector, '['), 255); |
$d=min(mb_substr_count($selector, '') + |
mb_substr_count($selector, '>') + |
mb_substr_count($selector, '+'), 255); |
//If a normal element name is at the begining of the string, |
//a leading whitespace might have been removed on whitespace collapsing and removal |
//therefore there might be one whitespace less as selected element names |
//this can lead to a too small specificity |
//see _css_selector_to_xpath |
if ( !in_array($selector[0], array('', '>', '.', '#', '+', ':', '['))/* && $selector ! '*'*/) { |
$d++; |
} |
if (DEBUGCSS) { |
/*DEBUGCSS*/print'<pre>n'; |
/*DEBUGCSS*/printf('_specificity(): 0x%08x '%s'n', ($a<<24) ($b<<16) ($c<<8) ($d), $selector); |
/*DEBUGCSS*/print'</pre>'; |
} |
returnself::$_stylesheet_origins[$origin] + ($a<<24) ($b<<16) ($c<<8) ($d); |
} |
/** |
* converts a CSS selector to an XPath query. |
* |
* @param string $selector |
* @return string |
*/ |
privatefunction_css_selector_to_xpath($selector, $first_pass=false) { |
// Collapse white space and strip whitespace around delimiters |
// $search = array('/s+/', '/s+([.>#+:])s+/'); |
// $replace = array(' ', '1'); |
// $selector = preg_replace($search, $replace, trim($selector)); |
// Initial query (non-absolute) |
$query='//'; |
// Will contain :before and :after if they must be created |
$pseudo_elements=array(); |
// Parse the selector |
//$s = preg_split('/([ :>.#+])/', $selector, -1, PREG_SPLIT_DELIM_CAPTURE); |
$delimiters=array('', '>', '.', '#', '+', ':', '[', '('); |
// Add an implicit * at the beginning of the selector |
// if it begins with an attribute selector |
if ( $selector[0] '[' ) |
$selector='*$selector'; |
// Add an implicit space at the beginning of the selector if there is no |
// delimiter there already. |
if ( !in_array($selector[0], $delimiters) ) |
$selector='$selector'; |
$tok=''; |
$len=mb_strlen($selector); |
$i=0; |
while ( $i<$len ) { |
$s=$selector[$i]; |
$i++; |
// Eat characters up to the next delimiter |
$tok=''; |
$in_attr=false; |
while ($i<$len) { |
$c=$selector[$i]; |
$c_prev=$selector[$i-1]; |
if ( !$in_attr&&in_array($c, $delimiters) ) |
break; |
if ( $c_prev'[' ) { |
$in_attr=true; |
} |
$tok.=$selector[$i++]; |
} |
switch ($s) { |
case'': |
case'>': |
// All elements matching the next token that are direct children of |
// the current token |
$expr=$s'' ? 'descendant' : 'child'; |
if ( mb_substr($query, -1, 1) !'/' ) |
$query.='/'; |
// Tag names are case-insensitive |
$tok=strtolower($tok); |
if ( !$tok ) |
$tok='*'; |
$query.='$expr::$tok'; |
$tok=''; |
break; |
case'.': |
case'#': |
// All elements matching the current token with a class/id equal to |
// the _next_ token. |
$attr=$s'.' ? 'class' : 'id'; |
// empty class/id * |
if ( mb_substr($query, -1, 1) '/' ) |
$query.='*'; |
// Match multiple classes: $tok contains the current selected |
// class. Search for class attributes with, |
// and |
// This doesn't work because libxml only supports XPath 1.0.. |
//$query .= '[matches(@$attr,'^${tok}$ ^${tok}[ ]+ [ ]+${tok}$ [ ]+${tok}[ ]+')]'; |
// Query improvement by Michael Sheakoski <michael@mjsdigital.com>: |
$query.='[contains(concat(' ', @$attr, ' '), concat(' ', '$tok', ' '))]'; |
$tok=''; |
break; |
case'+': |
// All sibling elements that folow the current token |
if ( mb_substr($query, -1, 1) !'/' ) |
$query.='/'; |
$query.='following-sibling::$tok'; |
$tok=''; |
break; |
case':': |
$i2=$i-strlen($tok)-2; // the char before ':' |
if ( !isset($selector[$i2]) in_array($selector[$i2], $delimiters) ) { |
$query.='*'; |
} |
$last=false; |
// Pseudo-classes |
switch ($tok) { |
case'first-child': |
$query.='[1]'; |
$tok=''; |
break; |
case'last-child': |
$query.='[not(following-sibling::*)]'; |
$tok=''; |
break; |
case'first-of-type': |
$query.='[position() = 1]'; |
$tok=''; |
break; |
case'last-of-type': |
$query.='[position() = last()]'; |
$tok=''; |
break; |
// an+b, n, odd, and even |
case'nth-last-of-type': |
case'nth-last-child': |
$last=true; |
case'nth-of-type': |
case'nth-child': |
$p=$i+1; |
$nth=trim(mb_substr($selector, $p, strpos($selector, ')', $i)-$p)); |
$condition=''; |
// 1 |
if ( preg_match('/^d+$/', $nth) ) { |
$condition='position() = $nth'; |
} |
// odd |
elseif ( $nth'odd' ) { |
$condition='(position() mod 2) = 1'; |
} |
// even |
elseif ( $nth'even' ) { |
$condition='(position() mod 2) = 0'; |
} |
// an+b |
else { |
$condition=$this->_selector_an_plus_b($nth, $last); |
} |
$query.='[$condition]'; |
$tok=''; |
break; |
case'link': |
$query.='[@href]'; |
$tok=''; |
break; |
case'first-line': // TODO |
case'first-letter': // TODO |
// N/A |
case'active': |
case'hover': |
case'visited': |
$query.='[false()]'; |
$tok=''; |
break; |
/* Pseudo-elements */ |
case'before': |
case'after': |
if ( $first_pass ) |
$pseudo_elements[$tok] =$tok; |
else |
$query.='/*[@$tok]'; |
$tok=''; |
break; |
case'empty': |
$query.='[not(*) and not(normalize-space())]'; |
$tok=''; |
break; |
case'disabled': |
case'checked': |
$query.='[@$tok]'; |
$tok=''; |
break; |
case'enabled': |
$query.='[not(@disabled)]'; |
$tok=''; |
break; |
} |
break; |
case'[': |
// Attribute selectors. All with an attribute matching the following token(s) |
$attr_delimiters=array('=', ']', '~', '', '$', '^', '*'); |
$tok_len=mb_strlen($tok); |
$j=0; |
$attr=''; |
$op=''; |
$value=''; |
while ( $j<$tok_len ) { |
if ( in_array($tok[$j], $attr_delimiters) ) |
break; |
$attr.=$tok[$j++]; |
} |
switch ( $tok[$j] ) { |
case'~': |
case'': |
case'$': |
case'^': |
case'*': |
$op.=$tok[$j++]; |
if ( $tok[$j] !'=' ) |
thrownewDOMPDF_Exception('Invalid CSS selector syntax: invalid attribute selector: $selector'); |
$op.=$tok[$j]; |
break; |
case'=': |
$op='='; |
break; |
} |
// Read the attribute value, if required |
if ( $op!='' ) { |
$j++; |
while ( $j<$tok_len ) { |
if ( $tok[$j] ']' ) |
break; |
$value.=$tok[$j++]; |
} |
} |
if ( $attr'' ) |
thrownewDOMPDF_Exception('Invalid CSS selector syntax: missing attribute name'); |
$value=trim($value, ''''); |
switch ( $op ) { |
case'': |
$query.='[@$attr]'; |
break; |
case'=': |
$query.='[@$attr='$value']'; |
break; |
case'~=': |
// FIXME: this will break if $value contains quoted strings |
// (e.g. [type~='a b c' 'd e f']) |
$values=explode('', $value); |
$query.='['; |
foreach ( $valuesas$val ) |
$query.='@$attr='$val' or '; |
$query=rtrim($query, ' or ') .']'; |
break; |
case' =': |
$values=explode('-', $value); |
$query.='['; |
foreach ( $valuesas$val ) |
$query.='starts-with(@$attr, '$val') or '; |
$query=rtrim($query, ' or ') .']'; |
break; |
case'$=': |
$query.='[substring(@$attr, string-length(@$attr)-'.(strlen($value) -1).')='$value']'; |
break; |
case'^=': |
$query.='[starts-with(@$attr,'$value')]'; |
break; |
case'*=': |
$query.='[contains(@$attr,'$value')]'; |
break; |
} |
break; |
} |
} |
$i++; |
// case ':': |
// // Pseudo selectors: ignore for now. Partially handled directly |
// // below. |
// // Skip until the next special character, leaving the token as-is |
// while ( $i < $len ) { |
// if ( in_array($selector[$i], $delimiters) ) |
// break; |
// $i++; |
// } |
// break; |
// default: |
// // Add the character to the token |
// $tok .= $selector[$i++]; |
// break; |
// } |
// } |
// Trim the trailing '/' from the query |
if ( mb_strlen($query) >2 ) |
$query=rtrim($query, '/'); |
returnarray('query'=>$query, 'pseudo_elements'=>$pseudo_elements); |
} |
// https://github.com/tenderlove/nokogiri/blob/master/lib/nokogiri/css/xpath_visitor.rb |
protectedfunction_selector_an_plus_b($expr, $last=false) { |
$expr=preg_replace('/s/', '', $expr); |
if ( !preg_match('/^(?P<a>-?[0-9]*)?n(?P<b>[-+]?[0-9]+)?$/', $expr, $matches)) { |
return'false()'; |
} |
$a= ((isset($matches['a']) &&$matches['a'] !'') ? intval($matches['a']) : 1); |
$b= ((isset($matches['b']) &&$matches['b'] !'') ? intval($matches['b']) : 0); |
$position= ($last ? '(last()-position()+1)' : 'position()'); |
if ($b0) { |
return'($position mod $a) = 0'; |
} |
else { |
$compare= (($a<0) ? '<=' : '>='); |
$b2=-$b; |
if( $b2>=0 ) { |
$b2='+$b2'; |
} |
return'($position$compare$b) and ((($position$b2) mod '.abs($a).') = 0)'; |
} |
} |
/** |
* applies all current styles to a particular document tree |
* |
* apply_styles() applies all currently loaded styles to the provided |
* {@link Frame_Tree}. Aside from parsing CSS, this is the main purpose |
* of this class. |
* |
* @param Frame_Tree $tree |
*/ |
functionapply_styles(Frame_Tree$tree) { |
// Use XPath to select nodes. This would be easier if we could attach |
// Frame objects directly to DOMNodes using the setUserData() method, but |
// we can't do that just yet. Instead, we set a _node attribute_ in |
// Frame->set_id() and use that as a handle on the Frame object via |
// Frame_Tree::$_registry. |
// We create a scratch array of styles indexed by frame id. Once all |
// styles have been assigned, we order the cached styles by specificity |
// and create a final style object to assign to the frame. |
// FIXME: this is not particularly robust.. |
$styles=array(); |
$xp=newDOMXPath($tree->get_dom()); |
// Add generated content |
foreach ($this->_stylesas$selector=>$style) { |
if (strpos($selector, ':before') false&& |
strpos($selector, ':after') false) continue; |
$query=$this->_css_selector_to_xpath($selector, true); |
// Retrieve the nodes |
$nodes=@$xp->query($query['query']); |
if ($nodesnull) { |
record_warnings(E_USER_WARNING, 'The CSS selector '$selector' is not valid', __FILE__, __LINE__); |
continue; |
} |
foreach ($nodesas$i=>$node) { |
foreach ($query['pseudo_elements'] as$pos) { |
// Do not add a new pseudo element if another one already matched |
if ( $node->hasAttribute('dompdf_{$pos}_frame_id') ) { |
continue; |
} |
if (($src=$this->_image($style->content)) !'none') { |
$new_node=$node->ownerDocument->createElement('img_generated'); |
$new_node->setAttribute('src', $src); |
} |
else { |
$new_node=$node->ownerDocument->createElement('dompdf_generated'); |
} |
$new_node->setAttribute($pos, $pos); |
$new_frame_id=$tree->insert_node($node, $new_node, $pos); |
$node->setAttribute('dompdf_{$pos}_frame_id', $new_frame_id); |
} |
} |
} |
// Apply all styles in stylesheet |
foreach ($this->_stylesas$selector=>$style) { |
$query=$this->_css_selector_to_xpath($selector); |
// Retrieve the nodes |
$nodes=@$xp->query($query['query']); |
if ($nodesnull) { |
record_warnings(E_USER_WARNING, 'The CSS selector '$selector' is not valid', __FILE__, __LINE__); |
continue; |
} |
foreach ($nodesas$node) { |
// Retrieve the node id |
if ( $node->nodeType!=XML_ELEMENT_NODE ) // Only DOMElements get styles |
continue; |
$id=$node->getAttribute('frame_id'); |
// Assign the current style to the scratch array |
$spec=$this->_specificity($selector); |
$styles[$id][$spec][] =$style; |
} |
} |
// Now create the styles and assign them to the appropriate frames. (We |
// iterate over the tree using an implicit Frame_Tree iterator.) |
$root_flg=false; |
foreach ($tree->get_frames() as$frame) { |
// pre_r($frame->get_node()->nodeName . ':'); |
if ( !$root_flg&&$this->_page_styles['base'] ) { |
$style=$this->_page_styles['base']; |
$root_flg=true; |
} else |
$style=$this->create_style(); |
// Find nearest DOMElement parent |
$p=$frame; |
while ( $p=$p->get_parent() ) |
if ($p->get_node()->nodeTypeXML_ELEMENT_NODE ) |
break; |
// Styles can only be applied directly to DOMElements; anonymous |
// frames inherit from their parent |
if ( $frame->get_node()->nodeType!=XML_ELEMENT_NODE ) { |
if ( $p ) |
$style->inherit($p->get_style()); |
$frame->set_style($style); |
continue; |
} |
$id=$frame->get_id(); |
// Handle HTML 4.0 attributes |
Attribute_Translator::translate_attributes($frame); |
if ( ($str=$frame->get_node()->getAttribute(Attribute_Translator::$_style_attr)) !'' ) { |
// Lowest specificity |
$styles[$id][1][] =$this->_parse_properties($str); |
} |
// Locate any additional style attributes |
if ( ($str=$frame->get_node()->getAttribute('style')) !'' ) { |
// Destroy CSS comments |
$str=preg_replace(''/*.*?*/'si', '', $str); |
$spec=$this->_specificity('!attr'); |
$styles[$id][$spec][] =$this->_parse_properties($str); |
} |
// Grab the applicable styles |
if ( isset($styles[$id]) ) { |
$applied_styles=$styles[ $frame->get_id() ]; |
// Sort by specificity |
ksort($applied_styles); |
if (DEBUGCSS) { |
$debug_nodename=$frame->get_node()->nodeName; |
print'<pre>n[$debug_nodenamen'; |
foreach ($applied_stylesas$spec=>$arr) { |
printf('specificity: 0x%08xn',$spec); |
foreach ($arras$s) { |
print'[n'; |
$s->debug_print(); |
print']n'; |
} |
} |
} |
// Merge the new styles with the inherited styles |
foreach ($applied_stylesas$arr) { |
foreach ($arras$s) |
$style->merge($s); |
} |
} |
// Inherit parent's styles if required |
if ( $p ) { |
if (DEBUGCSS) { |
print'inherit:n'; |
print'[n'; |
$p->get_style()->debug_print(); |
print']n'; |
} |
$style->inherit( $p->get_style() ); |
} |
if (DEBUGCSS) { |
print'DomElementStyle:n'; |
print'[n'; |
$style->debug_print(); |
print']n'; |
print'/$debug_nodename]n</pre>'; |
} |
/*DEBUGCSS print: see below different print debugging method |
pre_r($frame->get_node()->nodeName . ':'); |
echo '<pre>'; |
echo $style; |
echo '</pre>';*/ |
$frame->set_style($style); |
} |
// We're done! Clean out the registry of all styles since we |
// won't be needing this later. |
foreach ( array_keys($this->_styles) as$key ) { |
$this->_styles[$key] =null; |
unset($this->_styles[$key]); |
} |
} |
/** |
* parse a CSS string using a regex parser |
* |
* Called by {@link Stylesheet::parse_css()} |
* |
* @param string $str |
*/ |
privatefunction_parse_css($str) { |
$str=trim($str); |
// Destroy comments and remove HTML comments |
$css=preg_replace(array( |
''/*.*?*/'si', |
'/^<!--/', |
'/-->$/' |
), '', $str); |
// FIXME: handle '{' within strings, e.g. [attr='string {}'] |
// Something more legible: |
$re= |
'/s* # Skip leading whitespace n'. |
'( @([^s]+)s+([^{;]*) (?:; ({)) )? # Match @rules followed by ';' or '{' n'. |
'(?(1) # Only parse sub-sections if we're in an @rule.. n'. |
' (?(4) # ..and if there was a leading '{' n'. |
' s*( (?:(?>[^{}]+) ({)? # Parse rulesets and individual @page rules n'. |
' (?(6) (?>[^}]*) }) s*)+? n'. |
' ) n'. |
' }) # Balancing '}' n'. |
' # Branch to match regular rules (not preceeded by '@')n'. |
'([^{]*{[^}]*})) # Parse normal rulesetsn'. |
'/xs'; |
if ( preg_match_all($re, $css, $matches, PREG_SET_ORDER) false ) |
// An error occured |
thrownewDOMPDF_Exception('Error parsing css file: preg_match_all() failed.'); |
// After matching, the array indicies are set as follows: |
// |
// [0] => complete text of match |
// [1] => contains '@import ..;' or '@media {' if applicable |
// [2] => text following @ for cases where [1] is set |
// [3] => media types or full text following '@import ..;' |
// [4] => '{', if present |
// [5] => rulesets within media rules |
// [6] => '{', within media rules |
// [7] => individual rules, outside of media rules |
// |
//pre_r($matches); |
foreach ( $matchesas$match ) { |
$match[2] =trim($match[2]); |
if ( $match[2] !'' ) { |
// Handle @rules |
switch ($match[2]) { |
case'import': |
$this->_parse_import($match[3]); |
break; |
case'media': |
$acceptedmedia=self::$ACCEPTED_GENERIC_MEDIA_TYPES; |
if ( defined('DOMPDF_DEFAULT_MEDIA_TYPE') ) { |
$acceptedmedia[] =DOMPDF_DEFAULT_MEDIA_TYPE; |
} |
else { |
$acceptedmedia[] =self::$ACCEPTED_DEFAULT_MEDIA_TYPE; |
} |
$media=preg_split('/s*,s*/', mb_strtolower(trim($match[3]))); |
if ( count(array_intersect($acceptedmedia, $media)) ) { |
$this->_parse_sections($match[5]); |
} |
break; |
case'page': |
//This handles @page to be applied to page oriented media |
//Note: This has a reduced syntax: |
//@page { margin:1cm; color:blue; } |
//Not a sequence of styles like a full.css, but only the properties |
//of a single style, which is applied to the very first 'root' frame before |
//processing other styles of the frame. |
//Working properties: |
// margin (for margin around edge of paper) |
// font-family (default font of pages) |
// color (default text color of pages) |
//Non working properties: |
// border |
// padding |
// background-color |
//Todo:Reason is unknown |
//Other properties (like further font or border attributes) not tested. |
//If a border or background color around each paper sheet is desired, |
//assign it to the <body> tag, possibly only for the css of the correct media type. |
// If the page has a name, skip the style. |
$page_selector=trim($match[3]); |
switch($page_selector) { |
case'': |
$key='base'; |
break; |
case':left': |
case':right': |
case':odd': |
case':even': |
case':first': |
$key=$page_selector; |
default: continue; |
} |
// Store the style for later.. |
if ( empty($this->_page_styles[$key]) ) |
$this->_page_styles[$key] =$this->_parse_properties($match[5]); |
else |
$this->_page_styles[$key]->merge($this->_parse_properties($match[5])); |
break; |
case'font-face': |
$this->_parse_font_face($match[5]); |
break; |
default: |
// ignore everything else |
break; |
} |
continue; |
} |
if ( $match[7] !'' ) |
$this->_parse_sections($match[7]); |
} |
} |
/* See also style.cls Style::_image(), refactoring?, works also for imported css files */ |
protectedfunction_image($val) { |
$DEBUGCSS=DEBUGCSS; |
if ( mb_strpos($val, 'url') false ) { |
$path='none'; //Don't resolve no image -> otherwise would prefix path and no longer recognize as none |
} |
else { |
$val=preg_replace('/url(['']?([^'')]+)['']?)/','1', trim($val)); |
// Resolve the url now in the context of the current stylesheet |
$parsed_url= explode_url($val); |
if ( $parsed_url['protocol'] ''&&$this->get_protocol() '' ) { |
if ($parsed_url['path'][0] '/'$parsed_url['path'][0] '' ) { |
$path=$_SERVER['DOCUMENT_ROOT'].'/'; |
} else { |
$path=$this->get_base_path(); |
} |
$path.=$parsed_url['path'] .$parsed_url['file']; |
$path=realpath($path); |
// If realpath returns FALSE then specifically state that there is no background image |
// FIXME: Is this causing problems for imported CSS files? There are some './none' references when running the test cases. |
if (!$path) { $path='none'; } |
} else { |
$path= build_url($this->get_protocol(), |
$this->get_host(), |
$this->get_base_path(), |
$val); |
} |
} |
if ($DEBUGCSS) { |
print'<pre>[_imagen'; |
print_r($parsed_url); |
print$this->get_protocol().'n'.$this->get_base_path().'n'.$path.'n'; |
print'_image]</pre>';; |
} |
return$path; |
} |
/** |
* parse @import{} sections |
* |
* @param string $url the url of the imported CSS file |
*/ |
privatefunction_parse_import($url) { |
$arr=preg_split('/[sn,]/', $url,-1, PREG_SPLIT_NO_EMPTY); |
$url=array_shift($arr); |
$accept=false; |
if ( count($arr) >0 ) { |
$acceptedmedia=self::$ACCEPTED_GENERIC_MEDIA_TYPES; |
if ( defined('DOMPDF_DEFAULT_MEDIA_TYPE') ) { |
$acceptedmedia[] =DOMPDF_DEFAULT_MEDIA_TYPE; |
} else { |
$acceptedmedia[] =self::$ACCEPTED_DEFAULT_MEDIA_TYPE; |
} |
// @import url media_type [media_type..] |
foreach ( $arras$type ) { |
if ( in_array(mb_strtolower(trim($type)), $acceptedmedia) ) { |
$accept=true; |
break; |
} |
} |
} else { |
// unconditional import |
$accept=true; |
} |
if ( $accept ) { |
// Store our current base url properties in case the new url is elsewhere |
$protocol=$this->_protocol; |
$host=$this->_base_host; |
$path=$this->_base_path; |
// $url = str_replace(array('','url', '(', ')'), ', $url); |
// If the protocol is php, assume that we will import using file:// |
// $url = build_url($protocol 'php://' ? 'file://' : $protocol, $host, $path, $url); |
// Above does not work for subfolders and absolute urls. |
// Todo: As above, do we need to replace php or file to an empty protocol for local files? |
$url=$this->_image($url); |
$this->load_css_file($url); |
// Restore the current base url |
$this->_protocol=$protocol; |
$this->_base_host=$host; |
$this->_base_path=$path; |
} |
} |
/** |
* parse @font-face{} sections |
* http://www.w3.org/TR/css3-fonts/#the-font-face-rule |
* |
* @param string $str CSS @font-face rules |
* @return Style |
*/ |
privatefunction_parse_font_face($str) { |
$descriptors=$this->_parse_properties($str); |
preg_match_all('/(url local)s*(['']?([^'')]+)['']?)s*(formats*(['']?([^'')]+)['']?))?/i', $descriptors->src, $src); |
$sources=array(); |
$valid_sources=array(); |
foreach($src[0] as$i=>$value) { |
$source=array( |
'local'=>strtolower($src[1][$i]) 'local', |
'uri'=>$src[2][$i], |
'format'=>$src[4][$i], |
'path'=> build_url($this->_protocol, $this->_base_host, $this->_base_path, $src[2][$i]), |
); |
if ( !$source['local'] &&in_array($source['format'], array('', 'woff', 'opentype', 'truetype')) ) { |
$valid_sources[] =$source; |
} |
$sources[] =$source; |
} |
// No valid sources |
if ( empty($valid_sources) ) { |
return; |
} |
$style=array( |
'family'=>$descriptors->get_font_family_raw(), |
'weight'=>$descriptors->font_weight, |
'style'=>$descriptors->font_style, |
); |
Font_Metrics::register_font($style, $valid_sources[0]['path']); |
} |
/** |
* parse regular CSS blocks |
* |
* _parse_properties() creates a new Style object based on the provided |
* CSS rules. |
* |
* @param string $str CSS rules |
* @return Style |
*/ |
privatefunction_parse_properties($str) { |
$properties=preg_split('/;(?=(?:[^(]*([^)]*))*(?![^)]*)))/', $str); |
if (DEBUGCSS) print'[_parse_properties'; |
// Create the style |
$style=newStyle($this); |
foreach ($propertiesas$prop) { |
// If the $prop contains an url, the regex may be wrong |
// @todo: fix the regex so that it works everytime |
/*if (strpos($prop, 'url(') false) { |
if (preg_match('/([a-z-]+)s*:s*[^:]+$/i', $prop, $m)) |
$prop = $m[0]; |
}*/ |
//A css property can have ' ! important' appended (whitespace optional) |
//strip this off to decode core of the property correctly. |
//Pass on in the style to allow proper handling: |
//!important properties can only be overridden by other !important ones. |
//$style->$prop_name = is a shortcut of $style->__set($prop_name,$value);. |
//If no specific set function available, set _props['prop_name'] |
//style is always copied completely, or $_props handled separately |
//Therefore set a _important_props['prop_name']=true to indicate the modifier |
/* Instead of short code, prefer the typical case with fast code |
$important = preg_match('/(.*?)!s*important/',$prop,$match); |
if ( $important ) { |
$prop = $match[1]; |
} |
$prop = trim($prop); |
*/ |
if (DEBUGCSS) print'('; |
$important=false; |
$prop=trim($prop); |
if ( substr($prop, -9) 'important' ) { |
$prop_tmp=rtrim(substr($prop, 0, -9)); |
if ( substr($prop_tmp, -1) '!' ) { |
$prop=rtrim(substr($prop_tmp, 0, -1)); |
$important=true; |
} |
} |
if ( $prop'' ) { |
if (DEBUGCSS) print'empty)'; |
continue; |
} |
$i=mb_strpos($prop, ':'); |
if ( $ifalse ) { |
if (DEBUGCSS) print'novalue'.$prop.')'; |
continue; |
} |
$prop_name=rtrim(mb_strtolower(mb_substr($prop, 0, $i))); |
$value=ltrim(mb_substr($prop, $i+1)); |
if (DEBUGCSS) print$prop_name.':='.$value.($important?'!IMPORTANT':'').')'; |
//New style, anyway empty |
//if ($important !$style->important_get($prop_name) ) { |
//$style->$prop_name = array($value,$important); |
//assignment might be replaced by overloading through __set, |
//and overloaded functions might check _important_props, |
//therefore set _important_props first. |
if ($important) { |
$style->important_set($prop_name); |
} |
//For easier debugging, don't use overloading of assignments with __set |
$style->$prop_name=$value; |
//$style->props_set($prop_name, $value); |
} |
if (DEBUGCSS) print'_parse_properties]'; |
return$style; |
} |
/** |
* parse selector + rulesets |
* |
* @param string $str CSS selectors and rulesets |
*/ |
privatefunction_parse_sections($str) { |
// Pre-process: collapse all whitespace and strip whitespace around '>', |
// '.', ':', '+', '#' |
$patterns=array('/[sn]+/', '/s+([>.:+#])s+/'); |
$replacements=array('', '1'); |
$str=preg_replace($patterns, $replacements, $str); |
$sections=explode('}', $str); |
if (DEBUGCSS) print'[_parse_sections'; |
foreach ($sectionsas$sect) { |
$i=mb_strpos($sect, '{'); |
$selectors=explode(',', mb_substr($sect, 0, $i)); |
if (DEBUGCSS) print'[section'; |
$style=$this->_parse_properties(trim(mb_substr($sect, $i+1))); |
// Assign it to the selected elements |
foreach ($selectorsas$selector) { |
$selector=trim($selector); |
if ($selector'') { |
if (DEBUGCSS) print'#empty#'; |
continue; |
} |
if (DEBUGCSS) print'#'.$selector.'#'; |
//if (DEBUGCSS) { if (strpos($selector,'p') ! false) print '!!!p!!!#'; } |
$this->add_style($selector, $style); |
} |
if (DEBUGCSS) print'section]'; |
} |
if (DEBUGCSS) print'_parse_sections]'; |
} |
/** |
* dumps the entire stylesheet as a string |
* |
* Generates a string of each selector and associated style in the |
* Stylesheet. Useful for debugging. |
* |
* @return string |
*/ |
function__toString() { |
$str=''; |
foreach ($this->_stylesas$selector=>$style) |
$str.='$selector => '.$style->__toString() .'n'; |
return$str; |
} |
} |
Copy lines Copy permalink
The pages I want to convert are generated dynamically via PHP from a MySQL database. In other words the information on a page depends on the Id of the chosen object. So I would normally have a URL like this
I am using html2pdf
and so far I am unable to perform the conversion. When I pass id=2
directly like this
I get these errors:
Warning: include(renal_prescRequest_review.php?id=2) [function.include ]: failed to open stream: No such file or directory in/home/renalmed/public_html/testing/test/renal_prescRequest_pdf.php on line5
Warning: include(renal_prescRequest_review.php?id=2) [function.include]: failed to open stream: No such file or directory in /home/renalmed/public_html/testing/test/renal_prescRequest_pdf.php on line5
Warning: include() [function.include]: Failed opening 'renal_prescRequest_review.php?id=2' for inclusion(include_path='.:/usr/lib/php:/usr/local/lib/php') in/home/renalme/public_html/testing/test/renal_prescRequest_pdf.php on line5.
The fascinating thing is that these errors are thrown on the PDF document where the actual HTML is supposed to be displayed. I have been on this for quite a while now. Please help.
Chris LeyvaFree Css Stylesheet Templates
Damilare Binutu5 Answers
You can't include a query string on the include file.
Dec 16, 2018 WWE TLC 2018 Match Card And How To Watch The PPV. (Triple Threat TLC Match For The Smackdown Women's Championship) Ronda Rousey (c) vs. Nia Jax (Raw Women's Championship).
One solution on this is to transfer the codes of renal_prescRequest_review.php in the file where you want to convert html to pdf.
Below is the sample code.
I'm not sure you can use get variables in include. Use an url with file_get_contents function. Or remove the get variable id and assign it before the include, detect it with an isset within the included script.
Basic Css Stylesheet
You can't include files like that. You're specifying a query string within the include statement, where PHP is simply expecting a path. So PHP is expecting to find a file called renal_prescRequest_review.php?id=2
(in other words, it's not looking for renal_prescRequest_review.php
). Your PHP should look like
You can use session on this and remove the query string on the include file
In the renal_clinicalTrial_review.php, put session_start();and you can use now the session.
Uloz.to is the largest czech cloud storage. Upload, share, search and download for free. Credit allows you to download with unlimited speed. Download free new release mp3 Pinkish Black Razed To The Ground 2013 from zippyshare, uploaded, torrent. Download vision of disorder razed to the ground files found Uploaded on TraDownload and all major free file sharing websites like 4shared.com, uploaded.to, mediafire.com and many others. The earliest example that I can find of the precise 'raze to the ground' form is in The Glory of England. Which afterward the Genouais razed to the ground.' If you invite your neighbours to a barn raising, you had better get the spelling right, or the consequences might be unfortunate. See also, 'beck and call'. Get the embed code Pinkish Black - Razed to the Ground Album Lyrics1.She Left Him Red Lyrics2.Ashtray Eyes Lyrics3.Kites and Vultures Lyrics4.Razed to the Ground Lyrics5.Bad Dreamer Lyrics6.Rise Lyrics7.Loss of Feeling of Loss LyricsPinkish Black Lyrics provided by SongLyrics.com Note: When you embed the widget in your site, it will match your site's styles (CSS). Las vegas hotel razed to the ground.
You can not include the file like this :
Link Css Stylesheet Html
You should do it like this :
The parameter is then passed to the calling page.
For example, if your code is saved as test.php
, then call it like this: