WP-LESS - Version 1.1

Version Description

Download this release

Release Info

Developer oncletom
Plugin Icon wp plugin WP-LESS
Version 1.1
Comparing to
See all releases

Code changes from version 1.0 to 1.1

bootstrap-for-theme.php ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * This file tends to be included in any development.
4
+ * In a sentence, in every case where you don't want to use WP-LESS as a standalone.
5
+ *
6
+ * Once included, it's up to you to use the available toolkit for your needs.
7
+ *
8
+ * = How to use? =
9
+ *
10
+ * 1. In your theme, include the `wp-less` anywhere you want. (eg: `wp-content/themes/yourtheme/lib/wp-less`)
11
+ * 2. Include the required files in your functions.php file. (eg: `require dirname(__FILE__).'/lib/wp-less/bootstreap-theme.php`)
12
+ * 3. The `$WPLessPlugin` is available for your
13
+ *
14
+ * In case you need to access the $WPLessPlugin variable outside the include scope, simply do that:
15
+ * `$WPLessPlugin = WPLessPlugin::getInstance();`
16
+ *
17
+ * And to apply automatic building on page display:
18
+ * `add_action('wp_print_styles', array($WPLessPlugin, 'processStylesheets'));`
19
+ * Or apply all hooks with:
20
+ * `$WPLessPlugin->registerHooks();`
21
+ *
22
+ * You can rebuild all stylesheets at any time with:
23
+ * `$WPLessPlugin->processStylesheets();`
24
+ *
25
+ * Or a specific stylesheet:
26
+ * `wp_enqueue_style('my_css', 'path/to/my/style.css');`
27
+ * `$WPLessPlugin->processStylesheet('my_css');`
28
+ *
29
+ * = Filters and hooks aren't enough =
30
+ *
31
+ * Build your own flavour and manage it the way you want. Simply extends WPLessPlugin and/or WPLessConfiguration.
32
+ * Dig in the code to see what to configure. I tried to make things customizable without extending classes!
33
+ */
34
+
35
+ /*
36
+ * This will be effective only if the plugin is not activated.
37
+ * You can then redistribute your theme with this loader fearlessly.
38
+ */
39
+ if (!class_exists('WPLessPlugin'))
40
+ {
41
+ require dirname(__FILE__).'/lib/Plugin.class.php';
42
+ $WPLessPlugin = WPPluginToolkitPlugin::create('WPLess', __FILE__, 'WPLessPlugin');
43
+ }
bootstrap.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: WP LESS
4
  Description: LESS extends CSS with variables, mixins, operations and nested rules. This plugin magically parse all your <code>*.less</code> files queued with <code>wp_enqueue_style</code> in WordPress.
5
  Author: Oncle Tom
6
- Version: 1.0
7
  Author URI: http://case.oncle-tom.net/
8
  Plugin URI: http://wordpress.org/extend/plugins/wp-less/
9
 
@@ -14,12 +14,4 @@ Plugin URI: http://wordpress.org/extend/plugins/wp-less/
14
  require dirname(__FILE__).'/lib/Plugin.class.php';
15
  $WPLessPlugin = WPPluginToolkitPlugin::create('WPLess', __FILE__);
16
 
17
- if (!is_admin())
18
- {
19
- do_action('wp-less_init', $WPLessPlugin);
20
- add_action('wp_print_styles', array($WPLessPlugin, 'processStylesheets'));
21
- }
22
- else
23
- {
24
- do_action('wp-less_init_admin', $WPLessPlugin);
25
- }
3
  Plugin Name: WP LESS
4
  Description: LESS extends CSS with variables, mixins, operations and nested rules. This plugin magically parse all your <code>*.less</code> files queued with <code>wp_enqueue_style</code> in WordPress.
5
  Author: Oncle Tom
6
+ Version: 1.1
7
  Author URI: http://case.oncle-tom.net/
8
  Plugin URI: http://wordpress.org/extend/plugins/wp-less/
9
 
14
  require dirname(__FILE__).'/lib/Plugin.class.php';
15
  $WPLessPlugin = WPPluginToolkitPlugin::create('WPLess', __FILE__);
16
 
17
+ $WPLessPlugin->registerHooks();
 
 
 
 
 
 
 
 
doc/api/filters.txt ADDED
File without changes
doc/api/hooks.txt ADDED
File without changes
doc/theme/footer.php ADDED
@@ -0,0 +1,2 @@
 
 
1
+ </body>
2
+ </html>
doc/theme/functions.php ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if (!is_admin())
4
+ {
5
+ wp_enqueue_style('wp-less-sample-theme', get_template_directory_uri().'/screen.less', array(), '1.0', 'screen,projection');
6
+ }
doc/theme/header.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html <?php language_attributes() ?>>
3
+ <head>
4
+ <title><?php wp_title() ?></title>
5
+ <?php wp_head() ?>
6
+ <meta http-equiv="imagetoolbar" content="no" />
7
+ <meta http-equiv="Content-Type" content="<?php bloginfo('html_type') ?>; charset=<?php bloginfo('charset') ?>" />
8
+ </head>
9
+ <body>
doc/theme/index.php ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <?php get_header() ?>
2
+
3
+ <h1>Unleash LESS power!</h1>
4
+
5
+ <p>Thanks for using the plugin.</p>
6
+
7
+ <?php get_footer() ?>
doc/theme/screen.less ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @base: 24px;
2
+ @border-color: #B2B;
3
+
4
+ .underline { border-bottom: 1px solid green }
5
+
6
+ #header {
7
+ color: black;
8
+ border: 1px solid @border-color + #222222;
9
+
10
+ .navigation {
11
+ font-size: @base/2;
12
+ a {
13
+ .underline;
14
+ }
15
+ }
16
+ .logo {
17
+ width: 300px;
18
+ :hover { text-decoration: none }
19
+ }
20
+ }
doc/theme/style.css ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ Theme Name: Sample WP-LESS theme
3
+ Theme URI: http://wordpress.org/extend/plugins/wp-less/
4
+ Description: Plug 'n play theme showing how to implement WP-LESS
5
+ Author: Oncle Tom
6
+ Author URI: http://case.oncle-tom.net/
7
+ Version: 1.0
8
+
9
+ This example relies on the fact the WP-LESS plugin is activated.
10
+ A future example will show how to bundle WP-LESS without requiring the plugin. Ideal for themers.
11
+ */
doc/usage.txt ADDED
File without changes
lib/Configuration.class.php CHANGED
@@ -10,7 +10,7 @@ class WPLessConfiguration extends WPPluginToolkitConfiguration
10
  /**
11
  * Refers to the version of the plugin
12
  */
13
- const VERSION = '1.0';
14
 
15
 
16
  protected function configure()
10
  /**
11
  * Refers to the version of the plugin
12
  */
13
+ const VERSION = '1.1';
14
 
15
 
16
  protected function configure()
lib/Plugin.class.php CHANGED
@@ -13,6 +13,9 @@ if (!class_exists('BasePlugin'))
13
  */
14
  class WPLessPlugin extends WPPluginToolkitPlugin
15
  {
 
 
 
16
  /**
17
  * @static
18
  * @var Pattern used to match stylesheet files to process them as pure CSS
@@ -20,82 +23,128 @@ class WPLessPlugin extends WPPluginToolkitPlugin
20
  public static $match_pattern = '/\.less$/U';
21
 
22
  /**
23
- * Process all stylesheets to compile just in time
24
  *
25
  * @author oncletom
26
  * @since 1.0
27
  * @version 1.0
 
28
  */
29
- public function processStylesheets()
30
  {
31
- $styles = $this->getQueuedStylesToProcess();
32
  $wp_styles = $this->getStyles();
33
- $upload_dir = $this->configuration->getUploadDir();
34
-
35
- if (empty($styles))
36
- {
37
- return;
38
- }
39
 
40
- if (!wp_mkdir_p($upload_dir))
41
  {
42
- throw new WPLessException(sprintf('The upload dir folder (`%s`) is not writable from %s.', $upload_dir, get_class($this)));
 
 
 
43
  }
44
 
45
- WPLessStylesheet::$upload_dir = $this->configuration->getUploadDir();
46
- WPLessStylesheet::$upload_uri = $this->configuration->getUploadUrl();
47
 
48
- foreach ($styles as $style_id)
49
- {
50
- $stylesheet = new WPLessStylesheet($wp_styles->registered[$style_id]);
 
 
 
 
 
 
 
 
 
 
 
51
 
52
- if ($stylesheet->hasToCompile())
53
- {
54
- $stylesheet->save();
55
- }
 
 
 
 
 
 
 
 
 
 
56
 
57
- $wp_styles->registered[$style_id]->src = $stylesheet->getTargetUri();
 
 
58
  }
59
 
60
- do_action('wp-less_plugin_process_stylesheets', $styles);
 
 
61
  }
62
 
63
  /**
64
- * Find any style to process
65
  *
66
  * @author oncletom
67
  * @since 1.0
68
- * @version 1.0
69
- * @return array styles to process
70
  */
71
- protected function getQueuedStylesToProcess()
72
  {
 
73
  $wp_styles = $this->getStyles();
74
- $to_process = array();
75
 
76
- foreach ($wp_styles->queue as $style_id)
 
 
 
77
  {
78
- if (preg_match(self::$match_pattern, $wp_styles->registered[$style_id]->src))
79
- {
80
- $to_process[] = $style_id;
81
- }
82
  }
83
 
84
- return apply_filters('wp-less_get_queued_styles_to_process', $to_process);
 
 
 
 
 
 
 
 
 
 
 
85
  }
86
 
87
  /**
88
- * Returns WordPress Styles manager
89
  *
90
  * @author oncletom
91
- * @uses WP_Styles
92
- * @since 1.0
93
  * @version 1.0
94
- * @return WP_Styles styles instance
95
  */
96
- public function getStyles()
97
  {
98
- global $wp_styles;
99
- return $wp_styles;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
100
  }
101
  }
13
  */
14
  class WPLessPlugin extends WPPluginToolkitPlugin
15
  {
16
+ protected $is_filters_registered = false;
17
+ protected $is_hooks_registered = false;
18
+
19
  /**
20
  * @static
21
  * @var Pattern used to match stylesheet files to process them as pure CSS
23
  public static $match_pattern = '/\.less$/U';
24
 
25
  /**
26
+ * Find any style to process
27
  *
28
  * @author oncletom
29
  * @since 1.0
30
  * @version 1.0
31
+ * @return array styles to process
32
  */
33
+ protected function getQueuedStylesToProcess()
34
  {
 
35
  $wp_styles = $this->getStyles();
36
+ $to_process = array();
 
 
 
 
 
37
 
38
+ foreach ($wp_styles->queue as $style_id)
39
  {
40
+ if (preg_match(self::$match_pattern, $wp_styles->registered[$style_id]->src))
41
+ {
42
+ $to_process[] = $style_id;
43
+ }
44
  }
45
 
46
+ return apply_filters('wp-less_get_queued_styles_to_process', $to_process);
47
+ }
48
 
49
+ /**
50
+ * Returns WordPress Styles manager
51
+ *
52
+ * @author oncletom
53
+ * @uses WP_Styles
54
+ * @since 1.0
55
+ * @version 1.0
56
+ * @return WP_Styles styles instance
57
+ */
58
+ public function getStyles()
59
+ {
60
+ global $wp_styles;
61
+ return $wp_styles;
62
+ }
63
 
64
+ /**
65
+ * Process a single stylesheet
66
+ *
67
+ * @author oncletom
68
+ * @since 1.1
69
+ * @version 1.1
70
+ * @param string $handle
71
+ * @param $force boolean If set to true, rebuild all stylesheets, without considering they are updated or not
72
+ * @return WPLessStylesheet
73
+ */
74
+ public function processStylesheet($handle, $force = false)
75
+ {
76
+ $wp_styles = $this->getStyles();
77
+ $stylesheet = new WPLessStylesheet($wp_styles->registered[$handle]);
78
 
79
+ if ($force || $stylesheet->hasToCompile())
80
+ {
81
+ $stylesheet->save();
82
  }
83
 
84
+ $wp_styles->registered[$handle]->src = $stylesheet->getTargetUri();
85
+
86
+ return $stylesheet;
87
  }
88
 
89
  /**
90
+ * Process all stylesheets to compile just in time
91
  *
92
  * @author oncletom
93
  * @since 1.0
94
+ * @version 1.1
95
+ * @param $force boolean If set to true, rebuild all stylesheets, without considering they are updated or not
96
  */
97
+ public function processStylesheets($force = false)
98
  {
99
+ $styles = $this->getQueuedStylesToProcess();
100
  $wp_styles = $this->getStyles();
 
101
 
102
+ WPLessStylesheet::$upload_dir = $this->configuration->getUploadDir();
103
+ WPLessStylesheet::$upload_uri = $this->configuration->getUploadUrl();
104
+
105
+ if (empty($styles))
106
  {
107
+ return;
 
 
 
108
  }
109
 
110
+ if (!wp_mkdir_p(WPLessStylesheet::$upload_dir))
111
+ {
112
+ throw new WPLessException(sprintf('The upload dir folder (`%s`) is not writable from %s.', WPLessStylesheet::$upload_dir, get_class($this)));
113
+ }
114
+
115
+
116
+ foreach ($styles as $style_id)
117
+ {
118
+ $this->processStylesheet($style_id, $force);
119
+ }
120
+
121
+ do_action('wp-less_plugin_process_stylesheets', $styles);
122
  }
123
 
124
  /**
125
+ * Method to register hooks (and do it only once)
126
  *
127
  * @author oncletom
128
+ * @since 1.1
 
129
  * @version 1.0
 
130
  */
131
+ public function registerHooks()
132
  {
133
+ if ($this->is_hooks_registered)
134
+ {
135
+ return false;
136
+ }
137
+
138
+ if (!is_admin())
139
+ {
140
+ do_action('wp-less_init', $this);
141
+ add_action('wp_print_styles', array($this, 'processStylesheets'));
142
+ }
143
+ else
144
+ {
145
+ do_action('wp-less_init_admin', $this);
146
+ }
147
+
148
+ return $this->is_hooks_registered = true;
149
  }
150
  }
lib/vendor/lessphp/README CHANGED
@@ -1,4 +1,4 @@
1
- lessphp v0.1.5
2
  http://leafo.net/lessphp
3
  ========================================
4
 
1
+ lessphp v0.1.6
2
  http://leafo.net/lessphp
3
  ========================================
4
 
lib/vendor/lessphp/docs/docs.html CHANGED
@@ -10,7 +10,7 @@
10
  </head>
11
  <body>
12
 
13
- <h1>Documentation - lessphp</h1>
14
  <div class="content">
15
 
16
  <ul id="nav">
@@ -155,8 +155,8 @@ li {
155
  <a name="ablocks"></a>
156
  <h2>Abstract Blocks</h2>
157
 
158
- <p>Abstract blocks are like any other blocks, but their names start with a <code>@</code>. Like abstract variables, they are not
159
- included in the compiler's output. This allows you to do utilize mixins without adding any unused blocks to the output.
160
  You can also use an abstract class to define a package of invisible, but extractable blocks and properties.<p>
161
 
162
  <pre class="code">@mypackage {
10
  </head>
11
  <body>
12
 
13
+ <h1>Documentation - lessphp v0.1.6</h1>
14
  <div class="content">
15
 
16
  <ul id="nav">
155
  <a name="ablocks"></a>
156
  <h2>Abstract Blocks</h2>
157
 
158
+ <p>Abstract blocks are like any other blocks, but their names start with a <code>@</code>. Like abstract properties, they are not
159
+ included in the compiler's output. This allows you to utilize mixins without adding any unused blocks to the output.
160
  You can also use an abstract class to define a package of invisible, but extractable blocks and properties.<p>
161
 
162
  <pre class="code">@mypackage {
lib/vendor/lessphp/lessc.inc.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  /**
4
  * less.inc.php
5
- * v0.1.5
6
  *
7
  * less css compiler
8
  * adapted from http://lesscss.org/docs.html
@@ -182,8 +182,14 @@ class lessc
182
  $this->pop();
183
 
184
  // make the block(s) available in the new current scope
185
- foreach ($ctags as $t)
186
- $this->set($t, $env);
 
 
 
 
 
 
187
 
188
  return isset($out) ? $out : true;
189
  } catch (exception $ex) {
@@ -283,12 +289,12 @@ class lessc
283
 
284
  // copy everything except metadata
285
  if (!preg_match('/^__/', $name)) {
286
- // don't overwrite previous value
287
- if ($this->get($name)) {
288
  while ($tval = array_shift($value))
289
  $this->append($name, $tval);
290
  } else
291
- $this->set($name, $value); // fixme: this should be append?
292
  }
293
  }
294
 
@@ -356,7 +362,7 @@ class lessc
356
  $this->literal(';');
357
  } catch (exception $ex) {
358
  // there is an end of block next, then no problem
359
- if ($this->buffer{$this->count} != '}')
360
  throw new exception('parse error: failed to find end');
361
  }
362
 
@@ -449,8 +455,7 @@ class lessc
449
  private function literal($what)
450
  {
451
  // if $what is one char we can speed things up
452
- // fixme: throws a notice here when going over the len of the buffer
453
- if ((strlen($what) == 1 && $what != $this->buffer{$this->count}) ||
454
  !$this->match($this->preg_quote($what), $m))
455
  {
456
  throw new
@@ -784,8 +789,6 @@ class lessc
784
  return implode("\n", $props);
785
  }
786
 
787
-
788
- // todo replace render color
789
  private function compileValue($value)
790
  {
791
  switch ($value[0]) {
@@ -995,7 +998,6 @@ class lessc
995
  // get the most recent value of a variable
996
  // return default if it isn't found
997
  // $skip is number of vars to skip
998
- // todo: rename to getVar ?
999
  private function getVal($name, $skip = 0, $default = array('keyword', ''))
1000
  {
1001
  $val = $this->get($name);
@@ -1021,6 +1023,21 @@ class lessc
1021
  return end($val);
1022
  }
1023
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1024
  // set something in the current env
1025
  private function set($name, $value)
1026
  {
2
 
3
  /**
4
  * less.inc.php
5
+ * v0.1.6
6
  *
7
  * less css compiler
8
  * adapted from http://lesscss.org/docs.html
182
  $this->pop();
183
 
184
  // make the block(s) available in the new current scope
185
+ foreach ($ctags as $t) {
186
+ // if the block already exists then merge
187
+ if ($this->get($t, array(end($this->env)))) {
188
+ $this->merge($t, $env);
189
+ } else {
190
+ $this->set($t, $env);
191
+ }
192
+ }
193
 
194
  return isset($out) ? $out : true;
195
  } catch (exception $ex) {
289
 
290
  // copy everything except metadata
291
  if (!preg_match('/^__/', $name)) {
292
+ // don't overwrite previous value, look in current env for name
293
+ if ($this->get($name, array(end($this->env)))) {
294
  while ($tval = array_shift($value))
295
  $this->append($name, $tval);
296
  } else
297
+ $this->set($name, $value);
298
  }
299
  }
300
 
362
  $this->literal(';');
363
  } catch (exception $ex) {
364
  // there is an end of block next, then no problem
365
+ if (strlen($this->buffer) <= $this->count || $this->buffer{$this->count} != '}')
366
  throw new exception('parse error: failed to find end');
367
  }
368
 
455
  private function literal($what)
456
  {
457
  // if $what is one char we can speed things up
458
+ if ((strlen($what) == 1 && $this->count < strlen($this->buffer) && $what != $this->buffer{$this->count}) ||
 
459
  !$this->match($this->preg_quote($what), $m))
460
  {
461
  throw new
789
  return implode("\n", $props);
790
  }
791
 
 
 
792
  private function compileValue($value)
793
  {
794
  switch ($value[0]) {
998
  // get the most recent value of a variable
999
  // return default if it isn't found
1000
  // $skip is number of vars to skip
 
1001
  private function getVal($name, $skip = 0, $default = array('keyword', ''))
1002
  {
1003
  $val = $this->get($name);
1023
  return end($val);
1024
  }
1025
 
1026
+ // merge a block into the current env
1027
+ private function merge($name, $value)
1028
+ {
1029
+ // if the current block isn't there then just set
1030
+ $top =& $this->env[count($this->env) - 1];
1031
+ if (!isset($top[$name])) return $this->set($name, $value);
1032
+
1033
+ // copy the block into the old one, including meta data
1034
+ foreach ($value as $k=>$v) {
1035
+ // todo: merge property values instead of replacing
1036
+ // have to check type for this
1037
+ $top[$name][$k] = $v;
1038
+ }
1039
+ }
1040
+
1041
  // set something in the current env
1042
  private function set($name, $value)
1043
  {
lib/vendor/lessphp/plessc CHANGED
@@ -3,72 +3,94 @@
3
  //
4
  // command line utility to compile less to stdout
5
  // leaf corcoran <leafo.net>
 
6
 
7
- require './lessc.inc.php';
8
-
9
- $colors = array (
10
- 'color' => array(
11
- 'black' => 30,
12
- 'red' => 31,
13
- 'green' => 32,
14
- 'brown' => 33,
15
- 'blue' => 34,
16
- 'purple' => 35,
17
- 'cyan' => 36,
18
- 'grey' => 37,
19
- 'yellow' => 33
20
- ),
21
- 'style' => array(
22
- 'normal' => 0,
23
- 'bold' => 1,
24
- 'light' => 1,
25
- 'underscore' => 4,
26
- 'underline' => 4,
27
- 'blink' => 5,
28
- 'inverse' => 6,
29
- 'hidden' => 8,
30
- 'concealed' => 8
31
- ),
32
- 'background' => array(
33
- 'black' => 40,
34
- 'red' => 41,
35
- 'green' => 42,
36
- 'brown' => 43,
37
- 'yellow' => 43,
38
- 'blue' => 44,
39
- 'purple' => 45,
40
- 'cyan' => 46,
41
- 'grey' => 47
42
- )
43
- );
44
-
45
- array_shift($argv);
46
-
47
- // read less code from argument or from std in if there is no argument
48
- if (false !== ($loc = array_search("-r", $argv))) {
49
- unset($argv[$loc]);
50
- $c = array_shift($argv);
51
- if (!$c) {
52
- while (!feof(STDIN)) {
53
- $c .= fread(STDIN, 8192);
54
- }
55
  }
 
56
 
57
- } else if (false !== ($loc = array_search("-w", $argv))) {
58
- unset($argv[$loc]);
 
 
 
 
 
59
 
60
- // see if we are sending notifications
61
- $notif = array_search("-n", $argv);
62
- if ($notif) unset($argv[$notif]);
 
 
 
 
 
63
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
  if (!is_file($in = array_shift($argv)) ||
65
  null == $out = array_shift($argv))
66
  {
67
- exit("\033[31m\033[1mFatal Error:\033[0m plessc -w infile outfile\n");
 
68
  }
69
 
 
 
 
 
70
  $fail_time = 0;
71
- echo "Watching ".$in.($notif ? ' with notifications' : '').", press Ctrl + c to exit.\n";
72
  while (1) {
73
  if (!is_file($out) || (filemtime($in) > filemtime($out) && $fail_time != filemtime($in))) {
74
  // try to compile it
@@ -76,37 +98,37 @@ if (false !== ($loc = array_search("-r", $argv))) {
76
  $l = new lessc($in);
77
  $c = $l->parse();
78
  echo "Writing updated file: ".$out."\n";
79
- if (!file_put_contents($out, $c))
80
- exit('Fatal Error: Failed to write file '.$out."\n");
 
 
81
  } catch (exception $ex) {
82
  echo "\nFatal Error:\n".str_repeat('=', 20)."\n".$ex->getMessage()."\n\n";
83
  $fail_time = filemtime($in);
84
 
85
- if ($notif) {
86
  `notify-send -u critical "compile failed" "{$ex->getMessage()}"`;
87
  }
88
  }
89
  }
 
90
  sleep(1);
91
  }
92
-
93
- } else {
94
- if (!is_file($fname = array_shift($argv)))
95
- exit('Fatal Error: failed to find file: '.$fname."\n");
96
- $c = file_get_contents($fname);
97
-
98
- $pi = pathinfo($fname);
99
- $importDir = $pi['dirname'].'/';
100
  }
101
 
102
- error_reporting(E_ALL);
 
 
 
103
 
104
- $l = new lessc();
105
- if ($importDir) $l->importDir = $importDir;
106
  try {
107
- echo $l->parse($c);
 
108
  } catch (exception $ex) {
109
- echo "Fatal Error:\n".str_repeat('=', 20)."\n".$ex->getMessage()."\n";
 
110
  }
111
 
 
112
  ?>
3
  //
4
  // command line utility to compile less to stdout
5
  // leaf corcoran <leafo.net>
6
+ $VERSION = "v0.1.6";
7
 
8
+ error_reporting(E_ALL);
9
+ $path = realpath(dirname(__FILE__)).'/';
10
+
11
+ require $path."lessc.inc.php";
12
+
13
+ $fa = "Fatal Error: ";
14
+ function err($msg) {
15
+ fwrite(STDERR, $msg."\n");
16
+ }
17
+
18
+ if (php_sapi_name() != "cli") {
19
+ err($fa.$argv[0]." must be run in the command line.");
20
+ exit(1);
21
+ }
22
+ $exe = array_shift($argv); // remove filename
23
+
24
+ function process($data, $import = null) {
25
+ global $fa;
26
+
27
+ $l = new lessc();
28
+ if ($import) $l->importDi = $import;
29
+ try {
30
+ echo $l->parse($data);
31
+ exit(0);
32
+ } catch (exception $ex) {
33
+ err($fa."\n".str_repeat('=', 20)."\n".
34
+ $ex->getMessage());
35
+ exit(1);
36
+ }
37
+ }
38
+
39
+ // process args
40
+ $opts = array();
41
+ foreach ($argv as $loc => $a) {
42
+ if (preg_match("/^-([a-zA-Z]+)$/", $a, $m)) {
43
+ $m = $m[1];
44
+ for ($i = 0; $i < strlen($m); $i++)
45
+ $opts[$m{$i}] = $loc;
46
+ unset($argv[$loc]);
 
 
 
 
 
 
 
 
 
47
  }
48
+ }
49
 
50
+ function has($o, &$loc = null)
51
+ {
52
+ global $opts;
53
+ if (!isset($opts[$o])) return false;
54
+ $loc = $opts[$o];
55
+ return true;
56
+ }
57
 
58
+ function hasValue($o, &$value = null)
59
+ {
60
+ global $argv;
61
+ if (!has($o,$loc)) return false;
62
+ if (!isset($argv[$loc+1])) return false;
63
+ $value = $argv[$loc+1];
64
+ return true;
65
+ }
66
 
67
+ if (has("v")) {
68
+ exit($VERSION."\n");
69
+ }
70
+
71
+ if (has("r", $loc)) {
72
+ if (!hasValue("r", $data)) {
73
+ while (!feof(STDIN)) {
74
+ $data .= fread(STDIN, 8192);
75
+ }
76
+ }
77
+ return process($data);
78
+ }
79
+
80
+ if (has("w")) {
81
+ // need two files
82
  if (!is_file($in = array_shift($argv)) ||
83
  null == $out = array_shift($argv))
84
  {
85
+ err($fa.$exe." -w infile outfile");
86
+ exit(1);
87
  }
88
 
89
+ echo "Watching ".$in.
90
+ (has("n") ? ' with notifications' : '').
91
+ ", press Ctrl + c to exit.\n";
92
+
93
  $fail_time = 0;
 
94
  while (1) {
95
  if (!is_file($out) || (filemtime($in) > filemtime($out) && $fail_time != filemtime($in))) {
96
  // try to compile it
98
  $l = new lessc($in);
99
  $c = $l->parse();
100
  echo "Writing updated file: ".$out."\n";
101
+ if (!file_put_contents($out, $c)) {
102
+ err($fa."Could not write to file ".$out);
103
+ exit(1);
104
+ }
105
  } catch (exception $ex) {
106
  echo "\nFatal Error:\n".str_repeat('=', 20)."\n".$ex->getMessage()."\n\n";
107
  $fail_time = filemtime($in);
108
 
109
+ if (has("n")) {
110
  `notify-send -u critical "compile failed" "{$ex->getMessage()}"`;
111
  }
112
  }
113
  }
114
+
115
  sleep(1);
116
  }
117
+ exit(0);
 
 
 
 
 
 
 
118
  }
119
 
120
+ if (!$fname = array_shift($argv)) {
121
+ echo "Usage: ".$exe." input-file > output-file\n";
122
+ exit(1);
123
+ }
124
 
 
 
125
  try {
126
+ $l = new lessc($fname);
127
+ echo $l->parse();
128
  } catch (exception $ex) {
129
+ err($fa.$ex->getMessage());
130
+ exit(1);
131
  }
132
 
133
+
134
  ?>
lib/vendor/plugin-toolkit/BaseConfiguration.class.php CHANGED
@@ -232,7 +232,7 @@ abstract class WPPluginToolkitConfiguration
232
 
233
  if (!$url = get_option( 'upload_url_path'))
234
  {
235
- $url = empty($upload_path) or ($upload_path == $dir)
236
  ? WP_CONTENT_URL . '/uploads'
237
  : trailingslashit($siteurl).$upload_path;
238
  }
232
 
233
  if (!$url = get_option( 'upload_url_path'))
234
  {
235
+ $url = (empty($upload_path) or ($upload_path == $dir))
236
  ? WP_CONTENT_URL . '/uploads'
237
  : trailingslashit($siteurl).$upload_path;
238
  }
lib/vendor/plugin-toolkit/BasePlugin.class.php CHANGED
@@ -2,6 +2,7 @@
2
  /**
3
  * Base plugin class to extend
4
  *
 
5
  * @author oncletom
6
  * @package plugin-toolkit
7
  */
@@ -10,6 +11,8 @@ abstract class WPPluginToolkitPlugin
10
  protected $configuration;
11
  protected static $autoload_configured = false;
12
 
 
 
13
  /**
14
  * Plugin constructor
15
  *
@@ -69,9 +72,10 @@ abstract class WPPluginToolkitPlugin
69
  * @version 1.0
70
  * @param string $baseClassName
71
  * @param string $baseFileName
 
72
  * @return $baseClassName+Plugin instance
73
  */
74
- public final static function create($baseClassName, $baseFileName)
75
  {
76
  require_once dirname(__FILE__).'/BaseConfiguration.class.php';
77
  require_once dirname($baseFileName).'/lib/Configuration.class.php';
@@ -82,6 +86,12 @@ abstract class WPPluginToolkitPlugin
82
  list($class, $configuration) = apply_filters('plugin-toolkit_create', array($class, $configuration));
83
 
84
  $object = new $class(new $configuration($baseClassName, $baseFileName));
 
 
 
 
 
 
85
  do_action('plugin-toolkit_create', $object);
86
 
87
  return $object;
@@ -99,4 +109,42 @@ abstract class WPPluginToolkitPlugin
99
  {
100
  return $this->configuration;
101
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  }
2
  /**
3
  * Base plugin class to extend
4
  *
5
+ * @version 1.1
6
  * @author oncletom
7
  * @package plugin-toolkit
8
  */
11
  protected $configuration;
12
  protected static $autoload_configured = false;
13
 
14
+ protected static $instances = array();
15
+
16
  /**
17
  * Plugin constructor
18
  *
72
  * @version 1.0
73
  * @param string $baseClassName
74
  * @param string $baseFileName
75
+ * @param string $singleton_identifier[optional]
76
  * @return $baseClassName+Plugin instance
77
  */
78
+ public final static function create($baseClassName, $baseFileName, $singleton_identifier = null)
79
  {
80
  require_once dirname(__FILE__).'/BaseConfiguration.class.php';
81
  require_once dirname($baseFileName).'/lib/Configuration.class.php';
86
  list($class, $configuration) = apply_filters('plugin-toolkit_create', array($class, $configuration));
87
 
88
  $object = new $class(new $configuration($baseClassName, $baseFileName));
89
+
90
+ if (!is_null($singleton_identifier) && $singleton_identifier)
91
+ {
92
+ call_user_func(array($class, 'setInstance'), $singleton_identifier, $object);
93
+ }
94
+
95
  do_action('plugin-toolkit_create', $object);
96
 
97
  return $object;
109
  {
110
  return $this->configuration;
111
  }
112
+
113
+ /**
114
+ * Retrieves the instance of an object
115
+ * If no identifier is given, the first created instance is returned
116
+ *
117
+ * @author oncletom
118
+ * @since 1.1
119
+ * @version 1.0
120
+ * @static
121
+ * @param string $identifier [optional]
122
+ * @return object
123
+ */
124
+ public static function getInstance($identifier = null)
125
+ {
126
+ if (is_null($identifier))
127
+ {
128
+ $identifier = key(self::$instances);
129
+ }
130
+
131
+ return isset(self::$instances[$identifier]) ? self::$instances[$identifier] : null;
132
+ }
133
+
134
+ /**
135
+ * Stores an instance of a created object
136
+ * Self storage is so good :)
137
+ *
138
+ * @author oncletom
139
+ * @since 1.1
140
+ * @version 1.0
141
+ * @static
142
+ * @protected
143
+ * @param string $identifier
144
+ * @param object $object
145
+ */
146
+ protected static function setInstance($identifier, $object)
147
+ {
148
+ self::$instances[$identifier] = $object;
149
+ }
150
  }
readme.txt CHANGED
@@ -4,7 +4,7 @@ Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_i
4
  Tags: dev, theme, themes, toolkit, plugin-toolkit, less, lesscss, lessc, lessphp, productivity, style, stylesheet, api
5
  Requires at least: 2.8
6
  Tested up to: 2.8.x
7
- Stable tag: 1.0
8
 
9
  Implementation of LESS (Leaner CSS) in order to make themes development easier.
10
 
@@ -12,7 +12,9 @@ Implementation of LESS (Leaner CSS) in order to make themes development easier.
12
  == Description ==
13
  [LESS](http://lesscss.org) is a templating language based on top of CSS. It provides numerous enhancements to speed up development and make its maintenance easier.
14
 
15
- You can count on:
 
 
16
 
17
  * Variables
18
  * Mixins (inheritance of rules)
@@ -23,11 +25,14 @@ You can count on:
23
  The plugin lets you concentrate on what you need: coding CSS. Everything else is handled automatically, from cache management to user delivery.
24
  Seriously.
25
 
 
 
26
  The sole requirement is to use WordPress API and LESS convention: the `.less` extension.
27
 
28
  **Minimal Requirements**: PHP 5.1.2 and WordPress 2.8.
29
- **Relies on**: [LESSPHP 0.1.5](http://leafo.net/lessphp/), [plugin-toolkit](http://wordpress.org/extend/plugins/plugin-toolkit/).
30
 
 
31
 
32
  == Installation ==
33
 
@@ -42,12 +47,21 @@ The sole requirement is to use WordPress API and LESS convention: the `.less` ex
42
  1. Activate it through your WordPress plugins administration page
43
 
44
  == Changelog ==
 
 
 
 
 
 
 
 
 
45
  = Version 1.0 =
46
 
47
- * implemented the forthcoming `plugin-toolkit` to speed up plugin development
48
- * bundled lessphp 0.1.5
49
  * implemented API to let you control the plugin the way you want
50
  * just in time compilation with static file caching
 
 
51
 
52
 
53
  == Frequently Asked Questions ==
@@ -69,10 +83,10 @@ Nothing special. The LESS parser is fully compliant with CSS syntax.
69
  It means nothing will be broken so don't worry.
70
 
71
  = I'm a themer and I don't want to ask my users to activate this plugin =
72
- It's a very good moto. Anyway, at the moment I don't provide any helper for this purpose.
73
- It is planned for later.
74
 
75
- If you are familiar with OOP programmation, you can make your way out of this. The source code is fully self-documented.
76
 
77
  == Screenshots ==
78
 
4
  Tags: dev, theme, themes, toolkit, plugin-toolkit, less, lesscss, lessc, lessphp, productivity, style, stylesheet, api
5
  Requires at least: 2.8
6
  Tested up to: 2.8.x
7
+ Stable tag: 1.1
8
 
9
  Implementation of LESS (Leaner CSS) in order to make themes development easier.
10
 
12
  == Description ==
13
  [LESS](http://lesscss.org) is a templating language based on top of CSS. It provides numerous enhancements to speed up development and make its maintenance easier.
14
 
15
+ Theme developers can even bundle the plugin without worrying about conflicts: just include the special `bootstrap-for-theme.php` and read its instructions.
16
+
17
+ = Features =
18
 
19
  * Variables
20
  * Mixins (inheritance of rules)
25
  The plugin lets you concentrate on what you need: coding CSS. Everything else is handled automatically, from cache management to user delivery.
26
  Seriously.
27
 
28
+ = Requirements =
29
+
30
  The sole requirement is to use WordPress API and LESS convention: the `.less` extension.
31
 
32
  **Minimal Requirements**: PHP 5.1.2 and WordPress 2.8.
33
+ **Relies on**: [LESSPHP 0.1.6](http://leafo.net/lessphp/), [plugin-toolkit](http://wordpress.org/extend/plugins/plugin-toolkit/).
34
 
35
+ *Notice*: in case you'd like to drop the usage of this plugin, it's safe to do it. You will just need to convert back your stylesheets to CSS.
36
 
37
  == Installation ==
38
 
47
  1. Activate it through your WordPress plugins administration page
48
 
49
  == Changelog ==
50
+ = Version 1.1 =
51
+ * added `bootstrap-for-theme.php` to let themers bundle the plugin in their own themes
52
+ * added `WPLessPlugin::registerHooks` methods to ease hooks activation
53
+ * theme bootstrap will only load if the plugin is not alread activated
54
+ * `WPLessPlugin::processStylesheets()` and `WPLessPlugin::processStylesheet()` now accepts an additional parameter to force the rebuild
55
+ * lessphp: updated to version 0.1.6
56
+ * plugin-toolkit: updated to version 1.1
57
+
58
+
59
  = Version 1.0 =
60
 
 
 
61
  * implemented API to let you control the plugin the way you want
62
  * just in time compilation with static file caching
63
+ * lessphp: bundled to version 0.1.6
64
+ * plugin-toolkit: bundled experimental plugin development
65
 
66
 
67
  == Frequently Asked Questions ==
83
  It means nothing will be broken so don't worry.
84
 
85
  = I'm a themer and I don't want to ask my users to activate this plugin =
86
+ It's a very good moto. Since the 1.1 release, there is a special bootstrap file: `bootstrap-for-theme.php`.
87
+ Everything is prepared and documented inside, with examples and hint.
88
 
89
+ Just help yourself!
90
 
91
  == Screenshots ==
92