BASH 脚本, 生成 Web 浏览的 gallery

用到了一点点Javascript, 没有怎么测试.
#!/bin/bash
#
# generate a gallery for web usage.

# useage: title dir
#
# Ref jiangzuoyan.blogspot.com
# date: 2007-03-03 13:04:43


TITLE=${1:-View}

DIR=${2:-./}

parse_dir()
{
   local dir=$1 fn images  subdirs title aimgs aaimgs
   images=''

   subdirs=' '
   title=''
   local oldp=`pwd`
   cd "$dir" || return 3;
   pwd

   for fn in * ;
   do
       if  [ -d "$fn" ] ; then

           echo "[dir $fn ..."
           parse_dir "$fn"
           echo "end $fn]"
           subdirs="$subdirs <a href='$fn/index.html'>$fn</a>"

       else
           file -b -i "$fn" | grep "image/" > /dev/null  &&  {
               if [ "$images" ] ; then

                   images="$images,\"$fn\""
               else
                   mkdir -p ".cache"
                   images="\"$fn\""

               fi
               if [ ".cache/$fn" -ot "$fn" ] ; then

                   convert -resize 90x90 "$fn" ".cache/$fn"
               fi
           }
       fi
   done


   title=`basename $dir`
   title=${2:-$title}
   set_index "$subdirs" "$title" "$images"

   cd $oldp
}

set_index()
{
   local IMAGES SUBDIRS TITLE
   IMAGES=${3:-null}

   SUBDIRS=${1:- }
   TITLE=$2
cat > index.html <<EOF_INDEX_TPL

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf8">
<title>$TITLE</title>

</head>
<body>
<style>
.simgc{width:100px;height:100px;float:left;}
.aimg, .simg{max-width:90px;max-height:90px;margin:5px;}
</style>

  <a href="../index.html" style="float:right;">Up</a>
<h1>$TITLE</h1>
<div id="vd"></div>


<script>

var Class = {
 create: function() {
   return function() {

     this.initialize.apply(this, arguments);
   }
 }
}

Object.extend = function(destination, source) {

 for (var property in source) {
   destination[property] = source[property];
 }

 return destination;
}


Function.prototype.bindAsEventListener = function(object) {
 var __method = this;
 return function(event) {

   return __method.call(object, event || window.event);
 }
}

var ImageView=Class.create();
ImageView.prototype={

  options:{base_src:'./',
           pageSize: 50},

  initialize:function(obj, options){

     Object.extend(this.options, options||{});
     this.obj=document.getElementById(obj);
     this.showContainer=document.createElement('div');
     document.body.appendChild(this.showContainer);
     this.showContainer.style.display='none';
     this.showContainer.style.zIndex="10000";
     this.showContainer.style.position="absolute";
     this.showContainer.style.background="green";
     this.showContainer.style.overflow="auto";
     this.showContainer.style.margin="0px";
  },


  viewImage:function(imgsrc){
     var s='';
     s+='<div class="simgc">'

        +'<img src="'+this.options.base_src+".cache/"+imgsrc+'" class="simg" />'
        +'</div>';
     return s;
  },


  viewImages:function(imgs){
     var s='';
     for(var i=0;i<imgs.length;++i){

         s+=this.viewImage(imgs[i]);
     }
     return s;
  },


  slideTo:function(ith){
     if(ith<0 || ith>=this.images.length)

        return ;
     this.cur_slide=ith;
     this.cur_images=this.images.slice(ith, ith+this.options.pageSize);
  },

  slideLink:function(){

     var pith=-1, nith=-1, pl, nl;
     nith=this.cur_slide+this.options.pageSize;
     pith=this.cur_slide-this.options.pageSize;
     if(pith<0) {

        if(this.cur_slide==0) pith=-1;
        else pith=0;
     }

     if(nith>=this.images.length){ nith=-1;}
     if(pith>-1) pl=this.setSlideAction(pith);
     if(nith>-1) nl=this.setSlideAction(nith);
     return [pl, nl];
  },


  setSlideAction:function(ith){
     var sp=document.createElement('span');
     sp._pt_ith=ith;
     sp._pt_viewer=this;
     sp.onclick=function(){

        this._pt_viewer.slideTo(sp._pt_ith);
        this._pt_viewer.view();
     };
     return sp;
  },


  view:function(){
     if(!this.cur_images)
        this.slideTo(0);
     var s=this.viewImages(this.cur_images);
     this.obj.innerHTML=s;
     var dpn=document.createElement('div');
     dpn.style.clear="both";
     dpn.style.textAlign="center";
     if(this.cur_slide>0){

        var f=this.setSlideAction(0);
        f.innerHTML="first | "
        dpn.appendChild(f);
     }

     var pnl=this.slideLink();
     if(pnl[0]){
        pnl[0].innerHTML="<<";
        dpn.appendChild(pnl[0]);
     }

     var t=document.createTextNode(" | "+this.cur_slide+" | ");
     dpn.appendChild(t);
     if(pnl[1]){

        pnl[1].innerHTML=">>";
        dpn.appendChild(pnl[1]);
     }

     if(this.cur_slide+this.options.pageSize<this.images.length){
        var e=this.setSlideAction(this.images.length-this.options.pageSize);
        e.innerHTML="  | end";
        dpn.appendChild(e);
     }

     this.obj.appendChild(dpn);

     var imgs=this.obj.getElementsByTagName('img');
     for(var i=0;i<imgs.length;++i){

        imgs[i].onclick=this.imgOnclick.bindAsEventListener(imgs[i]);
        imgs[i]._pt_viewer=this;
     }

  },

  imgOnclick:function(e){
     var v=this._pt_viewer;
     v.toggle(this);
  },


  toggle:function(img){
     if(this.curshow){
        if(this.curshow==img){

           if(img.className=='aimg'){
              img.className='simg';
              this.unshow(img);
           }

           else
              alert('toogle, why this happend?');
           this.curshow=null;
           return;
        }
        else {

           this.curshow.className='simg';
        }
     }
     this.curshow=img;
     this.show(img);
     img.className='aimg';
  },


  posShow:function(){
     var x=this.docScrollLeft(), y=this.docScrollTop();
     var m=this.showContainer;
     m.style.left=x+"px";
     m.style.top=y+"px";
     m.style.display="block";
  },


  show:function(img){
     this.showContainer.innerHTML='<img src="'+this.getBigsrc(img.src)+'" alt="'+img.src+'"/>';
     this.showContainer.onclick=img.onclick
     this.posShow();
  },


  getBigsrc:function(imgsrc){
     var idx=imgsrc.lastIndexOf("/.cache/");
     if(idx<0) return imgsrc;
     return imgsrc.slice(0, idx)

           +imgsrc.slice(idx+".cache/".length);
  },

  unshow:function(img){

     this.showContainer.style.display="none";
  },

  // pick form RicoUtil ....
  docScrollLeft: function() {
     if ( window.pageXOffset )

        return window.pageXOffset;
     else if ( document.documentElement && document.documentElement.scrollLeft )
        return document.documentElement.scrollLeft;
     else if ( document.body )

        return document.body.scrollLeft;
     else
        return 0;
  },

  docScrollTop: function() {

     if ( window.pageYOffset )
        return window.pageYOffset;
     else if ( document.documentElement && document.documentElement.scrollTop )

        return document.documentElement.scrollTop;
     else if ( document.body )
        return document.body.scrollTop;
     else

        return 0;
  }
};
var images=[$IMAGES];
var iv=new ImageView('vd');
iv.images=images;
iv.view();

</script>
<hr>
<div>
$SUBDIRS
</div>
</body>
</html>

EOF_INDEX_TPL
}


umask 022
parse_dir $DIR $TITLE

一个 PHP MVC 的实现

一切见诸代码, 注释应该是无声的.....

<?php
/**
 * PtAction base class file
 *
 * PHP Version PHP 5
 *
 * LICENSE: The version 3.0 of PHP License.
 *
 * @author Changsheng Jiang <pointer@tom.com>
 */
 
define('PT_BASE_ROOT', dirname(__FILE__).DIRECTORY_SEPARATOR);

 
require_once 'func.lib.php';
 
/**
 * PtConfig
 *
 * The base configuration class with some static function for convenient.
 */
class PtConfig {
 
    /**
     * Get the static properties, this e.g can be served as a class
     * configuration.
     * 
     * @param string $name component name, usually a class name
     * @param string $var  the variable name
     * @return mixed the property
     */

    public static function &getStaticProperty($name, $var) {
        static $properties;
        return $properties[$name][$var];
    }

 
    public static function setStaticProperty($configs) {
        foreach ($configs as $class=>$config) {

            foreach ($config as $k=>$v) {
                $config = & self::getStaticProperty($class, $k);
                $config = $v;
            }

        }
    }
}
 
/**
 * PtAppConfiguration
 *
 * A module/application configuration class
 */
class PtAppConfiguration extends PtConfig {

 
}
 
/**
 * PtUser
 *
 */
class PtUser extends PtComponent {
    /**
     * @var  array $userData
     * @access protected
     */

    protected  $userData;
 
    var $id;
    var $username = '';
    var $password = '';
    var $privilege = -1;

 
    /**
     * set user data form array, the array must has the key
     * 'username', 'password', 'privilege' seted.
     *
     * @param array $ua
     * @access public
     */
    public function fromArray($ua) {
        foreach ($ua as $key=>$value) {

            $this->userData[$key]=$value;
        }
        $this->username = getValue($this->userData, 'username', '');
        $this->password = getValue($this->userData, 'password', '');
        $this->privilege = getValue($this->userData, 'privilege', 0);
        $this->id = getValue($this->userData, 'id', 0);

 
    }
 
    /**
     * Load user data from session
     *
     * @access public
     * @return bool true if session has user data.
     */
    public function getSession() {

        if(isset($_SESSION['user'])) {
            $this->fromArray($_SESSION['user']);
            return true;
        }

        return false;
    }
 
    /**
     * Return user data as a array
     */
    public function toArray() {

        return $this->userData;
    }
 
    /**
     * set the session
     */
    public function setSession() {

        foreach($this->userData as $key=>$value) {
            $_SESSION['user'][$key]=$value;
        }

    }
 
    /**
     * check is login, get session auto.
     */
    public function isLogin() {

        if ($this->privilege < 0) {
            $this->getSession();
        }

        return $this->privilege > 0;
    }
 
    /**
     * login, abstract function ...
     */
    public function login() {

 
    }
 
    /**
     * logout, reset the session
     */
    public function logout() {

        unset($_SESSION['user']);
        $this->privilege=0;    
    }

 
    /**
     * check user has the privilege do admin
     */
    public function isCanAdmin() {
        $level = PtConfig::getStaticProperty(get_class($this), 'admin_privilege');
        if (!$level) $level = 10000;
        return $this->privilege >= $level;
    }

 
    /**
     * check if user is is root.
     */
    public function isRoot() {
        $level = PtConfig::getStaticProperty(get_class($this), 'root_privilege');
        if (!$level) $level = 30000;
        return $this->privilege >= $level;
    }

}
 
/**
 * PtComponent
 *
 * The PtComponent class is the base class of all classes which has
 * prefix Pt.
 *
 * All common feature of MVC should be place here.
 * 
 */
class PtComponent
{
 
    /**
     * toggle debug message out or not.
     *
     * @access public
     * @var    integer
     */
    public $debugging = 0;

 
    /**
     * The number for generating a unique id
     *
     * @access private
     * @var    integer
     * @see    getUniqueId
     */
    private static $_uniqueid =0;
 
    /**
     * The component unique id
     * 
     * @access public
     * @var string
     */

    public $componentId = "";
 
    /**
     * The parameters about the instance.
     *
     * @access protected
     * @var    array
     * @see    getParam, setParam
     */
    protected $params = array();

 
    /**
     * Return a unique id as component
     *
     * @access public
     * @return integer
     */
    public static function getUniqueId(){
        return self::$_uniqueid++;
    }

 
 
    /**
     * Get Parameter by name with default if the parameter is not
     * seted.
     *
     * @access public
     * @param  string $name the key of the parameter
     * @param  mixed  $default the default value if parameter is not seted.
     * @return mixed
     */
    public function getParam($name, $default = false) {

        return isset($this->params[$name])
            ? $this->params[$name] : $default;
    }

 
    /**
     * Unset the parameter
     *
     * @access public
     * @param  string $name the key of the parameter
     */
    public function unsetParam($name) {
        unset($this->params[$name]);
    }

 
    /**
     * Set a parameter
     *
     * @access public
     * @param string $name the key of the parameter
     * @param mixed  $value the value of the parameter
     */
    public function setParam($name, $value ) {

        unset($this->params[$name]);//unset first to prevent type overload
        $this->params[$name] = $value;
    }

 
    /**
     * Set parameters
     *
     * @access public
     * @param array $params the parameters be seted
     */
    public function setParams($params) {
        if (is_array($params)) {

            $this->params = array_merge($this->params, $params);
        }

        throw new Exception("inner error: invalid argument in setParams");
    }
 
    /**
     * Get the component name
     *
     * @access public
     * @return string
     */
    function getComponentName() {

        if (is_object($this->module) && !empty($this->module->name))

            return $this->module->name . ':' . get_class( $this );
        else

            return get_class( $this );
    }
 
    /**
     * Initialize
     * @access public
     */
    public function initialize() {

 
    }
 
    /**
     * dispose function as the module dispose.
     *
     * @access public
     */
    public function dispose() {

 
    }
 
    /**
     * debuge message, check debugging level
     *
     * @access public
     */
    public function  debugMsg($message, $level=0) {

        if ($this->debugging &&
            $this->debugging > $level ) {

            echo $message;
        }
    }
}
 
/**
 * PtModel
 *
 * Abstract base class of all Model, generally this will just empty,
 * dispatch the call to really DB.
 */
abstract class PtModel extends PtComponent {

}
 
/**
 * PtAction
 *
 * Abstract base class of all Command/Action.
 * A subclass must overload the execute function.
 */
abstract class PtAction extends PtComponent {
 
    /**
     * data for a view to show
     *
     * @var array
     * @access protected
     * @see    setViewData
     */

    protected $view_data;
 
    /**
     * the action module
     *
     * @var   mixed
     * @access public
     */
    var       $module;
 
    /**
     * check is the request method post
     *
     * @access public
     */

    public function isPost() {
        return( isset( $_SERVER['REQUEST_METHOD'] ) && $_SERVER['REQUEST_METHOD'] === 'POST' );
    }

 
    /**
     * Main function, action take here.
     *
     * @access public
     */
    public function run($action) {
        $this->setViewData('curlevel', $this->module->getActionLevel($action));
        $this->setViewData('isLogin', $this->module->user->isLogin());
        $this->setViewData('isRoot', $this->module->user->isRoot());
        $this->setViewData('user', $this->module->user->toArray());
    }

 
    public function addViewData($key, $value) {
        if (is_array($value)) {

            $this->view_data[$key]=array_merge($this->view_data[$key], $value);
        } else {

            $this->view_data[$key]=$value;
        }
    }
 
    public function  setViewData($key, $value) {

        $this->view_data[$key]=$value;
    }
 
    public function  getViewData($key, $args) {

        if(isset($this->view_data[$key])) {
            $data=$this->view_data[$key];
        } else {

            return null;
        }
        foreach ($args as $k=>$v) {

            if(is_integer($k)) {
                if (isset($data[$v])) {

                    $data = $data[$v];
                } else {
                    return null;
                }

            } else {
                throw new Exception("try to get view data with not supported parameters");
            }

        }
        return $data;
    }
 
    /**
     * The privilege level required to take action
     *
     * @access public
     */
    public function  getLevel() {

        if (isset($this->_level)) {
            return $this->_level;
        } else {

            $level = PtConfig::getStaticProperty(get_class($this),'level');
            if ($level !== null ) {

                return $level;
            }
        }
        return 0;// default level, should this need to get from PtConfig?

    }   
}
 
abstract class PtView extends PtComponent {
 
    /**
     * The action of the view for
     *
     * @access public
     */

    var $action;
    var $module;
 
    /**
     * the view id, use to cache
     */
    var $viewId;

 
    /**
     * get view data
     */
    public function getData() {
        $args = func_get_args();
        $key = array_shift($args);
        return $this->action->getViewData($key, $args);
    }

 
    /**
     * get view data with default value
     *
     */
    public function getDataDefault() {
        $args = func_get_args();
        $key = array_shift($args);
        $default = array_shift($args);
        $data=$this->action->getViewData($key, $args);
        if (isset($data)) {

            return $data;
        } else {
            return $default;
        }

    }
 
    /**
     * the main function to display the view
     */
     public function display () {

 
    }
}
 
/**
 * PtController
 *
 * base class of all controller.
 */
class PtController extends PtComponent {

 
    /**
     * The content filters.
     *
     * @access protected
     * @var    array
     */
    protected $_filters = array();
    protected $options;
 
    /**
     * register filters
     *
     * @access public
     * @param  mixed  $filter  the filter
     */

    function registerFilter(&$filter) {
        $this->_filters[] =& $filter;
    }

 
    /**
     * The main and door funciton of a controller
     * This follow to process which take module run and which then take action run
     */
    public function run() {
        foreach ($this->_filters as $filter) {

            $filter->preFilter();
        }
        try {
            $this->process();
        } catch (Exception $e) {

            echo $e->getMessage();
        }        
        foreach (array_reverse($this->_filters) as $filter) {

            $filter->postFilter();
        }
    }
 
    /**
     * The main proces function
     */
    public function process() {

        $options =& PtConfig::getStaticProperty(get_class($this), 'options');
        $do = getValue($options, 'modaction_url', 'do');
        $action = getValue($_REQUEST, $do, '');
        if (strlen($action) == 0) {

            $action = PtConfig::getStaticProperty(get_class($this), 'default_action');
        }
        if (strpos($action, ':') != false) {

            list( $moduleName, $remaction ) = explode(':', $action);
        } else {

            $moduleName=getValue($options, "default_module", "PtModule");
            $remaction=$action;
        }

        $module = &$this->loadModule($moduleName);
        $module->initialize();
        $module->run($remaction);
    }

 
    /**
     * load module by module name use config or default
     */
    protected function loadModule($moduleName) {
        $map = &PtConfig::getStaticProperty(get_class($this), 'module_map');
        $moduleName = getValue($map, $moduleName, $moduleName);
        $module =& PtModule::factory($moduleName);
        $module->supcontroller = &$this;
        return $module;
    }

 
    /**
     * abort, the more action can be done such as components dispose.
     */
    public function abort() {//do some more to abort.
        exit();
    }

 
    /**
     * redirect to other url, then abort
     */
    public function redirect( $url ) {

        header( 'Location: ' . $url );
        $this->abort();
    }

 
    /**
     * get full url by module:action
     */
    public function getUrl($modaction) {
        $options = PtConfig::getStaticProperty(get_class($this), 'options');
        $do = getValue($options, 'modaction_url', 'do');
        return  'http://'.$_SERVER['SERVER_NAME'].$_SERVER["SCRIPT_NAME"] . '?'.$do

            .'='.$modaction;
    }
 
    /**
     * redirect to do a module:action
     */
    public function transfer($modaction) {

        $options = PtConfig::getStaticProperty(get_class($this), 'options');
        $do = getValue($options, 'modaction_url', 'do');
        $this->redirect($this->getUrl($modaction));
    }

 
}
 
 
/**
 * PtModule
 *
 * Base class of all Module.
 */
class PtModule extends PtController { // yes, a module is a controller!

 
    /**
     * The controller which call this module.
     *
     * @access public
     * @var    mixed  Controller
     */
    var $supcontroller = null;
 
    /**
     * The module name
     */
    var $name;

 
    var $user;
 
    /**
     * check action's privilege and current user's privilege
     */
    public function isCanRun($action) {

        $level = $this->getActionLevel($action);
        $ulevel = $this->getCurLevel();
        if ($ulevel < 0 || $level < 0) return false;
        if ($ulevel >= $level ) {

            return true;
        } else {
            return false;
        }

    }
 
    /**
     * get action privilege level
     */
    public function getActionLevel($action) {

        $levels = PtConfig::getStaticProperty(get_class($this), 'levels');
        if ( !isset($levels) ) {

            $level = 0;
        } else {
            $level = getValue($levels, $action, 0);
        }

        return $level;
    }
 
    public function getCurLevel() {

        if (isset($_SESSION['USER'])) {
            $ulevel = getValue($_SESSION['USER'], 'level', 0);
        } else {

            $ulevel = 0;
        }
        return $ulevel;
    }
 
    public function isAuthed($action) {

        if ($this->isCanRun($action)) {
            return true;
        }

        return false;
    }
 
    /**
     * The main function to process action as module part.
     *
     * First load check auth, load action, initialize it, and take
     * action run, then from the result get the proper view by config
     * or default, display the view's content
     *
     * @param string $action
     */
    public function run($action) {

        $user = new PtUser();
        $user->privilege = 0;
        $user->getSession();
        $this->user=&$user;
        if (strlen($action) == 0) {

            $action = PtConfig::getStaticProperty(get_class($this), 'default_action');
        }
        if (strlen($action) == 0) {

            throw new Exception("nothing to do, please set 'default_action'");
        }
        if (!$this->isAuthed($action)) {

            throw new Exception('not authed, failed at moudle.');
        }
        $this->controller = &$this->supcontroller;// if not reset by command initialize

        $command = &$this->loadAction($action);
        $command->initialize();
        $result = $command->run($action);
        if (strlen($result) == 0) {

            $result = 'success';
        }
        $view = &$this->loadView($command, $action, $result);
        $view->initialize();
        $view->display();
        //var_dump($_SESSION);

    }
 
    /**
     * load action class
     */
    public function loadAction($action) {

        $map = &PtConfig::getStaticProperty(get_class($this), 'action_map');
        if(isset($map[$action])) {

            $action = getValue($map[$action], 'action', $action);
        } 
        $command =& $this->doLoadAction($action);
        $command->module = &$this;
        return $command;
    }

 
    protected function doLoadAction($action) {
        $options = &PtConfig::getStaticProperty(get_class($this), 'options');
        $actionName = getValue($options, 'action_name_prefix', 'Action_').$action;
        $actiondir = getValue($options, 'action_dir',
                              'module'.DIRECTORY_SEPARATOR.$this->name

                              .DIRECTORY_SEPARATOR.'action'.DIRECTORY_SEPARATOR);
        $actionbasedir = getValue($options, 'action_base_dir', PT_BASE_ROOT);
        if (class_exists($actionName, false) ||
            @include_once $actionbasedir.$actiondir.$actionName.".php") {

            if (class_exists($actionName, false)) {
                if(!is_subclass_of($actionName, 'PtAction')){

                    throw new Exception("'$action' not a valid action");
                }
                $command=new $actionName;
                return $command;
            } else {

                throw new Exception("action '$action's Class not found");
            }
        } else {

            throw new Exception("action '$action's file not found");
        }
    }
 
 
    /**
     * load view class
     */

     public function loadView(&$command, $action, $result) {
        $actionmap = &PtConfig::getStaticProperty(get_class($this), 'action_map');
        $viewName = $action;
        if (isset($actionmap[$action])) {

            if (isset($actionmap[$action]['view'][$result]) ) {

                $viewName = $actionmap[$action]['view'][$result];
            } else {

                $viewName = $actionmape[$action];
            }
        }
        $viewName = getValue($options, 'view_name_prefix', 'View_').$viewName;
        $viewdir = getValue($options, 'view_dir',
                            'module'.DIRECTORY_SEPARATOR.$this->name

                            .DIRECTORY_SEPARATOR.'view'.DIRECTORY_SEPARATOR);
        $viewbasedir = getValue($options, 'view_base_dir', PT_BASE_ROOT);
        if (class_exists($viewName, false) ||
            @include_once $viewbasedir.$viewdir.$viewName.".php") {

            if (class_exists($viewName, false)) {
                if (!is_subclass_of($viewName, 'PtView')) {

                    throw new Exception("action '$action' with result '$result' has not a valid view");
                }
                $view=new $viewName;
            } else {

                throw new Exception("view '$viewName's Class not found");
            }
        } else {

            throw new Exception("view '$viewName's file not found");
        }
        $view->action=&$command;
        $view->module=&$this;
        return $view;
    }

 
    /**
     * Singleton function, get the singleton instance. Usually this
     * should be called after factory has load the class file.
     * 
     * @access public
     * @return PtModule a instance of PtModule
     */
    public static function &singleton($className, $name){

        if (!class_exists($className, false)) {
            throw new Exception("'$className' not a valid module or not found.");
        }

        if ($className!=__CLASS__ && !is_subclass_of($className, __CLASS__)){

            throw new Exception("class '$className' not a module");
        }
        if (!$name) {

            $name=$className;
        }
        if (isset($GLOBALS['_PtMoulde_SINGLETON'][$name])) {

            if ($GLOBALS['_PtMoulde_SINGLETON'][$name] instanceof $className) {

                return $GLOBALS['_PtMoulde_SINGLETON'][$name];
            } else {

                throw new Exception("the module $name is not a $className");
            }
        }
        $module=new $className;
        $GLOBALS['_PtMoulde_SINGLETON'][$name]=&$module;
        $module->name=$name;
        return $module;
    }

 
    public function __clone() {
        trigger_error('Moulde Clone is not allowed.', E_USER_ERROR);
    }

 
    /**
     * Try to load the $name module, and return a instance.  A
     * sub-module who wants to has it's own factory, should overload
     * this function, since the __CLASS__ is hardcoded.
     *
     * @access public
     * @param  string $name
     * @param  mixed  $param
     * @return PtModule a instance of PtModule if success, or throw PtInvalidModuleException
     */
    public static function factory($name) {

        if($name == __CLASS__) {
            return self::singleton($name, $name);
        }

        $options = &PtConfig::getStaticProperty(__CLASS__, "options");
        $moduledir = getValue($options, 'module_dir', 'module'.DIRECTORY_SEPARATOR);
        $modulebasedir = getValue($options, 'module_base_dir', PT_BASE_ROOT);
        $className = getValue($options, 'class_name_prefix', "Module_").$name;
        $moduledir = $modulebasedir.$moduledir;
        return self::_in_factory($name, $className, $moduledir);
    }

 
    protected static function  _in_factory($name, $className, $moduledir) {

        if (class_exists($className, false) ||
            @include_once $moduledir.$name.".php"){

            $module= &self::singleton($className, $name);
        } else {

            throw new Exception("Module '$name's file '${moduledir}${name}' not found");
        }
        return $module;
    }

}
 
?>

LaTeX Source2e

ltsect.dtx

\title, \author, \date, \thanks, \and, \maketitle, \title

\@secpenalty 节分页惩罚值.

\@startsection \@startsection{ name }{ level }{ indent }{ beforeskip }{ afterskip }{ style }*[ altheading ]{ heading }

name 节名, 例如 subsection.

level 节深, 例如, chapter=1, section=2.

indent 左缩进.

beforeskip 绝对值为节头上距, 如果为负, 节后段落缩进被禁.

afterskip 正值为节头下距, 负值为节右距.

style节头样式, 例 \bfseries\MakeUppercase.

\@seccntformat 格式化节号.

\if@afterindent 节后段落是否缩进, 可以通过 \let\@afterindentfalse\@afterindenttrue 来使首段落缩进, 更符合中文习惯.

\@afterheading 定制节头钩子.

\@hangfrom 竖直模式, 挂起缩进.

\c@secnumdepth, \c@tocdepth 节目深度和目录深度.

\secdef \secdef{\STARCMD}{\UNSTARCMD}

\sectionmark, \subsectionmark, \subsubsectionmark, \paragraphmark, \subparagraphmark 页面样式用, 如页眉, 页脚.

\@starttoc 打开辅助文件.

\addcontentsline \addcontentsline{ table }{ type }{ entry } 向 jobname.table 中添加.

\addtocontents \addtocontents{ table }{ text } .

\contentsline \contentsline{ type }{ entry }{ page }

\@dottedtocline \@dottedtocline{ level }{ indent }{ numwidth }{ title }{ page }

\numberline\contentsline 中使用, 将数字左对齐放在宽为 \@tempdima 的盒子里.

ltfloat.dtx

ltidxglo.dtx

ltbibl.dtx

ltpage.dtx

\pagestyle \pagestyle{ style }, 利用 \ps@stylename 设置相应页面.

\@oddhead, \@oddfoot, \@evenhead, \@evenfoot 在页面样式里定义.

\thispagestyle 当前页面样式.

\raggedbottom

\flushbottom

\sloppy

\sloppypar

\fussy

\overfullrule

ltoutput.dtx

页面布局参数 : \topmargin \oddsidemargin \evensidemargin \headheight \headsep \footskip \textheight \textwidth \columnsep \columnseprule \columnwidth

\@textbottom, \@texttop 执行于页面盒子的底部和顶部的宏.

页面样式参数: \floatsep \textfloatsep \topfigrule \botfigrule \intextsep \dblfloatsep \dbltextfloatsep \dblfigrule \@fptop \@fpsep \@fpbot \@dblfptop, \@dblfpsep, \@dblfpbot

\@oddhead, \@evenhead, \@oddfoot, \@evenfoot 页眉页脚的宏.

\@specialstyle 特殊样式?

....

ltclass.dtx

lthyphen.dtx

ltfinal.dtx

LaTeX Source2e

ltlogos.dtx

\TeX, \LaTeX, \LaTeXe

ltfiles.dtx

\IfFileExists, \InputIfFileExists

ltoutenc.dtx

.... ... .. .

ltcounts.dtx

\newcounter \setcounter \addtocounter \stepcounter \refstepcounter \value \arabic \roman \Roman \alph \Alph \fnsymbol

\@addtoreset

ltlength.dtx

\newlength \setlength \addtolength \settowidth \settoheight \settodepth \newlength \setlength \addtolength \settoheight \settodepth \settowidth

ltfssbas.dtx

.... ... .. .

ltfsstrc.dtx

.... ... .. .

ltfsscmp.dtx

.... ... .. .

ltfssdcl.dtx

ltfssini.dtx

fontdef.dtx

preload.dtx

ltfntcmd.dtx

ltpageno.dtx

\pagenumbering

ltxref.dtx

ltmiscen.dtx

ltmath.dtx

ltlists.dtx

ltboxes.dtx

lttab.dtx

ltpictur.dtx

ltthm.dtx