JFIF       %%-))-969KKd       %%-))-969KKd! f%eK_.T  v_/n6q>e}&Cx@t7OuqySN%y%tz@ Un(quo{tS]\~LzǚPk;fϛϹ2y-=_z.NWW7DW@'4`3w3rr;hP8B%ַBe]`7Ҽo1e)弆O|4Wk*}7Su[9=U 9 |_+:@}@˵u@ g<4N<@=/ I(~}qq=y- u|. y'`3S+4$e= k4P]M^_Nou*R-,X0EI}m&LtVȱa|R\@ ʟ+YeIlY`XV^HV/c-eb du ̈́_2+DpV ` ^^->t7JydE]I 8:7#j̀iiVbp~o݃[}zwGF@-(RTJY@ Ty}X 1!2AQaq"3BR`r@PSb #4CTs0DU$EFcd?Lc4\K#E1$@CV8OƂZ5g;.141;%]6e laǃpv8)80D1ŌxLgWYc+z%:( w^PtdԣV Z:qDsh W) ͷ+~FO]"բ?eN 4)WREZ;T+}]:FRtI ѱއ>'s_[\qNhK ' ^qJv9 ]ʜ1FMzwF8ѯBIp-g`?si;|Hr%>jOh29-+-gQmBH?3P9e')>[k^OaxtLiS30ҿ6*o--I$ 1 z2+OЪ+i˺,_n3(~}StUMc \xSmGD0jMB06%') #1c6s/iaIɉgC%Yoi**MHЛ=rh ĭ總 E>Jў2+ct/^$[_kAOʕicR4qm#Lw!Squ/:e%~zMBfa|e7PUC|"/)CD\cy gڰF9(?\jU+>Cwl#>x^'a7C}LYX<@X`W8P hۂx͍q֜?de1qe* NDuTm-ߣ y+pUy*9aĺ:P4n$2&BTϵ@ a>v3uc,(uF0jˊ́a~32f2=ήZe[r!F !Bu)b FŌt%41N/֑41n1|> 1^;1=IĖEpq%"{/~M.QWDdUA6~z>kPh2Oi?Uc[`+l;՚':۾ږtoZjQ7\:Z3}~ &ڮRQH{mDq0TaM5i:5sC0x<]=Mp c!C<6]~vpxeH[AmY'iԖ_~ a(Ȕ@+a< w] wbk1#aD 9. ?p$ Qؒi-8S㨸f45t:ʙѾ.{mMshU1k\z^*#It@ v:%#iSZ.{.Vemm,Z3*;HtU8E.v'e ޴ 4WwLDe)jY*R'?wM֣ b+IfO('Y J$o޼ l.蕁~ Y Em>Y^m"r^4w}2PI7R1gV\wtVT׿w'*N{ZGN8qzrM/LO~ O~|ڞ櫮o{\dV斀AJmn E#HQg$!{XM'{u* 4O)>F.";l2z3IJ2?Fh7)rjrv@ AJlУ 0`StpGD&nƒpxΡ}P늿D@cEH҆2[9a}U/biEzu)xYR>߹q (yA~ُp \U\L\6~" U'>GJOP,ko:JGI*٢C8f8굟m#GV̐Cj]}N_]aJulE.+I&y5 6*TGHZRů}efjv"\3/3_hq՝g !ir,ܐv%~*lXccyo) 拏Qp_tT3!,Dur!CH7;9GQQmE:ÑCaƅ;zeij;d+% z#e%gdI9E5BB&۟S"=C(>{֠ ɫNUळiu>;P}حW]ouBmJS0ktRtDm+$ԫU_dq)$ ʃnLGSፑf'vlzP/_]QԂ]ȗ|W\;wTSf!m,ri{w了enP(`*.1i2.}e@;HA&_N᷸1|:Gjڒj~i/֬]1(N +^ bQq:›m*o5Y(.JPV[3ޭj֭j+i(uָ]kV)A/%X Fa?8'o>ꝣKks\_k)S%zDTRw#h#e#1Euk&,Yw+Ap"PIZ*j*Ug">m>|ڇ(#FXzCi9%J'H3Xwi-9s0S`R^֮ YLJz+q^i}i1jLK+ [ NzDSq[+Q'ݖl=s<[iIWz=%}[jɁ֠$$N7IUm83SVŭw)#0$g C26^ʓW<=B>{R)&繻8j3cbbce7TE1r\'}FūLO+KʢXm/=H 6FaRHI^Lȹ83g9CM93쑑nE)=q4I$s'ݠajm]"O>L4Vb;(eHm$֫ӆyYtYYr(<Ɠ2Fm "f֒;Tξu8jZR$b!E*9 yy+V:Dm Œ9@-f*l2#ٿPt#T҂ӵ&;AȃWlf xϜZكfj%bs ,/uN{,Gz*kkP M6f/0[I;S)ml-؉)~q9v`ǣ4gZJ}h&dﺥ#{}uDa7j(I'2OҒMF7 .Ey<$5;2ժTI %)TwG54Ŭ Kb6rG;uq\[8DJ'i$?Pq-ݗs\JGkYO2%}b\9;Tk⾜3%qSd( [O4i'jQՃ &F Ҧ T2!G{N j~:Cz J3|xd(6TZ a b5gfK\I)WYARA(RVE$G8at̖qWq{B:Q^g3QzcAZrH|GMcjb{+)r=>:de:¹[QOe@>ISP1nIq!:3G).!ŶB꠲#0Eb2"Lt4ƺKCGn9P=PeoX8@fղ Gi9k ^aHAV<)GG*k_aUΜWsX4ʷ\%m,W*F}<1E/&NJIʳ:PmeRuń%A<ᶧ2s^s-9$PHw]ZB#[>9Fm*>Ut.HugK9uaAF.%fW&J~$k^S:iގT9_5`_bR`ܒ(8Fa?jMc4Pŭ!VB7 W+߀ i>b٠,]?<{aXgpJ]璹نrV53-)p:,R%>#W۲4K{%L%]ͅP,7"[NI:ܴ- AJr)#"=k#Eoa PP$C>7m_t ڠcJZymA [qwDw|*3(FMۭ\KP-'1WK, suu;~ZaTnyi$A =46i֑AUU"l:gA ]"8&ד<{z&O!WF^XGhViWM\q(*p#Fk?p\Ym*J3B3'%jn+ IG{VcVL-f7 #/u}5bD7XMi!{#b$U]q\RGa ;OZXv^WZ\ܭ( lhSˎ6 V'h GY{49$r8AIȃ#V$HL/~l.]:>29:EkSO%N$Ϋkͯ⫝̸yˮ0mE+IVwuIu>Xj%6@[k)aqJz|؏!Υ֔RP.l@tⵅkZg'5nrqDU^kJBEBfrG)+J$"dB3#ٔk4yQCz9S\8'#/5cˑYO(4dhIM<6BߢJNDZFEgD6vnl|^kr;^hϨ1!ʌ:įZBᝋx|T+'!c t"YH=)"g6-t+.Ur$+ZzRG s*f9_QY4El>DI[}B=>v)iTg[?oWwۿlWG69k{Qx]-*$<-=W¹nUĂ}G4tZ]^Q8m!])SyR)vOR(_Aiϵei#{$hਧ.SLN}߬e}EgZwgAWPBcZÖ']P ;2/hy}1M9Fj'.ӖZy-,r ND|jlC)jqSʚV)]p3;❀[:tBH##HqhZr\j"tG-тtHtB24PJ:w;xI0$ wEQ#)FejK rSw|">Tҙ#2Xc8g,(L`S2 tM>5@<)A71iXSlHڛ9(y4KUu:xARdf5\Zq|m{ӭjI8%. ڟ5pxvqd(9P$#"8CQ NKFۘ;RTPE8^`WãRxL髍{}ġͭ緗Ҍ/<xcKOVy0\{Uk85A07)_uCuopN>~3e e޽ytYnDm3)ܠ&,![y3CcؽK+raޱX~aRbm<wE #+ԺQXfGq+h[71_A* [V٣sCEXb\fNiXNݔz NҲ wrG"+ kлYI`ϼUՄ o9Vc7^[Y"E]W>(GSkt]Gcx~hM`?WV8q w< `bJb̑ NNG[xr̈>Kþ7<7H56pIEKgoE`?4e)ޛ)7M(-4ot}LDG6"qycg~x{>8.,7W_ɦ/nG|MFU^VYpa",BBBH;GC#2JerK*ZIqbIphت݉)c繥ՅVtLnEcf62:;\Rw@{ S5Q $ϑTz;EzFO5Pn.NA<~ҌoXR|Ig$^]A|^_mmҷj8mbMbՅHmvI_MqƊFCq&Б%z>ΧKEAg4y;/0f[|@$SG,h5@0RȁцEH-qm%Kb%Dx:0XNHWIᰵ$G)|^ χ,m,#%6צIpO FDFUH5JKlI>Vxn;ĶY;dZkarnƭaeG< W#9+؄l?jEmDo<~W++0#π*<.ۘZ+H$VfF|J&#N ?*<<⢌՞\.#I: !#Sh-4'F |-[WQFH7 )d`JFCbFɞ9N9vՅW4xPOBHc2a"*90Iv5IGI<hI I*'Ƿ.-m1ȼѹKF2ٷ;*A*T6FDSKsipI tGx f$9 Ǐzf{kd@r:/?(i^b 3)_g;&IEWu̓*2t7qL Ti5, wdXr&Gwmŏy)IJD+iE:v6[=9ʰ;q` =}#q:<>~mFU631TqQ (t2/c~ iK'y˴TlxsF_$ {a8[yfc>Y͘k8&9x\Նڻ{I&7+ fv F=,ꌼcCA[c:麑î6B겦&|mFm㪈Rfw .xJês1?_UnuQGǪ?6wR5b-:q{wK  !1A2Qq"@PRa #03BCSbr4$T`c?K)o<rzѸUL<6K4F̘E¹?Q7 QZtʄSV9iE$m6vU>8_F!zaS# j_4Jzm_bȚ;/:Iq7A9Qڜp͖!QTaOSTQzqS5U{LHOWc;TWUA}YWqUNKURѾĴ:gfYnQ*dv?F6i1G6[H?W*!Wl 8OlE?U$jv<&Rا@TG"X޺51?Ikymc{TLʧA4Y+#a=[#j Ge;@֍Xًv_(uVgJjbէz;5$۱ʡ)zv|eS u̎b{ean<6\;CQ<@΍b{ZM%[*n,z{EZR++e`w޹bh9cWF2ǴU:RMWd架;UJcDtK_G@y5GāYzF 8cWb㖈qw4ecqMis,)',o=ߘq5e-0j.}xNGq?d;D5T Dbng2!zN%i`IJ4]JN Kv ./iLZFOii h=yn%wdԲ:d뉆2 ]|1jnvBV@XkxN_;J Kӯ$ΟVlXm x[0'id =qcamjdӚȹaE4rY26!۩PS#U v{-51~q<'x;Z *'Fg"pojg9l:5W媴txyyUU%`_58Mngv[+jz>XwbIt$]ɞ*{ &b^F=C4ЏZ+ F\pR]9c1b * @@K,\ϔ =0<9N{U^ozﺊ<˒D4p2 ,Ƿ˗:#]j*&*jFTܪTdF@x8׭CX2U&y({9b駴to90\DUaaƏ@J:tš#x]d0pUiJ!Џ_1Ke9s$\t%ZiW-]ZVp[!c8OڋGPmM 'ÈX$I"s)Ȍ[ڦT ׫wJsn$QӨ]dJ[;~ԕ$lŧt}7RU@&778ܷK "$4C^iQ􄆺h(Cg#P QҤ1 7~V=6~8:#7/N5qz=8ȂiEʀJpnx8.9@~1m3sE? :zqGY}:O#yw23$1%m}8`E毑s_PznQ[LF%D;S)י -YW < quTݪҒl>I£$qG,Ȑf=g + `~}m5dO+ipyOfv]ishu*8tx"4n7putfV]D`i=ZHWIwȩ<[.P\xӊF)jbKfzASi{*u#8 9p뚰 H@ff>,`2 L6b8 mw{Hn3|b3Fg1e6C<eH /_~B#L *t0xbS% 웞: Aɔ89hjd[OY墪9sŎzNZ:&Yiu%MGw=Y ]QӍ -u@'p[wK%suԘse^wbiɫ:f䲯4ֶCP JFE32 X;yVeAbFyyX%H ,vgb~Ksʊ&V φ 5f̅2K7ZVԎBLǑ=zv-yq,nȇ'(:8$(rH*!S RI.Lj"9\W>])|›\o?-tEs#678PI:e5n$i0ScudA F(ET lq{讬3 28xۆ1IPԲ v0r$0{[J*cyA 1OQ-3f5;׆!`;mV[g{*d$221VR8jk.aH)7c=BO>~ T77XӇʧ _NاVV:Gye)NKk Ǵ`ՏS=Wy\cu`}@8C2su XqC Պ̜xEU ڭ{$KόI@F؛NLOA$F[X2rĔG L\wE2J3S8IJ2e`A7),b +noĐ<{XA"Lj%W̮RI7=e0O {F 3t6ǽN7aNHmo!_5G/GGz`ǻwl${wzd2X,!a/@X{wh]S MARIJUANA
— DIOS — NO — CREA — NADA — EN — VANO —
Linux vps-ed8565de 5.10.0-37-cloud-amd64 #1 SMP Debian 5.10.247-1 (2025-12-11) x86_64
  SOFT : Apache/2.4.65 (Debian) PHP : 7.4.33
/var/www/mdau-prod/html2pdf/_class/
51.178.36.14

 
[ NAME ] [ SIZE ] [ PERM ] [ DATE ] [ ACT ]
+FILE +DIR
exception.class.php 4.709 KB -rw-r--r-- 2022-04-21 16:06 R E G D
locale.class.php 2.237 KB -rw-r--r-- 2022-04-21 16:06 R E G D
myPdf.class.php 42.949 KB -rw-r--r-- 2022-04-21 16:06 R E G D
parsingCss.class.php 62.904 KB -rw-r--r-- 2022-04-21 16:06 R E G D
parsingHtml.class.php 17.303 KB -rw-r--r-- 2022-04-21 16:06 R E G D
tcpdfConfig.php 6.202 KB -rw-r--r-- 2022-04-21 16:06 R E G D
REQUEST EXIT
©TheAlmightyZeus
PDF convertor * distributed under the LGPL License * * @author Laurent MINGUET * @version 4.03 */ class HTML2PDF_parsingHtml { protected $_html = ''; // HTML code to parse protected $_num = 0; // table number protected $_level = 0; // table level protected $_encoding = ''; // encoding public $code = array(); // parsed HTML codfe const HTML_TAB = ' '; /** * main constructor * * @param string encoding * @access public */ public function __construct($encoding = 'UTF-8') { $this->_num = 0; $this->_level = array($this->_num); $this->_html = ''; $this->code = array(); $this->setEncoding($encoding); } /** * change the encoding * * @param string encoding * @access public */ public function setEncoding($encoding) { $this->_encoding = $encoding; } /** * Define the HTML code to parse * * @param string HTML code * @access public */ public function setHTML($html) { // remove the HTML in comment $html = preg_replace('//isU', '', $html); // save the HTML code $this->_html = $html; } /** * parse the HTML code * * @access public */ public function parse() { $parents = array(); // flag : are we in a
 Tag ?
        $tagPreIn = false;

        // action to use for each line of the content of a 
 Tag
        $tagPreBr = array(
                    'name' => 'br',
                    'close' => false,
                    'param' => array(
                        'style' => array(),
                        'num'    => 0
                    )
                );

        // tag that can be not closed
        $tagsNotClosed = array(
            'br', 'hr', 'img', 'col',
            'input', 'link', 'option',
            'circle', 'ellipse', 'path', 'rect', 'line', 'polygon', 'polyline'
        );

        // search the HTML tags
        $tmp = array();
        $this->_searchCode($tmp);

        // all the actions to do
        $actions = array();

        // foreach part of the HTML code
        foreach ($tmp as $part) {
            // if it is a tag code
            if ($part[0]=='code') {
                // analise the HTML code
                $res = $this->_analiseCode($part[1]);

                // if it is a real HTML tag
                if ($res) {
                    // save the current posistion in the HTML code
                    $res['html_pos'] = $part[2];

                    // if the tag must be closed
                    if (!in_array($res['name'], $tagsNotClosed)) {
                        // if it is a closure tag
                        if ($res['close']) {
                            // HTML validation
                            if (count($parents)<1)
                                throw new HTML2PDF_exception(3, $res['name'], $this->getHtmlErrorCode($res['html_pos']));
                            else if ($parents[count($parents)-1]!=$res['name'])
                                throw new HTML2PDF_exception(4, $parents, $this->getHtmlErrorCode($res['html_pos']));
                            else
                                unset($parents[count($parents)-1]);
                        } else {
                            // if it is a autoclosed tag
                            if ($res['autoclose']) {
                                // save the opened tag
                                $actions[] = $res;

                                // prepare the closed tag
                                $res['params'] = array();
                                $res['close'] = true;
                            }
                            // else :add a child for validation
                            else
                                $parents[count($parents)] = $res['name'];
                        }

                        // if it is a 
 tag (or  tag) not auclosed => update the flag
                        if (($res['name']=='pre' || $res['name']=='code') && !$res['autoclose']) {
                            $tagPreIn = !$res['close'];
                        }
                    }

                    // save the actions to convert
                    $actions[] = $res;
                } else { // else (it is not a real HTML tag => we transform it in Texte
                    $part[0]='txt';
                }
            }
            // if it is text
            if ($part[0]=='txt') {
                // if we are not in a 
 tag
                if (!$tagPreIn) {
                    // save the action
                    $actions[] = array(
                        'name'    => 'write',
                        'close'    => false,
                        'param' => array('txt' => $this->_prepareTxt($part[1])),
                    );
                } else { // else (if we are in a 
 tag)
                    // prepare the text
                    $part[1] = str_replace("\r", '', $part[1]);
                    $part[1] = explode("\n", $part[1]);

                    // foreach line of the text
                    foreach ($part[1] as $k => $txt) {
                        // transform the line
                        $txt = str_replace("\t", self::HTML_TAB, $txt);
                        $txt = str_replace(' ', ' ', $txt);

                        // add a break line
                        if ($k>0) $actions[] = $tagPreBr;

                        // save the action
                        $actions[] = array(
                            'name'    => 'write',
                            'close'    => false,
                            'param' => array('txt' => $this->_prepareTxt($txt, false)),
                        );
                    }
                }
            }
        }

        // for each indentified action, we have to clean up the begin and the end of the texte
        // based on tags that surround it

        // list of the tags to clean
        $tagsToClean = array(
            'page', 'page_header', 'page_footer', 'form',
            'table', 'thead', 'tfoot', 'tr', 'td', 'th', 'br',
            'div', 'hr', 'p', 'ul', 'ol', 'li',
            'h1', 'h2', 'h3', 'h4', 'h5', 'h6',
            'bookmark', 'fieldset', 'legend',
            'draw', 'circle', 'ellipse', 'path', 'rect', 'line', 'g', 'polygon', 'polyline',
            'option'
        );

        // foreach action
        $nb = count($actions);
        for ($k=0; $k<$nb; $k++) {
            // if it is a Text
            if ($actions[$k]['name']=='write') {
                // if the tag before the text is a tag to clean => ltrim on the text
                if ($k>0 && in_array($actions[$k-1]['name'], $tagsToClean))
                    $actions[$k]['param']['txt'] = ltrim($actions[$k]['param']['txt']);

                // if the tag after the text is a tag to clean => rtrim on the text
                if ($k<$nb-1 && in_array($actions[$k+1]['name'], $tagsToClean))
                    $actions[$k]['param']['txt'] = rtrim($actions[$k]['param']['txt']);

                // if the text is empty => remove the action
                if (!strlen($actions[$k]['param']['txt']))
                    unset($actions[$k]);
            }
        }

        // if we are not on the level 0 => HTML validator ERROR
        if (count($parents)) throw new HTML2PDF_exception(5, $parents);

        // save the actions to do
        $this->code = array_values($actions);
    }

    /**
     * prepare the text
     *
     * @param   string texte
     * @param   boolean true => replace multiple space+\t+\r+\n by a single space
     * @return  string texte
     * @access  protected
     */
    protected function _prepareTxt($txt, $spaces = true)
    {
        if ($spaces) $txt = preg_replace('/\s+/is', ' ', $txt);
        $txt = str_replace('€', '€', $txt);
        $txt = html_entity_decode($txt, ENT_QUOTES, $this->_encoding);
        return $txt;
    }

    /**
     * parse the HTML code
     *
     * @param    &array    array's result
     * @return   null
     */
    protected function _searchCode(&$tmp)
    {
        // initialise the array
        $tmp = array();

        // regexp to separate the tags from the texts
        $reg = '/(<[^>]+>)|([^<]+)+/isU';

        // last match found
        $str = '';
        $offset = 0;

        // As it finds a match
        while (preg_match($reg, $this->_html, $parse, PREG_OFFSET_CAPTURE, $offset)) {
            // if it is a tag
            if ($parse[1][0]) {
                // save the previous text if it exists
                if ($str!=='')    $tmp[] = array('txt', $str);

                // save the tag, with the offset
                $tmp[] = array('code', trim($parse[1][0]), $offset);

                // init the current text
                $str = '';
            } else { // else (if it is a text)
                // add the new text to the current text
                $str.= $parse[2][0];
            }

            // Update offset to the end of the match
            $offset = $parse[0][1] + strlen($parse[0][0]);
            unset($parse);
        }
        // if a text is present in the end, we save it
        if ($str!='') $tmp[] = array('txt', $str);
        unset($str);
    }

    /**
     * analise a HTML tag
     *
     * @param   string   HTML code to analise
     * @return  array    corresponding action
     */
    protected function _analiseCode($code)
    {
        // name of the tag, opening, closure, autoclosure
        $tag = '<([\/]{0,1})([_a-z0-9]+)([\/>\s]+)';
        if (!preg_match('/'.$tag.'/isU', $code, $match)) return null;
        $close     = ($match[1]=='/' ? true : false);
        $autoclose = preg_match('/\/>$/isU', $code);
        $name      = strtolower($match[2]);

        // required parameters (depends on the tag name)
        $param    = array();
        $param['style'] = '';
        if ($name=='img') {
            $param['alt'] = '';
            $param['src'] = '';
        }
        if ($name=='a') {
            $param['href'] = '';
        }

        // read the parameters : nom=valeur
        $prop = '([a-zA-Z0-9_]+)=([^"\'\s>]+)';
        preg_match_all('/'.$prop.'/is', $code, $match);
        for($k=0; $k $val) {
            $key = strtolower($key);
            switch($key)
            {
                case 'width':
                    unset($param[$key]);
                    $param['style'] .= 'width: '.$val.'px; ';
                    break;

                case 'align':
                    if ($name==='img') {
                        unset($param[$key]);
                        $param['style'] .= 'float: '.$val.'; ';
                    } elseif ($name!=='table') {
                        unset($param[$key]);
                        $param['style'] .= 'text-align: '.$val.'; ';
                    }
                    break;

                case 'valign':
                    unset($param[$key]);
                    $param['style'] .= 'vertical-align: '.$val.'; ';
                    break;

                case 'height':
                    unset($param[$key]);
                    $param['style'] .= 'height: '.$val.'px; ';
                    break;

                case 'bgcolor':
                    unset($param[$key]);
                    $param['style'] .= 'background: '.$val.'; ';
                    break;

                case 'bordercolor':
                    unset($param[$key]);
                    $color = $val;
                    break;

                case 'border':
                    unset($param[$key]);
                    if (preg_match('/^[0-9]+$/isU', $val)) $val = $val.'px';
                    $border = $val;
                    break;

                case 'cellpadding':
                case 'cellspacing':
                    if (preg_match('/^([0-9]+)$/isU', $val)) $param[$key] = $val.'px';
                    break;

                case 'colspan':
                case 'rowspan':
                    $val = preg_replace('/[^0-9]/isU', '', $val);
                    if (!$val) $val = 1;
                    $param[$key] = $val;
                    break;
            }
        }

        // compliance of the border
        if ($border!==null) {
            if ($border)    $border = 'border: solid '.$border.' '.$color;
            else            $border = 'border: none';

            $param['style'] .= $border.'; ';
            $param['border'] = $border;
        }

        // reading styles: decomposition and standardization
        $styles = explode(';', $param['style']);
        $param['style'] = array();
        foreach ($styles as $style) {
            $tmp = explode(':', $style);
            if (count($tmp)>1) {
                $cod = $tmp[0];
                unset($tmp[0]);
                $tmp = implode(':', $tmp);
                $param['style'][trim(strtolower($cod))] = preg_replace('/[\s]+/isU', ' ', trim($tmp));
            }
        }

        // determining the level of table opening, with an added level
        if (in_array($name, array('ul', 'ol', 'table')) && !$close) {
            $this->_num++;
            $this->_level[count($this->_level)] = $this->_num;
        }

        // get the level of the table containing the element
        if (!isset($param['num'])) {
            $param['num'] = $this->_level[count($this->_level)-1];
        }

        // for closures table: remove a level
        if (in_array($name, array('ul', 'ol', 'table')) && $close) {
            unset($this->_level[count($this->_level)-1]);
        }

        // prepare the parameters
        if (isset($param['value']))  $param['value']  = $this->_prepareTxt($param['value']);
        if (isset($param['alt']))    $param['alt']    = $this->_prepareTxt($param['alt']);
        if (isset($param['title']))  $param['title']  = $this->_prepareTxt($param['title']);
        if (isset($param['class']))  $param['class']  = $this->_prepareTxt($param['class']);

        // return the new action to do
        return array('name' => $name, 'close' => $close ? 1 : 0, 'autoclose' => $autoclose, 'param' => $param);
    }

    /**
     * get a full level of HTML, between an opening and closing corresponding
     *
     * @param   integer key
     * @return  array   actions
     */
    public function getLevel($k)
    {
        // if the code does not exist => return empty
        if (!isset($this->code[$k])) return array();

        // the tag to detect
        $detect = $this->code[$k]['name'];

        // if it is a text => return
        if ($detect=='write') {
            return array($this->code[$k]);
        }

        //
        $level = 0;      // depth level
        $end = false;    // end of the search
        $code = array(); // extract code

        // while it's not ended
        while (!$end) {
            // current action
            $row = $this->code[$k];

            // if 'write' => we add the text
            if ($row['name']=='write') {
                $code[] = $row;
            } else { // else, it is a html tag
                $not = false; // flag for not taking into account the current tag

                // if it is the searched tag
                if ($row['name']==$detect) {
                    // if we are just at the root level => dont take it
                    if ($level==0) {
                        $not = true;
                    }

                    // update the level
                    $level+= ($row['close'] ? -1 : 1);

                    // if we are now at the root level => it is the end, and dont take it
                    if ($level==0) {
                        $not = true;
                        $end = true;
                    }
                }

                // if we can takin into account the current tag => save it
                if (!$not) {
                    if (isset($row['style']['text-align'])) unset($row['style']['text-align']);
                    $code[] = $row;
                }
            }

            // it continues as long as there has code to analise
            if (isset($this->code[$k+1]))
                $k++;
            else
                $end = true;
        }

        // return the extract
        return $code;
    }

    /**
     * return a part of the HTML code, for error message
     *
     * @param   integer position
     * @param   integer take before
     * @param   integer take after
     * @return  string  part of the html code
     */
    public function getHtmlErrorCode($pos, $before=30, $after=40)
    {
        return substr($this->_html, $pos-$before, $before+$after);
    }
}