libraries/tbs/plugins/tbs_plugin_opentbs.php
function Ext_PrepareInfo($Ext=false) {

		$this->ExtEquiv = false;
		$this->ExtType = false;
	
		if ($Ext===false) {
			// Get the extension of the current archive
			if ($this->ArchIsStream) {
				$Ext = '';
			} else {
				$Ext = basename($this->ArchFile);
				$p = strrpos($Ext, '.');
				$Ext = ($p===false) ? '' : strtolower(substr($Ext, $p + 1));
			}
			$Frm = $this->Ext_DeductFormat($Ext, true);
			// Rename the name of the phantom file if it is a stream
			if ( $this->ArchIsStream && (strlen($Ext)>2) ) $this->ArchFile = str_replace('.zip', '.'.$Ext, $this->ArchFile);
		} else {
			// The extension is forced
			$Frm = $this->Ext_DeductFormat($Ext, false);
		}

		$TBS = &$this->TBS;
		$set_option = method_exists($TBS, 'SetOption');
		
		$i = false;
		$block_alias = false;
		
		if (isset($GLOBAL['_OPENTBS_AutoExt'][$Ext])) {
			// User defined information
			$i = $GLOBAL['_OPENTBS_AutoExt'][$Ext];
			if (isset($i['equiv'])) $this->ExtEquiv = $i['equiv'];
			if (isset($i['frm'])) $this->ExtType = $i['frm'];
		} elseif ($Frm==='odf') {
			// OpenOffice & LibreOffice documents
			$i = array('main' => 'content.xml', 'br' => '<text:line-break/>', 'ctype' => 'application/vnd.oasis.opendocument.', 'pic_path' => 'Pictures/', 'rpl_what' => '&apos;', 'rpl_with' => '\'');
			if ($this->FileExists('styles.xml')) $i['load'] = array('styles.xml'); // styles.xml may contain header/footer contents
			if ($Ext==='odf') $i['br'] = false;
			if ($Ext==='odm') $this->ExtEquiv = 'odt';
			$this->ExtType = 'odf';
			$ctype = array('t' => 'text', 's' => 'spreadsheet', 'g' => 'graphics', 'f' => 'formula', 'p' => 'presentation', 'm' => 'text-master');
			$i['ctype'] .= $ctype[($Ext[2])];
			$i['pic_ext'] = array('png' => 'png', 'bmp' => 'bmp', 'gif' => 'gif', 'jpg' => 'jpeg', 'jpeg' => 'jpeg', 'jpe' => 'jpeg', 'jfif' => 'jpeg', 'tif' => 'tiff', 'tiff' => 'tiff');
			$block_alias = array(
				'tbs:p' => 'text:p',              // ODT+ODP
				'tbs:title' => 'text:h',          // ODT+ODP
				'tbs:section' => 'text:section',  // ODT
				'tbs:table' => 'table:table',     // ODT (sheet for ODS)
				'tbs:row' => 'table:table-row',   // ODT+ODS
				'tbs:cell' => 'table:table-cell', // ODT+ODS
				'tbs:comment' => 'office:annotation',
				'tbs:page' => array(&$this, 'OpenDoc_GetPage'), // ODT
				'tbs:slide' => 'draw:page',       // ODP
				'tbs:sheet' => 'table:table',     // ODS (table for ODT)
				'tbs:draw' => array(&$this, 'OpenDoc_GetDraw'),
				'tbs:drawgroup' => 'draw:g',
				'tbs:drawitem' => array(&$this, 'OpenDoc_GetDraw'),
				'tbs:listitem' => 'text:list-item', // ODT+ODP
			);
			if ($set_option) {
				$TBS->SetOption('parallel_conf', 'tbs:table', 
					array(
						'parent' => 'table:table',
						'ignore' => array('table:covered-table-cell', 'table:table-header-rows'),
						'cols' => array('table:table-column' => 'table:number-columns-repeated'),
						'rows' => array('table:table-row'),
						'cells' => array('table:table-cell' => 'table:number-columns-spanned'),
					)
				);
			}
		} elseif ($Frm==='openxml') {
			// Microsoft Office documents
			$this->OpenXML_MapInit();
			if ($TBS->OtbsConvertApostrophes) {
				$x = array(chr(226) . chr(128) . chr(152), chr(226) . chr(128) . chr(153));
			} else {
				$x = null;
			}
			$ctype = 'application/vnd.openxmlformats-officedocument.';
			if ($Ext==='docx') {
				$i = array('br' => '<w:br/>', 'ctype' => $ctype . 'wordprocessingml.document', 'pic_path' => 'word/media/', 'rpl_what' => $x, 'rpl_with' => '\'');
				$i['main'] = $this->OpenXML_MapGetMain('wordprocessingml.document.main+xml', 'word/document.xml');
				$i['load'] = $this->OpenXML_MapGetFiles(array('wordprocessingml.header+xml', 'wordprocessingml.footer+xml'));
				$block_alias = array(
					'tbs:p' => 'w:p',
					'tbs:title' => 'w:p',
					'tbs:section' => array(&$this, 'MsWord_GetSection'),
					'tbs:table' => 'w:tbl',
					'tbs:row' => 'w:tr',
					'tbs:cell' => 'w:tc',
					'tbs:page' => array(&$this, 'MsWord_GetPage'),
					'tbs:draw' => 'mc:AlternateContent',
					'tbs:drawgroup' => 'mc:AlternateContent',
					'tbs:drawitem' => 'wps:wsp',
					'tbs:listitem' => 'w:p',
				);  
				if ($set_option) {
					$TBS->SetOption('parallel_conf', 'tbs:table', 
						array(
							'parent' => 'w:tbl',
							'ignore' => array('w:tblPr', 'w:tblGrid'),
							'cols' => array('w:gridCol' => ''),
							'rows' => array('w:tr'),
							'cells' => array('w:tc' => ''), // <w:gridSpan w:val="2"/>
						)
					);
				}
			} elseif ( ($Ext==='xlsx') || ($Ext==='xlsm')) {
				$this->MsExcel_DeleteCalcChain();
				$i = array('br' => false, 'ctype' => $ctype . 'spreadsheetml.sheet', 'pic_path' => 'xl/media/');
				$i['main'] = $this->OpenXML_MapGetMain('spreadsheetml.worksheet+xml', 'xl/worksheets/sheet1.xml');
				$this->ExtEquiv = 'xlsx';
				$block_alias = array(
					'tbs:row' => 'row',
					'tbs:cell' => 'c',
					'tbs:draw' => 'xdr:twoCellAnchor',
					'tbs:drawgroup' => 'xdr:twoCellAnchor',
					'tbs:drawitem' => 'xdr:sp',
				);
			} elseif ($Ext==='pptx') {
				$i = array('br' => false, 'ctype' => $ctype . 'presentationml.presentation', 'pic_path' => 'ppt/media/', 'rpl_what' => $x, 'rpl_with' => '\'');
				$this->MsPowerpoint_InitSlideLst();
				$i['main'] = (isset($this->OpenXmlSlideLst[0])) ? $this->OpenXmlSlideLst[0]['file'] : 'ppt/slides/slide1.xml';
				$i['load'] = $this->OpenXML_MapGetFiles(array('presentationml.notesSlide+xml')); // auto-load comments
				$block_alias = array(
					'tbs:p' => 'a:p',
					'tbs:title' => 'a:p',
					'tbs:table' => 'a:tbl',
					'tbs:row' => 'a:tr',
					'tbs:cell' => 'a:tc',
					'tbs:draw' => 'p:sp',
					'tbs:drawgroup' => 'p:grpSp',
					'tbs:drawitem' => 'p:sp',
					'tbs:listitem' => 'a:p',
				);
			}
			$i['pic_ext'] = array('png' => 'png', 'bmp' => 'bmp', 'gif' => 'gif', 'jpg' => 'jpeg', 'jpeg' => 'jpeg', 'jpe' => 'jpeg', 'tif' => 'tiff', 'tiff' => 'tiff', 'ico' => 'x-icon', 'svg' => 'svg+xml');
		}

		if ($i!==false) {
			$i['ext'] = $Ext;
			if (!isset($i['load'])) $i['load'] = array();
			$i['load'][] = $i['main']; // add to main file at the end of the files to load
		}
		  
		if ($set_option && ($block_alias!==false)) $TBS->SetOption('block_alias', $block_alias);

		$this->ExtInfo = $i;
		if ($this->ExtEquiv===false) $this->ExtEquiv = $Ext;
		if ($this->ExtType===false)  $this->ExtType = $Frm;
		return (is_array($i)); // return true if the extension is supported
	}
function Ext_PrepareInfo($Ext=false) {

		$this->ExtEquiv = false;
		$this->ExtType = false;
	
		if ($Ext===false) {
			// Get the extension of the current archive
			if ($this->ArchIsStream) {
				$Ext = '';
			} else {
				$Ext = basename($this->ArchFile);
				$p = strrpos($Ext, '.');
				$Ext = ($p===false) ? '' : strtolower(substr($Ext, $p + 1));
			}
			$Frm = $this->Ext_DeductFormat($Ext, true);
			// Rename the name of the phantom file if it is a stream
			if ( $this->ArchIsStream && (strlen($Ext)>2) ) $this->ArchFile = str_replace('.zip', '.'.$Ext, $this->ArchFile);
		} else {
			// The extension is forced
			$Frm = $this->Ext_DeductFormat($Ext, false);
		}

		$TBS = &$this->TBS;
		$set_option = method_exists($TBS, 'SetOption');
		
		$i = false;
		$block_alias = false;
		
		if (isset($GLOBAL['_OPENTBS_AutoExt'][$Ext])) {
			// User defined information
			$i = $GLOBAL['_OPENTBS_AutoExt'][$Ext];
			if (isset($i['equiv'])) $this->ExtEquiv = $i['equiv'];
			if (isset($i['frm'])) $this->ExtType = $i['frm'];
		} elseif ($Frm==='odf') {
			// OpenOffice & LibreOffice documents
			$i = array('main' => 'content.xml', 'br' => '<text:line-break/>', 'ctype' => 'application/vnd.oasis.opendocument.', 'pic_path' => 'Pictures/', 'rpl_what' => '&apos;', 'rpl_with' => '\'');
			if ($this->FileExists('styles.xml')) $i['load'] = array('styles.xml'); // styles.xml may contain header/footer contents
			if ($Ext==='odf') $i['br'] = false;
			if ($Ext==='odm') $this->ExtEquiv = 'odt';
			$this->ExtType = 'odf';
			$ctype = array('t' => 'text', 's' => 'spreadsheet', 'g' => 'graphics', 'f' => 'formula', 'p' => 'presentation', 'm' => 'text-master');
			$i['ctype'] .= $ctype[($Ext[2])];
			$i['pic_ext'] = array('png' => 'png', 'bmp' => 'bmp', 'gif' => 'gif', 'jpg' => 'jpeg', 'jpeg' => 'jpeg', 'jpe' => 'jpeg', 'jfif' => 'jpeg', 'tif' => 'tiff', 'tiff' => 'tiff');
			$block_alias = array(
				'tbs:p' => 'text:p',              // ODT+ODP
				'tbs:title' => 'text:h',          // ODT+ODP
				'tbs:section' => 'text:section',  // ODT
				'tbs:table' => 'table:table',     // ODT (sheet for ODS)
				'tbs:row' => 'table:table-row',   // ODT+ODS
				'tbs:cell' => 'table:table-cell', // ODT+ODS
				'tbs:comment' => 'office:annotation',
				'tbs:page' => array(&$this, 'OpenDoc_GetPage'), // ODT
				'tbs:slide' => 'draw:page',       // ODP
				'tbs:sheet' => 'table:table',     // ODS (table for ODT)
				'tbs:draw' => array(&$this, 'OpenDoc_GetDraw'),
				'tbs:drawgroup' => 'draw:g',
				'tbs:drawitem' => array(&$this, 'OpenDoc_GetDraw'),
				'tbs:listitem' => 'text:list-item', // ODT+ODP
			);
			if ($set_option) {
				$TBS->SetOption('parallel_conf', 'tbs:table', 
					array(
						'parent' => 'table:table',
						'ignore' => array('table:covered-table-cell', 'table:table-header-rows'),
						'cols' => array('table:table-column' => 'table:number-columns-repeated'),
						'rows' => array('table:table-row'),
						'cells' => array('table:table-cell' => 'table:number-columns-spanned'),
					)
				);
			}
		} elseif ($Frm==='openxml') {
			// Microsoft Office documents
			$this->OpenXML_MapInit();
			if ($TBS->OtbsConvertApostrophes) {
				$x = array(chr(226) . chr(128) . chr(152), chr(226) . chr(128) . chr(153));
			} else {
				$x = null;
			}
			$ctype = 'application/vnd.openxmlformats-officedocument.';
			if ($Ext==='docx') {
				$i = array('br' => '<w:br/>', 'ctype' => $ctype . 'wordprocessingml.document', 'pic_path' => 'word/media/', 'rpl_what' => $x, 'rpl_with' => '\'');
				$i['main'] = $this->OpenXML_MapGetMain('wordprocessingml.document.main+xml', 'word/document.xml');
				$i['load'] = $this->OpenXML_MapGetFiles(array('wordprocessingml.header+xml', 'wordprocessingml.footer+xml'));
				$block_alias = array(
					'tbs:p' => 'w:p',
					'tbs:title' => 'w:p',
					'tbs:section' => array(&$this, 'MsWord_GetSection'),
					'tbs:table' => 'w:tbl',
					'tbs:row' => 'w:tr',
					'tbs:cell' => 'w:tc',
					'tbs:page' => array(&$this, 'MsWord_GetPage'),
					'tbs:draw' => 'mc:AlternateContent',
					'tbs:drawgroup' => 'mc:AlternateContent',
					'tbs:drawitem' => 'wps:wsp',
					'tbs:listitem' => 'w:p',
				);  
				if ($set_option) {
					$TBS->SetOption('parallel_conf', 'tbs:table', 
						array(
							'parent' => 'w:tbl',
							'ignore' => array('w:tblPr', 'w:tblGrid'),
							'cols' => array('w:gridCol' => ''),
							'rows' => array('w:tr'),
							'cells' => array('w:tc' => ''), // <w:gridSpan w:val="2"/>
						)
					);
				}
			} elseif ( ($Ext==='xlsx') || ($Ext==='xlsm')) {
				$this->MsExcel_DeleteCalcChain();
				$i = array('br' => false, 'ctype' => $ctype . 'spreadsheetml.sheet', 'pic_path' => 'xl/media/');
				$i['main'] = $this->OpenXML_MapGetMain('spreadsheetml.worksheet+xml', 'xl/worksheets/sheet1.xml');
				$this->ExtEquiv = 'xlsx';
				$block_alias = array(
					'tbs:row' => 'row',
					'tbs:cell' => 'c',
					'tbs:draw' => 'xdr:twoCellAnchor',
					'tbs:drawgroup' => 'xdr:twoCellAnchor',
					'tbs:drawitem' => 'xdr:sp',
				);
			} elseif ($Ext==='pptx') {
				$i = array('br' => false, 'ctype' => $ctype . 'presentationml.presentation', 'pic_path' => 'ppt/media/', 'rpl_what' => $x, 'rpl_with' => '\'');
				$this->MsPowerpoint_InitSlideLst();
				$i['main'] = (isset($this->OpenXmlSlideLst[0])) ? $this->OpenXmlSlideLst[0]['file'] : 'ppt/slides/slide1.xml';
				$i['load'] = $this->OpenXML_MapGetFiles(array('presentationml.notesSlide+xml')); // auto-load comments
				$block_alias = array(
					'tbs:p' => 'a:p',
					'tbs:title' => 'a:p',
					'tbs:table' => 'a:tbl',
					'tbs:row' => 'a:tr',
					'tbs:cell' => 'a:tc',
					'tbs:draw' => 'p:sp',
					'tbs:drawgroup' => 'p:grpSp',
					'tbs:drawitem' => 'p:sp',
					'tbs:listitem' => 'a:p',
				);
			}
			$i['pic_ext'] = array('png' => 'png', 'bmp' => 'bmp', 'gif' => 'gif', 'jpg' => 'jpeg', 'jpeg' => 'jpeg', 'jpe' => 'jpeg', 'tif' => 'tiff', 'tiff' => 'tiff', 'ico' => 'x-icon', 'svg' => 'svg+xml');
		}

		if ($i!==false) {
			$i['ext'] = $Ext;
			if (!isset($i['load'])) $i['load'] = array();
			$i['load'][] = $i['main']; // add to main file at the end of the files to load
		}
		  
		if ($set_option && ($block_alias!==false)) $TBS->SetOption('block_alias', $block_alias);

		$this->ExtInfo = $i;
		if ($this->ExtEquiv===false) $this->ExtEquiv = $Ext;
		if ($this->ExtType===false)  $this->ExtType = $Frm;
		return (is_array($i)); // return true if the extension is supported
	}
Actualize property ExtInfo (Extension Info).
ExtInfo will be an array with keys 'load', 'br', 'ctype' and 'pic_path'. Keys 'rpl_what' and 'rpl_with' are optional.
load:     files in the archive to be automatically loaded by OpenTBS when the archive is loaded. Separate files with comma ';'.
br:       string that replace break-lines in the values merged by TBS, set to false if no conversion.
frm:      format of the file ('odf' or 'openxml'), for now it is used only to activate a special feature for openxml files
ctype:    (optional) the Content-Type header name that should be use for HTTP download. Omit or set to '' if not specified.
pic_path: (optional) the folder nale in the archive where to place pictures
rpl_what: (optional) string to replace automatically in the files when they are loaded. Can be a string or an array.
rpl_with: (optional) to be used with 'rpl_what',  Can be a string or an array.
User can define his own Extension Information, they are taken in acount if saved int the global variable $_OPENTBS_AutoExt.