Archive

Archive for the ‘Code’ Category

Status Press Widget

December 23rd, 2009 Brian No comments

I’ve been playing around a bit with Status Press Widget by Brian D. Goad.

I found that the data it fetched also showed the nick-/username which I think is kinda redundant so I modified the plugin a bit to let me manage it from the admin interface. While at it I also modified so URL’s are made clickable and cleaned up the code a bit.

Here’s the modified status-press-widget.php file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
<?php
/*
Plugin Name: Status Press Widget
Plugin URI: http://www.briandgoad.com/blog/status-press-widget/
Description: Adds a Widget to display your Facebook/Twitter/Last.FM/Pownce status in your sidebar.
Version: 1.14
Author: Brian D. Goad
Author URI: http://www.briandgoad.com/blog
*/

/*  
    Copyright 2008  Brian D. Goad  (email : bdgoad@gmail.com)
            & Adam Walker Cleaveland &  C. Scott Andreas,
            Authors of the original Status Press Plugin

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

if (!function_exists("htmlspecialchars_decode")) {
    function htmlspecialchars_decode($string,$style=ENT_COMPAT){
        $translation = array_flip(get_html_translation_table(HTML_SPECIALCHARS,$style));
        if ($style === ENT_QUOTES) {
            $translation['&#039;'] = '\'';
        }
        return strtr($string,$translation);
    }
}

class SPWidget {
    //Set Defaults
    var $default_options = array(
        'title' => "",
        'social' => "",
        'url' => "",
        'num' => "1",
        'status_mods' => "",
        'show_time' => 1,
        'time_mods' => ""
    );

    var $o;
   
    function SPWidget() {}

    //Begin By Checking to See if Widget Can Exist
    function init() {
        if (!function_exists('register_sidebar_widget')) {
            return;
        }
        if (!$options = get_option('widget_status_press')) {
            $options = array();
        }
        $widget_ops = array('classname' => 'widget_status_press', 'description' => 'Add a Social Status to your sidebar');
        $control_ops = array('width' => 200, 'height' => 350, 'id_base' => 'status_press');
        $name = 'Status Press';
        $registered = false;

        //Register Widgets
        foreach (array_keys($options) as $o) {
            if (!isset($options[$o]['title'])) {
                continue;
            }
            $id = "status_press-$o";
            $registered = true;
            wp_register_sidebar_widget($id, $name, array(&$this, 'widget'), $widget_ops, array( 'number' => $o ) );
            wp_register_widget_control($id, $name, array(&$this, 'control'), $control_ops, array( 'number' => $o ) );
        }
        if (!$registered) {
            wp_register_sidebar_widget('status_press-1', $name, array(&$this, 'widget'), $widget_ops, array( 'number' => -1 ) );
            wp_register_widget_control('status_press-1', $name, array(&$this, 'control'), $control_ops, array( 'number' => -1 ) );
        }
    }

    function widget($args, $widget_args = 1) {
        //Retrieve Any Arguments
        extract($args);

        if (is_numeric($widget_args)) {
            $widget_args = array('number' => $widget_args);
        }

        $widget_args = wp_parse_args($widget_args, array( 'number' => -1 ));
        extract($widget_args, EXTR_SKIP);
       
        //Get Options Saved in Control
        $options_all = get_option('widget_status_press');

        if (!isset($options_all[$number])) {
            return;
        }

        $this->o = $options_all[$number];
        //Set Temp Values (in case they have changed)
        $title = htmlspecialchars($this->o['title'], ENT_QUOTES);
        $url = $this->o['url'];
        $num = htmlspecialchars($this->o['num'], ENT_NOQUOTES);
        $status_mods = htmlspecialchars_decode($this->o['status_mods'], ENT_QUOTES);
        $show_time = $this->o['show_time'];
        $show_nick = $this->o['show_nick'];
        $time_mods = htmlspecialchars_decode($this->o['time_mods'], ENT_QUOTES);
        //Begin Status Press Functions

        require_once (ABSPATH . WPINC . '/rss.php');
       
        if ($url == '' ) {
            if ($title == '') {
                $title = 'Status Press';
            }
            $disp .= '<p>You Must Supply the URL to your Facebook Status RSS Feed </p>';
        } else {
            //Adjust cache setting
            if ( !defined('MAGPIE_CACHE_AGE') ) {
                define('MAGPIE_CACHE_AGE', 5*60); // five minutes
            }
            $rss = fetch_rss($url);
            if($rss) {
                if ($title == '') {
                    $title = $rss->channel[title];
                }
                if ($num > 0) {
                    $rss->items = array_slice($rss->items, 0, $num);
                }
                foreach($rss->items as $item) {
                    //Get Status Text
                    $status = $item[title];
                    if ($status != '') {
                        // Removes the nick in front of status text and makes any URL's into clickable links.
                        if (!$show_nick) {
                            $status = trim(substr($status, stripos($status, ':')+1));
                        }
                        $status = make_clickable($status);
                        $disp .= "\t<p " . $status_mods . ">" . $status;
                        if ($show_time) {
                            // Get the date + time of the last update from the RSS feed.
                            $pubdate = $item[pubdate];
                            // Convert this string to a time.
                            $pubdate = strtotime($pubdate);
                            // Calculate how long it's been since the status was updated.
                            $today = time();
                            $difference = $today - $pubdate;
                            // Display how long it's been since the last update.
                            $disp .= "</p><p ". $time_mods . ">(Updated ";
                            // Show days if it's been more than a day.
                            if (floor($difference / 86400) > 0) {
                                $disp .= floor($difference / 86400);
                                if (floor($difference / 86400) == 1) {
                                    $disp .= ' day, ';
                                } else {
                                    $disp .= ' days, ';
                                }
                                $difference -= 86400 * floor($difference / 86400);
                            }
                            // Show hours if it's been more than an hour.
                            if (floor($difference / 3600) > 0) {
                                $disp .= floor($difference / 3600);
                                if (floor($difference / 3600) == 1) {
                                    $disp .= ' hour, ';
                                } else {
                                    $disp .= ' hours, ';
                                }
                                $difference -= 3600 * floor($difference / 3600);
                            }
                            // Show minutes if it's been more than a minute.
                            $disp .= floor($difference / 60);
                            $difference -= 60 * floor($difference / 60);
                            if (floor($difference / 60) == 1) {
                                $disp .= ' minute, ';
                            } else {
                                $disp .= ' minutes ago)';
                            }
                        }
                        $disp .= "</p>\n";
                    }
                }
            } else {
                if ($title == '') {
                    $title = "Status Press";
                }
                $disp .= "\t<p>Status Press Error: Something bad happened! <br /> Here are the variables you entered: <ul><li> Title:".$title."</li><li>URL:".$url."</li><li>Number:".$num."</li><li>RSS: ".$rss."\t</li></ul></p>\n";
            }
        }
        //Call Widget
?>
                <?php echo $before_widget; ?>
                <?php echo $before_title . $title . $after_title; ?>

                <div>
                    <?php echo $disp; // Display Widget Content ?>
                </div>

                <?php echo $after_widget; ?>
<?php  
    }
    function control($widget_args = 1) {
        global $wp_registered_widgets;
        static $updated = false;
        if (is_numeric($widget_args)) {
            $widget_args = array('number' => $widget_args);
        }
        $widget_args = wp_parse_args($widget_args, array('number' => -1));
        extract($widget_args, EXTR_SKIP);
        $options_all = get_option('widget_status_press');
        if (!is_array($options_all)) {
            $options_all = array();
        }
        if (!$updated && !empty($_POST['sidebar'])) {
            $sidebar = (string)$_POST['sidebar'];
            $sidebars_widgets = wp_get_sidebars_widgets();
            if (isset($sidebars_widgets[$sidebar])) {
                $this_sidebar =& $sidebars_widgets[$sidebar];
            } else {
                $this_sidebar = array();
            }
            foreach ($this_sidebar as $_widget_id) {
                if ('widget_status_press' == $wp_registered_widgets[$_widget_id]['callback'] && isset($wp_registered_widgets[$_widget_id]['params'][0]['number'])) {
                    $widget_number = $wp_registered_widgets[$_widget_id]['params'][0]['number'];
                    if (!in_array("status_press-$widget_number", $_POST['widget-id'])) {
                        unset($options_all[$widget_number]);
                    }
                }
            }
            foreach ((array)$_POST['status_press'] as $widget_number => $posted) {
                if (!isset($posted['title']) && isset($options_all[$widget_number])) {
                    continue;
                }
                $options = array();
                $options['title'] = strip_tags(stripslashes($posted['title']));
                $options['social'] = $posted['social'];
                $options['url'] = sanitize_url(strip_tags($posted['url']));
                $options['show_nick'] = $posted['show_nick'];
                $options['num'] = intval($posted['num']);
                $options['status_mods'] = strip_tags(stripslashes($posted['status_mods']));
                $options['show_time'] = isset($posted['show_time']);
                $options['time_mods'] = strip_tags(stripslashes($posted['time_mods']));
                $options_all[$widget_number] = $options;
            }
            update_option('widget_status_press', $options_all);
            $updated = true;
        }
        if (-1 == $number) {
            $wpnm = '%i%';
            $values = $this->default_options;
        } else {
            update_option('widget_status_press', $options_all);
            $wpnm = $number;
            $values = $options_all[$number];
        }

        //Show Admin Screen
?>
        <p style="text-align:left;">
            <label for="status_press-title"><?php _e('Title (Leave Blank to Pull Title From Feed):', 'status-press-widget'); ?></label><br />
            <input style="width: 200px;" id="status_press-title" name="status_press[<?php echo $wpnm; ?>][title]" type="text" value="<?php echo htmlspecialchars($values['title'], ENT_QUOTES); ?>" />
        </p>
        <script language="javascript">
            function rss(social) {
                actSocial = social.value;
                var txtUrl = document.getElementById("status_press-url[<?php echo $wpnm; ?>]")
                function getUserName(actSocial) {
                    do {
                        var name = prompt("Please input your " + actSocial + " username here:", "");
                    } while (name == "");
                    if (name!=null && name!="") {
                        return name;
                    } else {
                        social.selectedIndex = 0;
                    }
                }
                switch (actSocial) {
                    case "Facebook":
                        okFB = confirm('Please ensure that you are already logged in to Facebook.');
                        if (okFB) {
                            alert('On the following page, please find the My Status RSS feed and copy it into the box below.');
                            window.open("http://www.facebook.com/minifeed.php?filter=11");
                        }
                    break;
                    case "Twitter":
                        name = getUserName(actSocial);
                        if (name != null) {
                            txtUrl.value = "http://twitter.com/statuses/user_timeline/" + name + ".rss";
                        }
                    break;
                    case "Last.FM":
                        name = getUserName(actSocial);
                        if (name != null) {
                            txtUrl.value = "http://ws.audioscrobbler.com/1.0/user/" + name + "/recenttracks.rss";
                        }
                    break;
                }
            }
            function showHide(that, element) {
                e = document.getElementById(element);
                if (that.checked) {
                    e.style.visibility = "visible";
                } else {
                    e.style.visibility = "hidden";
                }
            }
            //showHide(document.getElementById("status_press-show_time[<? echo $wpnm; ?>]"), "status_press-time_mods[<? echo $wpnm; ?>]"); 
        </script>

        <p style="text-align:left;">
            <span style="vertical-align: bottom;"><?php _e('Social Status Network:  ', 'status-press-widget'); ?></span>
            <select name="status_press[<?php echo $wpnm; ?>][social]" id="status_press-social" onchange="rss(this)">
                <option value=""<?php if($values['social'] == '') echo ' selected="selected"'; ?>></option>
                <option value="Facebook"<?php if($values['social'] == "Facebook") echo ' selected="selected"'; ?>><?php _e('Facebook', 'status-press-widget'); ?></option>
                <option value="Twitter"<?php if($values['social'] == "Twitter") echo ' selected="selected"'; ?>><?php _e('Twitter', 'status-press-widget'); ?></option>
                <option value="Last.FM"<?php if($values['social'] == "Last.FM") echo ' selected="selected"'; ?>><?php _e('Last.FM', 'status-press-widget'); ?></option>
            </select>
        </p>
        <p>
            <label for="status_press-url[<?php echo $wpnm; ?>]"><?php _e('Status URL Feed:', 'status-press-widget'); ?></label><br />
            <input style="width: 230px;" id="status_press-url[<?php echo $wpnm; ?>]" name="status_press[<?php echo $wpnm; ?>][url]" type="text" value="<?php echo $values['url']; ?>" />
        </p>
        <p><?php if($values['show_nick']) $values['show_nick'] = ' checked="checked"';?>
            <label for="status_press-show_nick"><?php _e( 'Show nick-/username: ', 'status-press-widget'); ?></label>
            <input type="checkbox" class="checkbox" id="status_press-show_nick[<?php echo $wpnm; ?>]" name="status_press[<?php echo $wpnm; ?>][show_nick]"<?php echo $values['show_nick']; ?> />
        </p>
        <p style="text-align:left;">
            <label for="status_press-num"><?php _e('Number of Status Feeds to Display <br/>(Use "0" to display All):', 'status-press-widget'); ?></label><br />
            <input style="width: 20px;" id="status_press-num" name="status_press[<?php echo $wpnm; ?>][num]" type="text" value="<?php echo htmlspecialchars($values['num'], ENT_NOQUOTES); ?>" />
        </p>
        <p style="text-align:left;">
            <label for="status_press-status_mods"><?php _e('Stylizing Modifications for Status Tags<br/>(i.e. id="status_press", etc):', 'status-press-widget'); ?></label><br />
            <input style="width: 230px;" id="status_press-status_mods" name="status_press[<?php echo $wpnm; ?>][status_mods]" type="text" value="<?php echo htmlspecialchars($values['status_mods'], ENT_QUOTES); ?>" />
        </p>
        <p><?php if($values['show_time']) $values['show_time'] = ' checked="checked"'; ?>
            <label for="status_press-show_time"><?php _e( 'Show Time Since Status Update: ', 'status-press-widget'); ?></label>
            <input type="checkbox" class="checkbox" id="status_press-show_time[<?php echo $wpnm; ?>]" name="status_press[<?php echo $wpnm; ?>][show_time]" onClick="showHide(this, \'status_press-time_mods[<?php echo $wpnm; ?>]\')"<?php echo $values['show_time']; ?> />
        </p>
        <p style="text-align:left;" id="status_press-time_mods[<?php echo $wpnm; ?>]">
            <label for="status_press-time_mods[<?php echo $wpnm; ?>]"><?php _e('Stylizing Modifications for Time Since Tags <br/>(i.e. id="status-time", etc):', 'status-press-widget'); ?></label><br />
            <input style="width: 230px;" id="status_press-time_mods[<?php echo $wpnm; ?>]" name="status_press[<?php echo $wpnm; ?>][time_mods]" type="text" value="<?php echo htmlspecialchars($values['time_mods'], ENT_QUOTES); ?>" />
        </p>
        <input type="hidden" id="status_press-submit" name="status_press[<?php echo $wpnm; ?>][submit]" value="1" />
<?php
    }
}
$spw = new SPWidget();
//Initialize Widget on Run
add_action('widgets_init', array($spw, 'init'));

?>
Categories: Blog, PHP Tags: , ,

mirc.php for GeSHi

December 12th, 2007 Brian 1 comment

Seems there were a minor issue with the mirc.php file from GeSHi causing all code entries set to be parsed as mIRC scripts to stop with an error. Fixed (or rather made a dirty hack) it so my mIRC scripts once again could be highlighted :)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/*************************************************************************************
* mirc.php
* -----
* Author: Alberto 'Birckin' de Areba (Birckin@hotmail.com)
* Copyright: (c) 2006 Alberto de Areba
* Release Version: 1.0.7.20
* Date Started: 2006/05/29
*
* mIRC Scripting language file for GeSHi.
*
* CHANGES
* -------
* 2006/05/29 (1.0.0)
*   -  First Release
*
* 2007/12/12 (1.0.1) - Brian Schmidt Pedersen
*   -  Removed the forward slash from all mIRC keywords, since in actual
*       mIRC scripts, they're often written without the slash.
*   -  Entry 6 (timer parsing) under REGEXPS caused GeSHi to halt with an error
*       simple solution was to remove the slash(es)
*
*************************************************************************************
*
*     This file is part of GeSHi.
*
*   GeSHi is free software; you can redistribute it and/or modify
*   it under the terms of the GNU General Public License as published by
*   the Free Software Foundation; either version 2 of the License, or
*   (at your option) any later version.
*
*   GeSHi is distributed in the hope that it will be useful,
*   but WITHOUT ANY WARRANTY; without even the implied warranty of
*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*   GNU General Public License for more details.
*
*   You should have received a copy of the GNU General Public License
*   along with GeSHi; if not, write to the Free Software
*   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*
************************************************************************************/


$language_data = array (
'LANG_NAME' =&gt; 'mIRC Scripting',
'COMMENT_SINGLE' =&gt; array(1 =&gt; ';'),
'COMMENT_MULTI' =&gt; array(),
'CASE_KEYWORDS' =&gt; GESHI_CAPS_NO_CHANGE,
'QUOTEMARKS' =&gt; array(),
'ESCAPE_CHAR' =&gt; '',
'KEYWORDS' =&gt; array(
1 =&gt; array(
'alias', 'menu', 'dialog'
),
2 =&gt; array(
'if', 'elseif', 'else', 'while', 'return', 'goto'
),
3 =&gt; array(
'action', 'ajinvite', 'alias', 'aline', 'amsg', 'ame', 'anick', 'aop',
'auser', 'avoice', 'auto', 'autojoin', 'away', 'background', 'ban',
'beep', 'channel', 'clear', 'clearall', 'clipboard', 'close',
'closemsg', 'color', 'copy', 'creq', 'ctcp', 'ctcpreply', 'ctcps',
'dcc', 'dde', 'ddeserver', 'debug', 'describe', 'disable',
'disconnect', 'dlevel', 'dll', 'dns', 'dqwindow', 'ebeeps', 'echo',
'editbox', 'emailaddr', 'enable', 'events', 'exit', 'filter',
'findtext', 'finger', 'flash', 'flood', 'flush', 'flushini',
'font', 'fsend', 'fserve', 'fullname', 'ghide', 'gload', 'gmove',
'gopts', 'gplay', 'gpoint', 'gqreq', 'groups', 'gshow', 'gsize',
'gstop', 'gtalk', 'gunload', 'guser', 'halt', 'haltdef', 'help', 'hop', 'ignore',
'inc', 'invite', 'join', 'kick', 'linesep', 'links', 'list', 'load',
'loadbuf', 'localinfo', 'log', 'me', 'mdi', 'mkdir', 'mnick',
'mode', 'msg', 'names', 'nick', 'noop', 'notice', 'notify',
'omsg', 'onotice', 'part', 'partall', 'pdcc', 'perform', 'ping',
'play', 'pop', 'protect', 'pvoice', 'qmsg', 'qme', 'query',
'queryrn', 'quit', 'raw', 'remini', 'remote', 'remove', 'rename',
'renwin', 'resetidle', 'rlevel', 'rmdir', 'run', 'ruser', 'save',
'savebuf', 'save', 'saveini', 'say', 'server', 'set', 'showmirc', 'sline',
'sound', 'speak', 'splay', 'sreq', 'strip', 'time',
'timers', 'timestamp', 'titlebar', 'tnick', 'tokenize', 'topic',
'ulist', 'unload', 'updatenl', 'url', 'uwho', 'var', 'window', 'winhelp',
'write', 'writeini', 'who', 'whois', 'whowas'
)
),
'SYMBOLS' =&gt; array(
'(', ')', '{', '}', '[', ']', '|'
),
'CASE_SENSITIVE' =&gt; array(
GESHI_COMMENTS =&gt; true,
1 =&gt; false,
2 =&gt; false
),
'STYLES' =&gt; array(
'KEYWORDS' =&gt; array(
1 =&gt; 'color: #994444;',
2 =&gt; 'color: #000000; font-weight: bold;',
3 =&gt; 'color: #990000; font-weight: bold;'
),
'COMMENTS' =&gt; array(
1 =&gt; 'color: #808080; font-style: italic;'
),
'ESCAPE_CHAR' =&gt; array(),
'BRACKETS' =&gt; array(
0 =&gt; 'color: #FF0000;'
),
'STRINGS' =&gt; array(),
'NUMBERS' =&gt; array(
0 =&gt; ''
),
'METHODS' =&gt; array(),
'SYMBOLS' =&gt; array(
0 =&gt; 'color: #FF0000;'
),
'REGEXPS' =&gt; array(
0 =&gt; 'color: #000099;',
1 =&gt; 'color: #990000;',
2 =&gt; 'color: #888800;',
3 =&gt; 'color: #888800;',
4 =&gt; 'color: #000099;',
5 =&gt; 'color: #000099;',
6 =&gt; 'color: #990000; font-weight: bold;'
),
'SCRIPT' =&gt; array()
),
'URLS' =&gt; array(
1 =&gt; '',
2 =&gt; '',
3 =&gt; '',
4 =&gt; ''
),
'OOLANG' =&gt; false,
'OBJECT_SPLITTERS' =&gt; array(),
'REGEXPS' =&gt; array(
0 =&gt; '\$[^$][^ ,\(\)]*',
1 =&gt; '(%|&amp;).+?[^ ,\)]*',
2 =&gt; '(#|@).+?[^ ,\)]*',
3 =&gt; '-[a-z\d]+',
4 =&gt; '(on|ctcp) (!|@|&amp;)?(\d|\*):[a-zA-Z]+:',
/*
4 =&gt; array(
GESHI_SEARCH =&gt; '((on|ctcp) (!|@|&amp;)?(\d|\*):(Action|Active|Agent|AppActive|Ban|Chat|Close|Connect|Ctcp|CtcpReply|DccServer|DeHelp|DeOp|DeVoice|Dialog|Dns|Error|Exit|FileRcvd|FileSent|GetFail|Help|Hotlink|Input|Invite|Join|KeyDown|KeyUp|Kick|Load|Logon|MidiEnd|Mode|Mp3End|Nick|NoSound|Notice|Notify|Op|Open|Part|Ping|Pong|PlayEnd|Quit|Raw|RawMode|SendFail|Serv|ServerMode|ServerOp|Signal|Snotice|Start|Text|Topic|UnBan|Unload|Unotify|User|Mode|Voice|Wallops|WaveEnd):)',
GESHI_REPLACE =&gt; '\\1',
GESHI_MODIFIERS =&gt; 'i',
GESHI_BEFORE =&gt; '',
GESHI_AFTER =&gt; ''
),
*/

5 =&gt; 'raw (\d|\*):',
6 =&gt; 'timer(?!s\b)[0-9a-zA-Z_]+'
),
'STRICT_MODE_APPLIES' =&gt; GESHI_NEVER,
'SCRIPT_DELIMITERS' =&gt; array(),
'HIGHLIGHT_STRICT_BLOCK' =&gt; array()
);
?&gt;
Categories: Code, PHP, mIRC Tags: , , ,

Lots of updates

June 20th, 2007 Brian No comments

I recently switched host from Surftown.dk to Servage.net, mostly just to check Servage out, but also because I know the owner and one of the admins.

So far I must say I’m a bit disappointed. The administration panel isn’t as intuitive as the one I used at Surftown, but I guess I can live with it, most of the functions I had at Surftown, and lacks here at Servage, were functions I didn’t really use. Servage seems to have problems with responsiveness quite often, can’t pinpoint any specific times, it’s in periods, usually after I’ve done a lot of SQL queries, which makes me think they’re a bit too restrictive on the number of MySQL connections they allow. — Time will tell how well Servage fares, my needs aren’t big so I doubt I’ll have any great concerns.

While moving hosts I also upgrade to the latest WordPress, and made a lot of changes:

Instead of my own gallery page I decided to go with NextGEN Gallery. Has a lot of nice features, however compared to my own gallery it’s very very cumbersome to maintain. My own were just “upload files to a folder”, then the script would handle the rest the next time that folder would be browsed. The pagination, ability to add descriptions and the “effects” that comes with NGG, and also the fact that I rarely upload any pictures, makes it good for me. Made a small change though, had to make NGG add margin-top to every thumbnail, so that it would align properly within its container.

Codebin have been removed, instead I’ll just make a regular blog entry in the Code category, when adding new snippets of code. Again it’s not as easy to administrate as my previous one, but easier to maintain WordPress with updates, backups etc. A thing that bothers me hugely, is that when editing one of these code blogs, the formatting (indentation, special characters etc.) are completely screwed up due to WordPress’ handling of the text-fields, or some such.

Aah, and then I dropped my own theme, mostly because there were some quirks with the CSS that I simply couldn’t figure out, so I decided to drop it entirely. Instead I’m using a pre-made theme, which I’m modifying a bit to suit my taste and needs. Only few changes have been necessary though, mostly to the sidebar.

Categories: Blog, Code Tags: , , , , ,

calc.tcl

June 20th, 2007 Brian No comments
1
2
3
4
5
6
7
8
#### calc.tcl v1.0.1 ###########################################################
################################################################################
## Written by:                                                                ##
##   KuNgFo0  (http://www.eggfaq.com/).              ##
##                                                                            ##
## Modified by:                                                               ##
##   Brian Schmidt aka. brianMan.                                             ##
################################################################################

#### Readme / Help #############################################################
################################################################################
## This script is ripped from KuNgFoO’s ib.tcl v3.19 (infobot) script. ##
## ##
## Script that can calculate just about anything ;) ##
## ##
## Usage: ##
## To have the .calc[ulate] commands available on a channel you need to set ##
## the channel flag +calculator from the console/partyline . ##
## “.chanset #channel +calculator´´ ##
## ##
## Channel Commands (available only if channel is +convert): ##
## .calc[ulate] ##
## Example: ##
## “.calc 15*20+3´´ ##
################################################################################

#### Changelog #################################################################
################################################################################
## v1.0.1 ##
## * Minor code cleanup ##
## ##
## v1.0.0 ##
## + Initial release. ##
## * Changed the default trigger “botname, calc[ulate]´´ to “.calc[ulate]´´ ##
## + Added the possibility to control which channels could use the commands ##
## with the channel flag “+/-calculator´´ ##
################################################################################

bind pub – .calc pub_calc
bind pub – .calculate pub_calc
bind msg – calc msg_calc
bind msg – calculate msg_calc

setudef flag calculator

# You shouldn’t change these, however you may add additional variables
# These are used via %varname in the ‘calculate’ command
# Example: Mybot, calculate %pi / 2
set calc_const(pi) 3.14159265358979323846 ; # PI
set calc_const(e) 2.7182818284590452354 ; # E
set calc_const(n) 6.0221367e23 ; # Avogadro’s number [1/mol]
set calc_const(R) 8.314510 ; # Universal gas constant [J/(mol*K)]
set calc_const(k) 1.380658e-23 ; # Boltzmann’s constant [J/K]
set calc_const(G) 6.67259e-11 ; # Universal gravitational constant [N*m^2/kg^2]
set calc_const(h) 6.62606891e-34 ; # Planck’s constant [J*s]
set calc_const(c) 2.99792458e8 ; # Speed of light [m/s]

# No more editing required

proc xrange {xr xr1 xr2} {
return [join [lrange [split $xr] $xr1 $xr2]]
}

proc xindex {xr xr1} {
return [join [lrange [split $xr] $xr1 $xr1]]
}

proc calc_fixdata {arg output} {
global botnick
if {[string index $output 0] != “#”} {
regsub -all -nocase {$output’s} $arg “your” arg
}
regsub -all -nocase {$botnick’s} $arg “my” arg
return $arg
}

proc calc_msg {targets arg} {
foreach target $targets { puthelp “PRIVMSG $target :[calc_fixdata $arg $target]” }
}

proc calc_fixtopic {arg} {
regsub -all {[\\\{\}\[\]\”]} $arg {} arg ; # Bad characters
regsub -all {(\s)+} $arg {\1} arg ; # Double whitespace
regsub -all {^\s*|\s*$} $arg {} arg ; # Whitespace at ends
return $arg
}

# Begin ‘calc’ code
proc calc_fixexpr {exp} {
global calc_const
set exp [calc_fixtopic $exp]
foreach i [array names calc_const] {
regsub -all “\%$i” $exp $calc_const($i) exp
}
return $exp
}
# End ‘calc’ code

# Begin Public binds code
proc msg_calc {nick uhost hand arg} {
global botnick
pub_calc $nick $uhost $hand “” $arg
}

proc pub_calc {nick uhost hand chan arg} {
global botnick calc_flag
if {(![isbotnick $nick]) && (![matchattr $hand +b])} {
if {(![string match "$chan" ""]) && (![channel get $chan calculator])} {
return 0 ; # If command comes from a channel, and that channel doesn’t have +calculator then ignore
}
set isuser [expr {[matchattr $hand - $chan] || [matchattr $hand -]}] ; # Note that $chan might be “”, so we must handle both cases
if {([validchan $chan]) && ($isuser)} {
set output1 $chan ; # The bot sends the text to the channel for users
} else {
set output1 $nick ; # Non-users get privmsg’d
}
if {[set i [string last ">" $arg]] == -1} {
set output2 $output1 ; # By default, output2 (~stdout~) goes to output1 (~stderr~)
} else {
# Output has been redirected
if {(!$isuser) || ([set output2 [string trim [string range $arg [expr $i + 1] end] ” “]] == “”)} {
set output2 $output1 ; # Error (User doesn’t have access, or output was “”), so we go back to the default
}
set arg [string trim [string range $arg 0 [expr $i - 1]] ” “]
}
set remainder [xrange $arg 0 end]

if {$remainder == “”} {
calc_msg $output1 “error parsing sentence”
} elseif {[catch {expr [calc_fixexpr $remainder]} output]} {
calc_msg $output1 “error calculating ‘$remainder’ ($output)”
} else {
calc_msg $output2 “$remainder = $output”
}
}
}
# End Public binds code

# Init stuff
if {[catch {package require Tcl 8.2} error]} {
putlog “error TCL v8.2 or higher is required to run this script”
return 0
}

putlog “*** LOADED: calc.tcl”

Categories: Code, TCL Tags: , , ,

convert.tcl

June 20th, 2007 Brian No comments
1
2
3
4
5
6
7
8
#### convert.tcl v1.0.1 ########################################################
################################################################################
## Written by:                                                                ##
##   KuNgFo0  (http://www.eggfaq.com/).              ##
##                                                                            ##
## Modified by:                                                               ##
##   Brian Schmidt aka. brianMan.                                             ##
################################################################################

#### Readme / Help #############################################################
################################################################################
## This script is ripped from KuNgFoO’s ib.tcl v3.19 (infobot) script. ##
## ##
## The script converts between a number of various units, for more speficic ##
## information on which untis you should please refer to the source of this ##
## script. ##
## ##
## Usage: ##
## To have the .conv[ert] commands available on a channel you need to set ##
## the channel flag +convert from the console/partyline . ##
## “.chanset #channel +convert´´ ##
## ##
## Channel Commands (available only if channel is +convert): ##
## .conv[ert] to ##
## Example: ##
## “.conv 20 C to F´´ ##
## Converts 20 degrees Celcius to it’s Fahrenheit equivilant. ##
################################################################################

#### Changelog #################################################################
################################################################################
## v1.0.1 ##
## * Minor code cleanup ##
## ##
## v1.0.0 ##
## + Initial release. ##
## * Changed the default trigger “botname, conv[ert]´´ to “.con[vert]´´ ##
## + Added the possibility to control which channels could use the commands ##
## with the channel flag “+/-convert´´ ##
################################################################################

bind pub – .conv pub_conv
bind pub – .convert pub_conv
bind msg – conv msg_conv
bind msg – convert msg_conv

# Set the name of the channelflag used to tell whether the convert command is
# enabled or not for that specific channel.
set conv_channel_flag “convert”

setudef flag $conv_channel_flag

# Set the next line as the exec command to run the ‘units’ command from the shell
# Note: Not all systems will have this installed
# Set to “” to disable
set conv_units_exec “units -v”

# Conversion formulas – each array is for its own dimension (length, volume, etc).
# Each unit is converted to a standard type by multiplying the value by the factors
# below. It is then converted from the standard type to any other unit by
# dividing the factors. The standard unit used must be the same for everything in
# each dimension, and can be anything as long as they are the same. I used the root
# metric units for most things (meters, liters, grams, etc).
# Note: All strings are matched as regular expressions
# * Prefix with (?c) for units that should be case sensitive
# * Prefix with (.*?) for metric units
# * Append (?:s) for units with an optional plural ending, etc
# * Only use multiplication and division in the formulas, no addition or subtraction
# * It’s a very good idea to have all the formulas return values in decimal form
# (“1″ doesn’t matter, though)
# Syntax:
# name abbreviation factor
set conv_unit(length) {
(.*?)meter(?:s)? (.*?)m 1
inch(?:es)? in {2.54 / 100}
foot|feet ft {2.54 / 100 * 12}
mile(?:s)? mi {2.54 / 100 * 12 * 5280}
}
set conv_unit(volume) {
(.*?)liter(?:s)? (.*?)L 1
pint(?:s)? pt {3.785 / 8}
quart(?:s)? qt {3.785 / 4}
gallon(?:s)? gal 3.785
}
set conv_unit(weight) {
(.*?)gram(?:s)? (.*?)g 1
ounce(?:s)? oz 28.35
pound(?:s)? lbs 453.59
ton(?:s)? T {453.59 * 2000}
}
set conv_unit(work) {
(.*?)joule(?:s)? (.*?)J 1
(.*?)watt-?second(?:s)? (.*?)w-?s 1
(.*?)watt-?hour(?:s)? (.*?)w-?hrs 3600.0
britishthermalunit(?:s)? btu 1055.056
calorie(?:s)? cal 4.1868
foot-?pound(?:s)? ft-?lbs 1.356
electron-?volt(?:s)? eV 1.6021917E-19
}
set conv_unit(power) {
(.*?)watt(?:s)? (.*?)w 1
volt-?amp(?:s)? va 1
horsepower hp 746
}
set conv_unit(time) {
(.*?)second(?:s)? (.*?)s(?:ec(?:s)?)? 1
minute(?:s)? min(?:s)? 60.0
hour(?:s)? h(?:r(?:s)?)? {60.0 * 60}
day(?:s)? {} {60.0 * 60 * 24}
week(?:s)? wk(?:s)? {60.0 * 60 * 24 * 7}
year(?:s)? yr(?:s)? {60.0 * 60 * 24 * 365}
decade(?:s)? {} {60.0 * 60 * 24 * 365 * 10}
century|centuries {} {60.0 * 60 * 24 * 365 * 100}
}
set conv_unit(binary) {
option metric 2
(.*?)byte(?:s)? (.*?)b 1
(.*?)bit(?:s)? {} {1.0 / 8}
}

# Misc conversion formulas – these are types that cannot
# be converted by regular multiplication/division of factors.
# The principle is the same as the formulas above, however
# the arrays are broken down into *_from and *_to variables.
# Note: $value is used as the value being converted.
set conv_misc_from(num) {
option metric 0
integer|int {} {[scan $value "%d"]}
long {} {[scan $value "%u"]}
decimal|dec|float|double {} {[scan $value "%f"]}
octal|oct {} {[scan $value "%o"]}
hexadecimal|hex {} {[scan $value "%x"]}
binary|bin {} {[bin2int $value]}
ip {} {[ip2long $value]}
rgb {} {[rgb2int $value]}
}
set conv_misc_to(num) {
option metric 0
integer|int {} {[format "%d" [conv_int $value]]}
long {} {[format "%u" [conv_int $value]]}
decimal|dec|float|double {} {[format "%f" $value]}
octal|oct {} {[format "%o" [conv_int $value]]}
hexadecimal|hex {} {[format "%X" [conv_int $value]]}
binary|bin {} {[int2bin [conv_int $value]]}
ip {} {[long2ip [conv_int $value]]}
rgb {} {[int2rgb [conv_int $value]]}
}
set conv_misc_from(temperature) {
option metric 0
fahrenheit F {($value – 32) * 5 / 9.0}
kelvin K {$value – 273.15}
celsius|centigrade C {$value}
}
set conv_misc_to(temperature) {
option metric 0
fahrenheit F {(9 / 5.0 * $value) + 32}
kelvin K {$value + 273.15}
celsius|centigrade C {$value}
}

# Conversion strings to specificially ignore (that conflict with expr)
set conv_ignore {
e abs acos asin
atan atan2 ceil
cos cosh double
exp floor fmod
hypot int log
log10 pow rand
round sin sinh
sqrt srand tan
tanh
}

# Metric conversion factors
# Note: Abbreviations are case sensitive here
# Syntax:
# mame abbreviation factor
set conv_metric {
Yotta Y 24
Zetta Z 21
Exa E 18
Peta P 15
Tera T 12
Giga G 9
Mega M 6
Kilo k 3
Hecto h 2
Deca dk 1

Deci d -1
Centi c -2
Milli m -3
Micro µ -6
Nano n -9
Pico p -12
Femto f -15
Atto a -18
Zepto z -21
Yocto y -24
}

proc xrange {xr xr1 xr2} {
return [join [lrange [split $xr] $xr1 $xr2]]
}

proc anymatch {string1 string2} {
foreach string $string2 {
if {[lsearch -exact [string tolower $string1] [string tolower $string]] != -1} {
return 1
}
}
return 0
}

proc conv_fixtopic {arg} {
regsub -all {[\\\{\}\[\]\”]} $arg {} arg ; # Bad characters
regsub -all {(\s)+} $arg {\1} arg ; # Double whitespace
regsub -all {^\s*|\s*$} $arg {} arg ; # Whitespace at ends
return $arg
}

proc conv_fixdata {arg output} {
global botnick
if {[string index $output 0] != “#”} {
regsub -all -nocase {$output’s} $arg “your” arg
}
regsub -all -nocase {$botnick’s} $arg “my” arg
return $arg
}

proc conv_msg {targets arg} {
foreach target $targets {
puthelp “PRIVMSG $target :[conv_fixdata $arg $target]“
}
}

proc conv_fixexpr {exp} {
global ib_const
set exp [conv_fixtopic $exp]
foreach i [array names ib_const] {
regsub -all “\%$i” $exp $ib_const($i) exp
}
return $exp
}

# Begin conversion code
proc int2bin {int} {
return [format "%s.%s.%s.%s" \
[byte2bin [expr ($int >> 24) & 0xff]] \
[byte2bin [expr ($int >> 16) & 0xff]] \
[byte2bin [expr ($int >> 8) & 0xff]] \
[byte2bin [expr $int & 0xff]]]
}

proc byte2bin {byte} {
set result “”
for {set i 0} {$i < 8} {incr i} {
append result [expr ($byte & 128) >> 7]
set byte [expr $byte << 1]
}
return $result
}

proc bin2int {bin} {
set result 0
for {set i 0} {$i < [string length $bin]} {incr i} {
if {([set digit [string index $bin $i]] == 0) || ($digit == 1)} {
set result [expr $result << 1 | $digit]
} elseif {$digit == “.”} {
#ignore
} else {
set result “”
}
}
return $result
}

proc ip2long {ip} {
if {[scan $ip "%d.%d.%d.%d" a b c d] == 4} {
foreach i “$a $b $c $d” {
if {($i > 255) || ($i < 0)} {
return “”
}
}
set long [expr $a << 24 | $b << 16 | $c << 8 | $d]
if {$long < 0} {
set long [expr pow(2, 32) + $long]
}
return $long
} else {
return “”
}
}

proc long2ip {long} {
return [format "%d.%d.%d.%d" \
[expr ($long >> 24) & 0xff] \
[expr ($long >> 16) & 0xff] \
[expr ($long >> 8) & 0xff] \
[expr $long & 0xff]]
}

proc rgb2int {rgb} {
if {[scan $rgb "%d.%d.%d" red green blue] == 3} { return [expr $red << 16 | $green << 8 | $blue << 0] } \
else { return “” }
}

proc int2rgb {long} {
return [format "%d.%d.%d" \
[expr ($long >> 16) & 0xff] \
[expr ($long >> 8) & 0xff] \
[expr $long & 0xff]]
}

# expr’s abs() and int() can’t handle large unsigned integers,
# these functions are just to get around this
proc conv_int {value} {
return [lindex [split $value "."] 0]
}

proc conv_abs {value} {
return [string trimleft $value "-"]
}

proc conv_absint {value} {
return [conv_int [conv_abs $value]]
}

proc conv_units {value type1 type2} {
global conv_units_exec
regsub -all {‘} [conv_fixtopic $type1] {} type1
regsub -all {‘} [conv_fixtopic $type2] {} type2
if {[catch {exec bash -c "$conv_units_exec '$value $type1' '$type2'"} output]} {
error $output
}
foreach line [split $output \n] {
if {[regexp -- {^\s*([^=]+=.+)$} $line tmp result]} {
return $result
}
}
error “unknown response from units command”
}

proc conv_scan {var_formula var_unit index} {
global conv_ignore conv_unit
upvar 1 $var_formula formula $var_unit unit
set string {([a-z]+(-[a-z]+)?)}
if {[regexp -nocase -start $index -- $string $formula a unit]} {
if {[lsearch -exact $conv_ignore $unit] != -1} {
# Ignore this unit and search for the next unit
regexp -nocase -start $index -indices $string — $formula a index
return [conv_scan "formula" "unit" [expr [lindex $index 1] + 1]]
} else {
# Found unit, return ok
return 1
}
}
# No more units found
return 0
}

# $var will be either unit, misc_from, or misc_to
proc conv {value unit var lists} {
global conv_$var
upvar 1 list uplist
if {![info exists uplist]} {
set uplist “”
}
set type [expr {($var == "unit") || ($var == "misc_from") ? "*" : "/"}]
# First we check full names, then abbreviations
foreach method {name abbv} {
foreach list $lists {
# Default options
set option_absint 0
set option_metric 1
foreach {name abbv formula} [set conv_$var\($list)] {
if {$name == “option”} {
set option_$abbv $formula
} elseif {[regexp -nocase -- "^([set $method])\$” $unit a b prefix]} {
set uplist $list
if {([catch {expr $formula} value]) || ($value == “”)} {
error “evaluating expression for ‘$unit’”
}
if {$option_absint} {
set value [conv_absint $value]
}
if {($option_metric) && ($prefix != “”) && ([catch {expr [conv_metric $prefix $method $option_metric] $type $value} value])} {
error “evaluating metric conversion for ‘$unit’”
}
return $value
}
}
}
}
error “unknown conversion type ‘$unit’”
}

# $method will be either “name” or “abbv”
# $option will be either 1 or 2
proc conv_metric {prefix method option} {
global conv_metric
foreach {name abbv factor} $conv_metric {
if {(($method == “name”) && ([string equal -nocase $name $prefix])) || (($method == “abbv”) && ([string equal $abbv $prefix]))} {
if {$option == 1} {
return [expr pow(10, $factor)] ; # Regular metric
} elseif {$option == 2} {
return [expr pow(2, ($factor / 3 * 10))] ; # Binary conversion
}
}
}
error “unknown metric prefix”
}
# End conversion code

# Begin Public binds code
proc msg_conv {nick uhost hand arg} {
global botnick
pub_conv $nick $uhost $hand “” $arg
}

proc pub_conv {nick uhost hand chan arg} {
global botnick value global conv_channel_flag
global conv_units_exec conv_unit conv_misc_from conv_misc_to
if {(![isbotnick $nick]) && (![matchattr $hand +b])} {
if {(![string match "$chan" ""]) && (![channel get $chan $conv_channel_flag])} {
return 0 ; # If command comes from a channel, and that channel doesn’t have +convert then ignore
}
set isuser [expr {[matchattr $hand - $chan] || [matchattr $hand -]}] ; # Note that $chan might be “”, so we must handle both cases
if {([validchan $chan]) && ($isuser)} {
set output1 $chan ; # The bot sends the text to the channel for users
} else {
set output1 $nick ; # Non-users get privmsg’d
}
if {[set i [string last ">" $arg]] == -1} {
set output2 $output1 ; # By default, output2 (~stdout~) goes to output1 (~stderr~)
} else {
# Output has been redirected
if {(!$isuser) || ([set output2 [string trim [string range $arg [expr $i + 1] end] ” “]] == “”)} {
set output2 $output1 ; # Error (User doesn’t have access, or output was “”), so we go back to the default
}
set arg [string trim [string range $arg 0 [expr $i - 1]] ” “]
}
set remainder [xrange $arg 0 end]
if {(([scan $remainder "%s from %s to %s" value type1 type2] != 3) || ([anymatch [list $value $type1 $type2] {from to}])) && \
(([scan $remainder "%s from %s %s" value type1 type2] != 3) || ([anymatch [list $value $type1 $type2] {from to}])) && \
(([scan $remainder "%s %s to %s" value type1 type2] != 3) || ([anymatch [list $value $type1 $type2] {from to}])) && \
(([scan $remainder "%s %s %s" value type1 type2] != 3) || ([anymatch [list $value $type1 $type2] {from to}])) && \
((([info exists value]) && ([unset value] == “”)) || 1) && \
(([scan $remainder "from %s to %s" type1 type2] != 2) || ([anymatch [list $type1 $type2] {from to}])) && \
(([scan $remainder "from %s %s" type1 type2] != 2) || ([anymatch [list $type1 $type2] {from to}])) && \
(([scan $remainder "%s to %s" type1 type2] != 2) || ([anymatch [list $type1 $type2] {from to}])) && \
(([scan $remainder "%s %s" type1 type2] != 2) || ([anymatch [list $type1 $type2] {from to}]))} {
conv_msg $output1 “error parsing sentence”
} else {
if {![info exists value]} {
set value 1
}
if {![catch {conv $value $type1 "misc_from" [array names conv_misc_from]} type1_value]} {
if {[catch {conv $type1_value $type2 "misc_to" $list} type2_value]} {
conv_msg $output1 “error $type2_value”
} else {
conv_msg $output2 “$value $type1 = $type2_value $type2″
}
} elseif {($conv_units_exec != “”) && (![catch {conv_units $value $type1 $type2} output])} {
conv_msg $output2 $output
} else {
set type1_formula $type1
set type2_formula $type2
set found 0
while 1 {
if {[conv_scan "type1_formula" "type1_unit" 0]} {
if {![conv_scan "type2_formula" "type2_unit" 0]} {
conv_msg $output1 “error unmatched type ‘$type1_unit’”
} elseif {[catch {conv 1 $type1_unit "unit" [array names conv_unit]} type1_value]} {
conv_msg $output1 “error $type1_value”
} elseif {![regsub -nocase $type1_unit $type1_formula $type1_value type1_formula]} {
conv_msg $output1 “error decompiling expression ‘$type1_unit’”
} elseif {[catch {conv 1 $type2_unit "unit" $list} type2_value]} {
conv_msg $output1 “error $type2_value”
} elseif {![regsub -nocase $type2_unit $type2_formula $type2_value type2_formula]} {
conv_msg $output1 “error decompiling expression ‘$type2_unit’”
} else {
incr found
continue
}
} elseif {[conv_scan "type2_formula" "type2_unit" 0]} {
conv_msg $output1 “error unmatched type ‘$type2_unit’”
} else {
break
} ; # At the end, so stop
return ; # We got an error somewhere, bail out
}
if {!$found} {
conv_msg $output1 “error no conversion types found”
} elseif {[catch {expr [conv_fixexpr "($value) * ($type1_formula) / ($type2_formula)"]} value2]} {
conv_msg $output1 “error evaluating expression”
} else {
conv_msg $output2 “$value $type1 = $value2 $type2″
}
}
}
}
}
# End Public binds code

# Init stuff
if {[catch {package require Tcl 8.3} error]} {
putlog “error TCL v8.3 or higher is required to run this script”
return 0
}

putlog “*** LOADED: convert.tcl”

Categories: Code, TCL Tags: , , ,