Extra spacing in TinyMCE after pasting from Word

TinyMCE can add extra empty paragraphs when you insert text from Word. TinyMCE simply wraps each newline into paragraph.
To solve it you need to follow these steps:

  1. Enable paste plugin.
  2. Add handler for parsing inserted text

So your TinyMCE code will look like:

  tinyMCE.init({
        ...
      	plugins: "paste",
      	paste_auto_cleanup_on_paste : true,
      	paste_postprocess : function(pl, o) {
            // remove extra line breaks
            o.node.innerHTML = o.node.innerHTML.replace(/<p.*>\s*(<br>|&nbsp;)\s*<\/p>/ig, "");
        }
  });

See more info on the official wiki

Tags: , ,

March 6th, 2010, posted by alex

Doctrine Sluggable and translit

Doctrine Sluggable behaviour doesn’t work with non-ASCII characters – it just removes them from the slug. For some languages, e.g. Russian with Cyrillic alphabet, it becomes unusable. The obvious way is to use transliteration.
Luckily Doctrine has easy way to do that, you can pass method for building slug:

Artist:
  actAs:
    Sluggable:
      fields: [name]
      builder: [oxtSluggableTranslit, urlize]

The easiest way I found to transliterate non-ASCII text is to use PECL translit package. For Debian-based systems you can install it with dh-make-php.
Here’s the code:

class oxtSluggableTranslit
{
  /**
   * Convert any passed string to a url friendly string. Converts 'My first blog post' to 'my-first-blog-post'
   *
   * @param  string $text  Text to urlize
   * @return string $text  Urlized text
   */
  static public function urlize($text)
  {
    return Doctrine_Inflector::urlize(transliterate($text, array('cyrillic_transliterate', 'remove_punctuation'), 'utf-8', 'utf-8'));
  }
}

You can view all available transliterate filters by running

php -r 'print_r(transliterate_filters_get());'

Tags: , ,

February 1st, 2010, posted by alex

Symfony, propel and long running scripts

For long running scripts in symfony with propel ORM you may experience problems with memory usage. To avoid them make sure to disable propel instance caching by calling this code at the beginning of the script:

Propel::disableInstancePooling();

Propel by default caches in memory all fetched database objects. That means that for scripts with extensive db usage or long running time you may hit php memory_limit sooner or later.
Starting with propel 1.3 shipped with symfony 1.3 and 1.4 which are about to be released you’ll be able to disable instance pooling in database yaml config.

Tags: ,

November 28th, 2009, posted by alex

Disable menu bar in gnome-terminal

You can easily hide menu bar for gnome-terminal at a runtime. Obviously it’s rarely used and you can save some screen space by hiding it.

To hide it for newly opened terminal windows by default change this flag in gnome config:
/apps/gnome-terminal/profiles/Default/default_show_menubar to false.

gconftool --type boolean --set /apps/gnome-terminal/profiles/Default/default_show_menubar false

Tags: ,

October 18th, 2009, posted by alex

symfony: sfValidatorFile – invalid mime type (text/plain) for PNG images

On some systems sfValidatorFile may give you an error when trying to upoad PNG images. It says that it has invalid mime type – text/plain, though you have 'mime_types' = 'web_images' and other image formats work well.

It may be caused by wrong result from mime_content_type() function. To check if it’s your case create simple php script with just one line:

echo mime_content_type('path_to_your_png_image');

If it will give you text/plain then you have three options:

  1. Upgrade your PHP to 5.3.0, though I doubt it’s available for most *nix distributions at this time.
  2. Install PECL package Fileinfo.
  3. The easiest, modify form class.

In first two options sfValidatorFile will use finfo_open function prior to mime_content_type and it should give correct results for PNG image. However, upgrading PHP or installing PECL package isn’t always possible.

The simplest way to fix this bug is to apply small modifications to your form class, just reorder mime type guessers:

public function configure()
{
  $this->validatorSchema['image'] = new sfValidatorFile(array(
      'required'	=> false,
      'path'       => sfConfig::get('sf_upload_dir') . '/directory',
      'mime_types' => 'web_images'
    ));
  $this->validatorSchema['image']->setOption('mime_type_guessers', array(
    array($this->validatorSchema['image'], 'guessFromFileinfo'),
    array($this->validatorSchema['image'], 'guessFromFileBinary'),
    array($this->validatorSchema['image'], 'guessFromMimeContentType')
  ));
}

In this case validator will first try fileinfo (which should be available since PHP 5.3.0), then 'file -bi' which should work correctly on *nix platform and only if both failed it will use mime_content_type

Tags: ,

July 27th, 2009, posted by alex

Calling phing tasks from Eclipse

Here you can read how to run phing tasks using built-in Ant tool in Eclipse.

In this post I’ll describe what to do if your phing task requires user input. The solution is simple – ask for user property in ant and pass it back to phing:
Read the rest of this entry »

Tags: , ,

June 11th, 2009, posted by alex

Add absolute link menu item to user menu in Drupal

First of all, user menu (local tasks) in Drupal cannot be edited via admin. To add items to the menu you need to create new module and implement hook_menu() in it.
The following example shows how to do it in Drupal 6:

function yourmodule_menu() {
  $items['http://some.url'] = array(
    'tab_root'	=> 'user',
    'tab_parent'	=> 'user',
    'title' => 'External URL',
    'page callback' => 'user_page',
    'access callback' => 'user_is_anonymous',
    'type' => MENU_LOCAL_TASK,
    'weight'	=> 5
  );
 
  return $items;
}

Change ‘access callback’ to whatever function (or constant) you want, but don’t forget to set ‘page callback’. It is being checked when building menu structure even if we don’t have any page callback actually.

Tags: ,

May 21st, 2009, posted by alex

symfony l10n – going further

As you may know symfony offers localized objects out of the box. It gives you an easy way to have different data for different cultures.

Sometimes it is not enough. I needed two localized version of website but with completely different content – everything including users, admin and super admin. Both version were supposed to run under the same domain and to be distinguished just by locale part in the url. I was too lazy and didn’t want to copy applications or projects (moreover, it is a problem in the future, you’ll have to modify each copy). So, I decided to use different databases with exact schema for different cultures.

Here’s guide how to implement this.
Read the rest of this entry »

Tags: , ,

April 19th, 2009, posted by alex

Hierarchical clustering using C++

Our aim is to implement hierarchical clustering algorithm with O(N*N*log(N)) complexity using STL.

The idea of hierarchical clustering is merging two nearest clusters on every step starting from N one-element clusters. To find two nearest clusters on step K we need (N-K+1)x(N-K+1) matrix of distances between current clusters. We need, in worst case, N times of updating and finding minimum in sequence of NxN, (N-1)x(N-1), (N-2)x(N-2), …, 1×1 matrix. So, in usual realization of HC algorithm it should cost you O(N*N*N) operations.

To improve algorithm complexity up to O(N*N*log(N)) we can use vector V of similar to priority queues structures. V[i] should consist of sorted by distance points P(i,j) where distance is distance between clusters i and j. Our similar to priority queues data structure should support: ability to extract minimal element with complexity O(1), ability to delete element with complexity O(log(n)), and ability to add and element with complexity O(log(n)).

Standard STL priority_queue allows us to extract minimum and add element with required time, but it has no ability to find quickly an element, so we can’t delete elements with complexity O(log(n)). I propose to use set or multiset STL structure instead. Set and multiset uses “red-black tree” data structure with O(log(n)) complexity of deletion and insertion. Also, in STL sets all elements stored in sorted order and we can easily access to minimum (maximum) element [using standard begin() or end() methods].

In my realization I used following structure to store distances and cluster’s indexes:

struct distances
{
	double dist;
	int index;
};

Also I defined appropriate comparing operator so that elements in my set always sorted in right order.

struct Cmp{
	bool operator()(const distances d1, const distances d2) const
	{
		if(d1.dist == d2.dist)
		{
			return d1.index &lt; d2.index;
		}
		return d1.dist &lt; d2.dist;
	}
};

Then declaration of our vector of sets should look like this one:

std::vector&gt; P;

Here is source codes with sample input file and some comments:

sources.zip

Tags: , ,

January 23rd, 2009, posted by Atuk

Problems with SSE2 in OpenCV

When I tried to use some methods from OpenCV library (for example CvResize()) in my MS Visual Studio 2005 project I encountered with errors in cxtypes.h header file near

#if CV_SSE2
__m128d t = _mm_load_sd( &value );
int i = _mm_cvtsd_si32(t);
return i - _mm_movemask_pd(_mm_cmplt_sd(t,_mm_cvtsi32_sd(t,i)));
#else
....

These errors were related with SSE2. The problem is that my AMD Sempron 2200+ family 6 (x86 family 6 model 8 ) processor do not support SSE2 instructions. SSE – Streaming SIMD Extensions 2 are extends on MMX instructions to operate on special registers to increase computational speed in some cases.

To fix these problems you need to set CV_SSE2 variable to 0 in cxcore’s cxtypes.h (near 65 line).
For example like here:

//  #if defined WIN32 &amp;&amp; (!defined WIN64 || defined EM64T) && 
//      (_MSC_VER >= 1400 || defined CV_ICC) 
//      || (defined __SSE2__ && defined __GNUC__ && __GNUC__ >= 4)
//    #include 
//    #define CV_SSE2 1
//  #else
    #define CV_SSE2 0
//  #endif

Tags: , ,

January 6th, 2009, posted by Atuk