⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rtfclass.php

📁 The goal with this project was to make it possible for almost any mobile-phone to use ICQ and be abl
💻 PHP
📖 第 1 页 / 共 2 页
字号:
			if( ereg( "^([A-Za-z]+)(-?[0-9]*) ?$", $this->cword, $match)) {

				$this->parseControl( $match[1], $match[2]);

				if( $this->wantXML) {
					$this->out.="<control word=\"".$match[1]."\"";
					if( strlen( $match[2]) > 0)
						$this->out.=" param=\"".$match[2]."\"";
					$this->out.="/>";
				}
			}
		}

		/*
			If output stream supports comments, dispatch it
		*/
		function flushComment( $comment) {
			if( $this->wantXML || $this->wantHTML) {
				$this->out.="<!-- ".$comment." -->";
			}
		}

		/*
			Dispatch start/end of logical rtf groups
			(not every output type needs it; merely debugging purpose)
		*/
		function flushGroup( $state) {
			if( $state == "open") {

				/* push onto the stack */
				array_push( $this->stack, $this->flags);
			
				if( $this->wantXML)
					$this->out.="<group>";
			}
			if( $state == "close") {

				/* pop from the stack */
				$this->last_flags = $this->flags;
				$this->flags = array_pop( $this->stack);

				$this->flags["fonttbl_current_write"] = ""; // on group close, no more fontdefinition will be written to this id
															// this is not really the right way to do it !
															// of course a '}' not necessarily donates a fonttable end; a fonttable
															// group at least *can* contain sub-groups
															// therefore an stacked approach is heavily needed
				$this->flags["fonttbl"] = false; // no matter what you do, if a group closes, its fonttbl definition is closed too

				if( $this->wantXML)
					$this->out.="</group>";
			}
		}

		function flushHead() {
			if( $this->wantXML)
				$this->out.="<rtf>";
		}

		function flushBottom() {
			if( $this->wantXML)
				$this->out.="</rtf>";
		}


		function checkHtmlSpanContent( $command) {
			reset( $this->fontmodifier_table);
			while( list( $rtf, $html) = each( $this->fontmodifier_table)) {
				if( $this->flags[$rtf] == true) {
					if( $command == "start")
						$this->out .= "<".$html.">";
					else
						$this->out .= "</".$html.">";
				}
			}
		}
		/*
			flush text in queue
		*/
		function flushQueue() {
			if( strlen( $this->queue)) {
				// processing logic
				if( ereg( "^[0-9]+$", $this->flags["fonttbl_want_fcharset"])) {
					$this->fonttable[$this->flags["fonttbl_want_fcharset"]]["charset"] = $this->queue;
					$this->flags["fonttbl_want_fcharset"] = "";
					$this->queue = "";
				}
				
				// output logic
				if( strlen( $this->queue)) {
					/*
						Everything which passes this is (or, at leat, *should*) be only outputted plaintext
						Thats why we can safely add the css-stylesheet when using wantHTML
					*/
					if( $this->wantXML)
						$this->out.= "<plain>".$this->queue."</plain>";

					if( $this->wantHTML) {
						// only output html if a valid (for now, just numeric;) fonttable is given
						if( ereg( "^[0-9]+$", $this->flags["fonttbl_current_read"])) {
							
							if( $this->flags["beginparagraph"] == true) {
								$this->flags["beginparagraph"] = false;
								$this->out .= "<div align=\"";
								switch( $this->flags["alignment"]) {
									case "right":
										$this->out .= "right";
										break;
									case "center":
										$this->out .= "center";
										break;
									case "left":
									default:
										$this->out .= "left";
								}
								$this->out .= "\">";
							}
							
							/* define new style for that span */
							$this->styles["f".$this->flags["fonttbl_current_read"]."s".$this->flags["fontsize"]] = "font-family:".$this->fonttable[$this->flags["fonttbl_current_read"]]["charset"]." font-size:".$this->flags["fontsize"].";";
							/* write span start */
							$this->out .= "<span class=\"f".$this->flags["fonttbl_current_read"]."s".$this->flags["fontsize"]."\">";

							/* check if the span content has a modifier */
							$this->checkHtmlSpanContent( "start");
							/* write span content */
							$this->out .= $this->queue;
							/* close modifiers */
							$this->checkHtmlSpanContent( "stop");
							/* close span */
							"</span>";
						}
					}
					$this->queue = "";
				}
			}
		}

		/*
			handle special charactes like \'ef
		*/
		function flushSpecial( $special) {
			if( strlen( $special) == 2) {
				if( $this->wantXML)
					$this->out .= "<special value=\"".$special."\"/>";
			}
		}

		/*
			Output errors at end
		*/
		function flushErrors() {
			if( count( $this->err) > 0) {
				if( $this->wantXML) {
						$this->out .= "<errors>";
						while( list($num,$value) = each( $this->err)) {
							$this->out .= "<message>".$value."</message>";
						}
						$this->out .= "</errors>";
				}
			}
		}

		function makeStyles() {
			$this->outstyles = "<style type=\"text/css\"><!--\n";
			reset( $this->styles);
			while( list( $stylename, $styleattrib) = each( $this->styles)) {
				$this->outstyles .= ".".$stylename." { ".$styleattrib." }\n";
			}
			$this->outstyles .= "--></style>\n";
		}

		/*
			finally ..

			How this parser (is supposed) to work:
			======================================
			This parse simple starts at the beginning of the rtf core stream, catches every
			controlling character {,} and \, automatically builds control words and control
			symbols during his livetime, trashes every other character into the plain text
			queue
		*/
		function parse() {

			$this->parserInit();

			$i = 0;
			$this->cw= false;	// flag if control word is currently parsed
			$this->cfirst = false;// first control character ?
			$this->cword = "";	// last or current control word ( depends on $this->cw

			$this->queue = "";		// plain text data found during parsing

			$this->flushHead();

			while( $i < $this->len) {
				switch( $this->rtf[$i]) {
					case "{":	if( $this->cw) {
									$this->flushControl();
									$this->cw= false; $this->cfirst = false;
								} else 
									$this->flushQueue();

								$this->flushGroup( "open");
								break;
					case "}":	if( $this->cw) {
									$this->flushControl();
									$this->cw= false; $this->cfirst = false;
								} else
									$this->flushQueue();

								$this->flushGroup( "close");
								break;
					case "\\":	if( $this->cfirst) {	// catches '\\' 
									$this->queue .= '\\';
									$this->cfirst = false;
									$this->cw= false;
									break;
								}
								if( $this->cw) {
									$this->flushControl();
								} else 
									$this->flushQueue();
								$this->cw = true;
								$this->cfirst = true;
								$this->cword = "";
								break;
					default:	
								if( (ord( $this->rtf[$i]) == 10) || (ord($this->rtf[$i]) == 13)) break; // eat line breaks
								if( $this->cw) {	// active control word ?
									/*
										Watch the RE: there's an optional space at the end which IS part of
										the control word (but actually its ignored by flushControl)
									*/
									if( ereg( "^[a-zA-Z0-9-]?$", $this->rtf[$i])) { // continue parsing
										$this->cword .= $this->rtf[$i];
										$this->cfirst = false;
									} else {
										/*
											Control word could be a 'control symbol', like \~ or \* etc.
										*/
										$specialmatch = false;
										if( $this->cfirst) {
											if( $this->rtf[$i] == '\'') { // expect to get some special chars
												$this->flushQueue();
												$this->flushSpecial( $this->rtf[$i+1].$this->rtf[$i+2]);
												$i+=2;
												$specialmatch = true;
												$this->cw = false; $this->cfirst = false; $this->cword = "";
											} else 
											if( ereg( "^[{}\*]$", $this->rtf[$i])) {
												$this->flushComment( "control symbols not yet handled");
												$specialmatch = true;
											}
											$this->cfirst = false;
										} else {
											if( $this->rtf[$i] == ' ') {	// space delimtes control words, so just discard it and flush the controlword
												$this->cw = false;
												$this->flushControl();
												break;
											}
										}
										if( ! $specialmatch) {
											$this->flushControl();
											$this->cw = false; $this->cfirst = false;
											/*
												The current character is a delimeter, but is NOT
												part of the control word so we hop one step back
												in the stream and process it again
											*/
											$i--;
										}
									}
								} else {
									// < and > need translation before putting into queue when XML or HTML is wanted
									if( ($this->wantHTML) || ($this->wantXML)) {
										switch( $this->rtf[$i]) {
											case "<":
												$this->queue .= "&lt;";
												break;
											case ">":
												$this->queue .= "&gt;";
												break;
											default:
												$this->queue .= $this->rtf[$i];
												break;
										}
									} else 
										$this->queue .= $this->rtf[$i];
								}
									
				}
				$i++;
			}
			$this->flushQueue();
			$this->flushErrors();
			$this->flushBottom();

			if( $this->wantHTML) {
				$this->makeStyles();
			}
		}
	}
?>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -